一、搭建屬於你的第一個神經網絡

還記得第一次跑出自己的神經網絡的那種欣喜感,彷彿是看着自己的第一個孩子出生了一樣。爲了讓更多人儘快也體驗的這種欣喜感,特此總結此係列教程,代碼來自書<deep learning on keras>.
簡要介紹一下我們需要的:

  • 安裝annaconda,它自帶的很多科學計算包能夠省掉很多我們自己安裝的麻煩
  • 打開cmd,輸入pip install tensorflow,默認安裝的是cpu版tensorflow,對於我們這新手級別的,已經夠用了,要裝gpu版比較麻煩
  • 在裝好tensorflow以後再pip install keras,這個keras是基於tensorflow或者caffe的,我習慣使用tensorflow,keras是在tensorflow上的進一步封裝,使用起來非常簡單,我們只需要把精力放在網絡結構的搭建上就夠了。

引入庫和數據集

此處我們引入MNIST數據集,這是一個手寫數字數據集,由60000個訓練集和10000個測試集構成。

import keras
from keras.datasets import mnist
(trainimages, trainlabels), (testimages, testlabels) = mnist.loaddata()

這句代碼表示調用數據集mnist,把訓練圖片和標籤分別存到trainimages和trainlabels裏面,測試圖片和標籤分別存在testimages和testlabels裏面。
接下來我們看一看具體是如何儲存這些數據的:

>>> train_images.shape
(60000, 28, 28)
>>> len(train_labels)
60000
>>> train_labels
array([5, 0, 4, ..., 5, 6, 8], dtype=uint8)

我們看到計算機使用數組的形式來儲存這些數據,(60000,28,28)代表着有60000個圖片,每一個的大小是28*28。而labels則更加直接,每一個位置對應於圖片的位置爲數字的大小。
接下來,看一下測試集的情況,其實完全類似:

>>> test_images.shape
(10000, 28, 28)
>>> len(test_labels)
10000
>>> test_labels
array([7, 2, 1, ..., 4, 5, 6], dtype=uint8)

搭建訓練框架

from keras import models
from keras import layers
network = models.Sequential()
network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(10, activation='softmax'))

我們從keras引入了models 和layers,前者用來搭建整個模型框架。

  • models.Sequential()這一句代表我們之後加layers是按照順序從前往後加。
  • 至於layers.Dense則是設置這一層的具體參數第一個爲輸出維度,第二項爲激活函數類型,第三維爲輸入的形狀,我們看到shape的第二項逗號之後沒有東西,這個是根據輸入數據來自動補的,例如我們輸入數據爲28*28*60000個,那麼第二項則是28*28*60000/28/28=60000,也就是說總數一定要是28*28的整數倍,不然會報錯。
  • 第二層layers輸出爲10,激活函數爲softmax,就是將10個輸出裏面最大取1,最小取0,最後就得到了我們需要的預測值,至於爲什麼這裏不需要輸入,這就是keras的好處了,它自動計算需要的輸入的大小,所以我們只需要關心最開始的輸入大小,不需要逐層計算每一層的大小,這對於深層網絡的搭建非常方便。
network.compile(optimizer='rmsprop',
  loss='categorical_crossentropy',
  metrics=['accuracy'])

設置優化器,損失函數,還有需要顯示的指標,這三個都是可以改的,大家可以help(network.compile)來查看更多有關這些參數的東西。

預處理數據和標籤

train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28 * 28))
testimages = testimages.astype('float32') / 255

輸入的圖像是unit8類型的,我們轉化爲float32,因爲python裏面很多運算只支持float32類型,然後將形狀拉長爲28*28的,因爲我們構建的網絡是一個簡單的全連接網絡,也就是逐個像素點的預測,最後是歸一化的問題,由於像素值一開始都是0-255,我曾經就感到很奇怪爲什麼要全部歸一化到0-1,不就是等比例縮放嗎,爲什麼會影響到收斂性呢,感興趣的同學可以搜索神經網絡正則化相關的知識。

from keras.utils import to_categorical
train_labels = to_categorical(train_labels)
testlabels = tocategorical(testlabels)

對標籤下手,將原來的十個數字轉化成分類的編碼,這個具體爲什麼以後會再詳細介紹。

開始訓練!

>>> network.fit(train_images, train_labels, epochs=5, batch_size=128)
Epoch 1/5
60000/60000 [==============================] - 9s - loss: 0.2524 - acc: 0.927
Epoch 2/5
51328/60000 [========================>.....] - ETA: 1s - loss: 0.1035 - acc: 0.9692

keras還有一個好處就是它的可視化做的比較好,開始訓練以後,有一個動態的小箭頭告訴你訓練到什麼程度了,讓人感到很舒服。再解釋一下代碼,第一項,放入訓練數據,第二項放入對應的標籤,epochs代表要訓練多少批次,因爲這個優化是一個循環往復的過程,需要不斷的循環才能逐漸靠近最優,最後就是batch_size,這是minibatch,這也是正則化相關內容,如果每次都將全部的數據集放進來才訓練一次,那麼我們的訓練進度就會很慢,所以我們就會把數據分成很多小批次,一次喂一點進去,而爲什麼偏偏是128呢,這是因爲計算機是二進制的,給它2的次方的數,運算會更加快。

評估訓練效果

>>> test_loss, test_acc = network.evaluate(test_images, test_labels)
>>> print('test_acc:', test_acc
testacc: 0.9785

通過上述指令,在訓練完以後network輸入測試集和對應的標籤來進行測試。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章