Neural Network 的
概念探討與實作
萌老師 創意教學
Machine Learning 概念
 Machine Learning 演算法(Algorithms) 不只
有 Neural Network,還包括 K-Means、
Support Vector Machines(SVM)、Decision
Tree、... 等等,基本上,都是希望透過資料分
類(Classification)或分群(Clustering) 的方式,
轉換為規則或知識
ML步驟
 訓練(Training):首先將已知的歷史資料,依資料特徵(譬如性別、年齡),將
樣本作分類(譬如男人、女人、小孩),這就是所謂的訓練(Training)。
 建立模型(Model):訓練之後,我們就會得到一個模型(簡略的講,就是公
式),推算未知的資料是哪一類,例如性別是男,年齡大於18歲,模型就推斷
他是男人;反之,年齡小於18歲,不論性別,模型就推斷他是小孩。
 評估(Evaluation):隨機抓一部分的已知資料,測試模型的準確率(或其他評
估指標,如 precision and recall),確定模型是堪用的,這就是『驗證』
(Validation),有了評估指標,我們就可以跟老闆或客戶,拍胸脯、打包票,
不準就切腹自盡(千萬不要喔)。
 預測(Prediction):有了以上模型後,一個未知的人進來後,我們就可以依據
性別及年齡推斷,他/她是男人、女人或小孩? 但是,注意! Machine
Learning 不是以程式撰寫明確的規則(If ... Then ...Else),而是『以已知的資
料推斷未知的資料』,只要,不斷餵資料,機器就慢慢的變聰明了。
Neural Network 概念
人工神經網路
簡單迴歸(Regression)
Activation Function
Activation Fuction
梯度下降法
 模型經過以上的強化,我們就沒辦法用單純的數學公式推導,求出權重
(W),因此,一般會改用『梯度下降法』(Gradient descent),以逼近法求
解
練習範例:MNIST手寫數字
 MNIST 資料集的訓練資料,建立單一隱藏層(Hidden Layer)的 Neural
Network 模型,以預測實際影像是哪一個阿拉伯數字
使用環境
 Anaconda 雲端程式開發 (HTTP://notebooks.azure.com)
阿拉伯數字(0~9)辨識的流程
 先讀入訓練資料,本例為 60,000 筆資料,每筆資料是一個 28 * 28 的點矩
陣圖形。
 圖形的每一點都當成一個輸入變數(X),乘以一個權重W(i,j),向隱藏層
(Hidden Layer)傳導,隱藏層的每一個節點會得到輸入變數的加權總和(W
* X)。
 再如法炮製,向輸出層傳導,輸出層的每一個節點會得到隱藏層的加權總
和,將輸出層的每一個節點化為機率,就得到一個預測模型了。
 之後我們將新資料輸入模型,就會得到 0~9 的機率,最大的機率對應的數
字就是我們的預測值了。
 權重(W)是唯一未知的變數,他們等於多少呢? 這就是 Neural Network 厲
害的地方,它透過優化(Optimization)計算,就可以求出 W 的最佳解,構
築出模型公式了。
# 導入函式庫
import numpy as np
from keras.models import Sequential
from keras.datasets import mnist
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.utils import np_utils # 用來後續將 label 標籤轉為 one-hot-encoding
from matplotlib import pyplot as plt
import tensorflow as tf #程式修改,新增這行
# 載入 MNIST 資料庫的訓練資料,並自動分為『訓練組』及『測試組』
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# 建立簡單的線性執行的模型
model = Sequential()
# Add Input layer, 隱藏層(hidden layer) 有 256個輸出變數
model.add(Dense(units=256, input_dim=784, kernel_initializer='normal', activation=tf.nn.relu))
# Add output layer
model.add(Dense(units=10, kernel_initializer='normal', activation= tf.nn.softmax))
# 編譯: 選擇損失函數、優化方法及成效衡量方式
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 將 training 的 label 進行 one-hot encoding,例如數字 7 經過 One-hot encoding 轉換
後是 0000001000,即第7個值為 1
y_TrainOneHot = np_utils.to_categorical(y_train)
y_TestOneHot = np_utils.to_categorical(y_test)
# 將 training 的 input 資料轉為2維
X_train_2D = X_train.reshape(60000, 28*28).astype('float32')
X_test_2D = X_test.reshape(10000, 28*28).astype('float32')
x_Train_norm = X_train_2D/255
x_Test_norm = X_test_2D/255
# 進行訓練, 訓練過程會存在 train_history 變數中
train_history = model.fit(x=x_Train_norm, y=y_TrainOneHot, validation_split=0.2,
epochs=10, batch_size=800, verbose=2)
# 顯示訓練成果(分數)
scores = model.evaluate(x_Test_norm, y_TestOneHot)
print()
print("t[Info] Accuracy of testing data = {:2.1f}%".format(scores[1]*100.0))
# 預測(prediction)
X = x_Test_norm[0:10,:]
predictions = model.predict_classes(X)
# get prediction result
print(predictions)
# 顯示 第一筆訓練資料的圖形,確認是否正確
plt.imshow(X_test[0])
plt.show()
plt.plot(train_history.history['loss'])
plt.plot(train_history.history['val_loss'])
plt.title('Train History')
plt.ylabel('loss')
plt.xlabel('Epoch')
plt.legend(['loss', 'val_loss'], loc='upper left')
plt.show()
模型結構存檔:以下程式將結構存到 model.config 檔案,檔案為
JSON或YAML格式。
from keras.models import model_from_json
json_string = model.to_json() with open("model.config", "w") as
text_file:
text_file.write(json_string)
權重(W)存檔:以權重(W)存檔:以下程式將權重存到 model.weight
檔案下程式將權重存到 model.weight 檔案
model.save_weights("model.weight")
同時儲存結構與權重,檔案的類別為HDF5
from keras.models import load_model
model.save('model.h5') # creates a HDF5 file 'model.h5'
模型載入,我們要使用時,可輸入下列程式碼,載入模型結構及權重(W)。
import numpy as np
from keras.models import Sequential
from keras.models import model_from_json
with open("model.config", "r") as text_file:
json_string = text_file.read()
model = Sequential()
model = model_from_json(json_string)
model.load_weights("model.weight", by_name=False)
或者直接載入HDF5檔案
from keras.models import load_model
# 刪除既有模型變數
del model
# 載入模型
model = load_model('my_model.h5')
驗證
用Draw.exe 小程式,可以使用滑鼠,書寫數字,並將它存成與MNIST類似的格式
(.csv),再用Python程式載入,依照訓練出來的模型測試是否可以辨識,
步驟如下:
執行 Draw.exe,書寫 0~9,並存成 0.csv, 1.csv ..., 9.csv。程式與*.csv放在同
目錄
執行後面的程式,可以看到10個數字的辨識結果,如果都正確,那就成功了。
for i in range(0, 10):
X2 = np.genfromtxt(str(i)+'.csv', delimiter=',').astype('float32')
X1 = X2.reshape(1,28*28) / 255
predictions = model.predict_classes(X1)
# get prediction result
print(predictions)
plt.imshow(X2.reshape(28,28)*255)
plt.show()
結論
 訓練出來的準確率均達85%,甚至95%,乍看
很高,但仔細想想,如果是應用在銀行存款數
目的辨識,使用者輸入10位數,只要一個數字
錯,銀行老董可能就要崩潰了,反之,用在遊
戲中,使用者可能會讚聲連連,驚嘆不已,所
以,Machine Learning 的應用還是必須考量
使用的時機與應用場域,才能贏得掌聲

Week4 neural network