用 Keras 編寫你的第一個人工神經網路
教程概述:這裡不需要編寫太多的代碼,不過我們將一步步慢慢地告訴你怎麼以後怎麼創建自己的模型。教程將會涵蓋以下步驟:
載入數據
定義模型
編譯模型
訓練模型
評估模型
結合所有步驟在一起
這個教程的前置條件:
有 python 2 或 3 的環境和編程基礎
安裝並配置好 Scipy 庫(包括 Numpy )
你安裝好 Keras 並且有一個後端(Theano or TensorFlow)
創建一個新的文件,命名為 keras_first_network.py ,然後將教程的代碼一步步複製進去。
1. 載入數據
每當我們使用機器學習演算法使用隨機過程(如隨機數),先設置隨機數種子是一個好的習慣。
這樣您就可以運行相同的代碼一次又一次,得到相同的結果。如果你需要證明結果,使用隨機數據比較演算法或調試代碼,這是很有用的。
你可以初始化隨機數發生器及其種子,例如:
現在我們可以載入我們的數據了。在這個教程中,我們將使用皮馬印第安人糖尿病數據集(http://archive.ics.uci.edu/ml/datasets/Pima+Indians+Diabetes).這是UCI 機器學習資料庫一個標準的機器學習數據集。它描述了病人醫療記錄和他們是否在五年內發病。
因此,它是一個二分類問題(出現糖尿病為1, 否則為 0)。所有描述病人的輸入變數都是數值。這便於直接用於需要數值輸入輸出的神經網路, 適合我們第一個 Keras 神經網路。下載數據集並且重命名為 pima-indians-diabetes.csv 放入 python 腳本所在的目錄的 data/pima-indians-diabetes.csv。
你可以只直接使用 Numpy 庫的 loadtxt() 方法載入數據,一共 8 個輸出變數和 1 個輸出變數(最後一列)。載入之後我們就可以把數據分離為 X(輸出變數)和 Y(輸出分類)
# load pima indians dataset
dataset=numpy.loadtxt("data/pima-indians-diabetes.csv",delimiter=",")
# split into input (X) and output (Y) variables
X=dataset[:,:8]
Y=dataset[:,8]
我們已經初始化了我們對的隨機數生成器來確保結果可復現, 也載入了數據。我們現在可以準備定義我們的神經網路模型了。
2. 定義模型
Keras 中的模型被定義為一系列的層。
我們實例化一個 Sequential 模型對象,每次添加一層知道我們對網路的拓撲結構滿意。
第一件事情我們需要確保的是輸出神經元的數量。這可以在模型創建的時候設置參數 input_dim 來定義,我們將這個參數設置為 8 對應 8 個輸出變數。我們怎麼知道層的數量和他們的類型呢?
這是一個非常難回答的問題。這是啟發式的,我們通過不斷地試錯找出最好的網路結構、一般來說,你需要足夠大的網路去明白結構對於問題是否有用。在這個例子中, 我們使用三層全連接的結構。
全連接層使用 Dense 定義。我們可以通過第一個參數定義層的神經元數量,第二個參數 init 定義權重的初始化方法, activation 參數定義激活函數。
在這個例子中, 我們把權重初始化成一個服從均勻分布的小隨機數(init="uniform"),在0到0.05直接(這是 Keras 標準均勻分布權重初始值)。另一種傳統的選擇是『normal』,會從高斯分布(正態分布)中產生一個小的隨機數。
我們在前兩層使用 (relu)[https://en.wikipedia.org/wiki/Rectifier_(neural_networks)] 激活函數, 在輸出層使用 Sigmoid 函數。曾經 Sigmoid 和 tanh 激活函數是所有的層首選的。但時至今日, 使用 relu 激活函數可以達到更好的性能。我們在輸出層使用 Sigmoid 函數來確保網路輸出在 0 和 1 之間,
我們可以添加每一層將這些東西放到一起。第一層有 12 個神經元、8個輸出變數。第二層有 8 個神經元和最後 1 個神經元的輸出層用於預測類別(糖尿病有無發病)
# create model
model=Sequential()
model.add(Dense(12,input_dim=8,init="uniform",activation="relu"))
model.add(Dense(8,init="uniform",activation="relu"))
model.add(Dense(1,init="uniform",activation="sigmoid"))
3. 編譯模型
現在我們定義好模型, 那麼就可以編譯他了。
編譯使用高效的數學庫, 封裝了 Theano 或者 TensorFlow(稱為 backend)。後端(backend)在你的硬體上自動選擇最好的方式去表現用於訓練和預測的神經網路,比如 CPU、GPU 或者分散式。
編譯時, 我們需要額外定義訓練網路所需要的參數。記住, 訓練網路意味著尋找最優的權重集去預測。
我們需要定義評估權重集的損失函數, 用於尋找不同權重的優化器以及我們希望在訓練過程呈現的可選指標。
在這個例子中, 我們使用對數損失函數(logarithmic loss), 對於二分類問題, 其在 Keras 中稱為「binary_crossentropy」。我們還將使用梯度下降演算法『adam』, 沒有為什麼, 它就是一種高效地默認方法。想了解更多這種演算法可以查看論文: (Adam: A Method for Stochastic Optimization)[http://arxiv.org/abs/1412.6980]
最後, 以為這是一個分類問題, 所以我們會收集和彙報分類的準確率作為度量指標。
# Compile model
model.compile(loss="binary_crossentropy",optimizer="adam",metrics=["accuracy"])
4. 訓練模型
我們已經定義和編譯了模型, 他是為高效地計算而準備的。
現在是時候在數據上訓練模型了。
我們可以在載入的數據上訓練和擬合模型,通過 fit() 函數。
訓練過程會在數據集迭代一定的次數,成為 epochs, 這個可以通過 nb_epoch 參數來設定。我們也可以設定 batch_size 參數來指定進行梯度下降時每個batch包含的樣本數。訓練時一個batch的樣本會被計算一次梯度下降, 使目標函數優化一步。在這個例子中, 我們將迭代150次、批處理大小為10。再說一次, 這些參數可以通過試錯來選擇。
# Fit the model
model.fit(X,Y,nb_epoch=150,batch_size=10)
這就是在你的 CPU 或者 GPU 上發生的事情。
5. 評估模型
我們已經在整個數據集上訓練了我們的神經網路, 我們可以在線通的數據集上評估神經網路的性能。
這隻會告訴我們模型有多適合已有的數據(訓練的準確率),但我們無從知道演算法在新數據上的性能。
我們可以簡單但很理想地把數據分為訓練集和測試集來分別訓練和評估模型。
你可以通過 evaluate() 函數在訓練集評估你的模型, 使用你訓練模型時相同的輸出和輸出。
這會針對每一個輸出-輸出產生預測並且收集分數,包括平均損失和其他我們定義的指標,比如準確率。
# evaluate the model
scores=model.evaluate(X,Y)
print("%s: %.2f%%"%(model.metrics_names[1],scores[1]*100))
6. 將這些放在一起
你已經看到用 Keras 創建你的第一個神經網路有多麼簡單、
運行以上的代碼, 將會看到150個迭代中, 每次迭代的損失和準確率,以及最終的模型在訓練集上的評估結果, 在我的 CPU 上耗時 10s(使用 Theano 作為後端)
...Epoch 143/150768/768 [==============================] - 0s - loss: 0.4614 - acc: 0.7878Epoch 144/150768/768 [==============================] - 0s - loss: 0.4508 - acc: 0.7969Epoch 145/150768/768 [==============================] - 0s - loss: 0.4580 - acc: 0.7747Epoch 146/150768/768 [==============================] - 0s - loss: 0.4627 - acc: 0.7812Epoch 147/150768/768 [==============================] - 0s - loss: 0.4531 - acc: 0.7943Epoch 148/150768/768 [==============================] - 0s - loss: 0.4656 - acc: 0.7734Epoch 149/150768/768 [==============================] - 0s - loss: 0.4566 - acc: 0.7839Epoch 150/150768/768 [==============================] - 0s - loss: 0.4593 - acc: 0.7839768/768 [==============================] - 0sacc: 79.56%
如果你嘗試在 IPython 或者 Jupyter , 你將會得到錯誤。原因是在訓練期間輸出進度條。你可以關閉這個, 通過讓 model.fit() 的參數 verbose=0
福利: 做出預測
我被問得最多的一個問題是:
在我訓練模型之後, 怎麼預測新數據的分類?
這是個好問題。
我們擬合了上述例子, 用他來在訓練集上作出預測, 假裝我們之前沒看到過這些數據。
做預測同樣非常簡單, 只需要使用 model.predict()。我們在輸出層使用 Sigmoid 激活函數, 因此我們的預測值將會在 0 到 1 的區間內。在這個分類任務中,我們可以輕易地通過四捨五入轉換為離散二分類。
預測訓練集中每一個記錄的完整例子如下:
# Create first network with Keras
fromkeras.modelsimportSequential
fromkeras.layersimportDense
importnumpy
# fix random seed for reproducibility
seed=7
numpy.random.seed(seed)
# load pima indians dataset
dataset=numpy.loadtxt("pima-indians-diabetes.csv",delimiter=",")
# split into input (X) and output (Y) variables
X=dataset[:,:8]
Y=dataset[:,8]
# create model
model=Sequential()
model.add(Dense(12,input_dim=8,init="uniform",activation="relu"))
model.add(Dense(8,init="uniform",activation="relu"))
model.add(Dense(1,init="uniform",activation="sigmoid"))
# Compile model
model.compile(loss="binary_crossentropy",optimizer="adam",metrics=["accuracy"])
# Fit the model
model.fit(X,Y,nb_epoch=150,batch_size=10,verbose=2)
# calculate predictions
predictions=model.predict(X)
# round predictions
rounded=[round(x)forxinpredictions]
print(rounded)
運行這個修改過的例子, 將會列印出每個輸出的預測值。如果有需要的話, 我們可以直接使用這些預測。
總結
在這篇文章當中, 我們學會了如何通過 Keras 創建自己的第一個神經網路模型。
特別是我們學會了 使用 Keras 來創建神經網路或深度學習模型時關鍵的 5 個步驟:
載入數據
定義模型
編譯模型
訓練模型
評估模型
- 加入人工智慧學院系統學習 -
※復旦中文文本分類過程
※在一頭扎進機器學習前應該知道的那些事兒
TAG:AI講堂 |