? ? 20180108
MLP(多層感知器)是最簡單的神經(jīng)網(wǎng)絡(luò),MNIST是一個經(jīng)典的數(shù)據(jù)集,包括6萬條訓(xùn)練數(shù)據(jù)和1萬條測試數(shù)據(jù),用于識別手寫數(shù)字0到9,網(wǎng)址在:http://yann.lecun.com/exdb/mnist/
我們本節(jié)的目的就是使用CNTK C# MLP實現(xiàn)MNIST數(shù)據(jù)訓(xùn)練和識別,例子與上一節(jié)相同,就是CNTK的Example目錄中的CsharpTrain程序。
1、準備訓(xùn)練文件和測試文件
準備過程很簡單,找到Example目錄中的Mnist目錄,我的是C:\cntk23\Examples\Image\DataSets\MNIST,其下有install_mnist.py文件,命令行運行它就行了,
python ?install_mnist.py
如果出現(xiàn)如下錯誤,別忘了上一節(jié)的提醒,要先運行Scripts目錄下的cntkpy35.bat程序設(shè)置python的cntk環(huán)境變量
Traceback (most recent call last): File "install_mnist.py", line 3, inimport mnist_utils as ut File "C:\cntk23\Examples\Image\DataSets\MNIST\mnist_utils.py", line 11, in import numpy as np
ModuleNotFoundError: No module named 'numpy'
運行后會生成兩個新文件:Train-28x28_cntk_text.txt和Test-28x28_cntk_text.txt,一個是訓(xùn)練文件,一個是測試文件,內(nèi)容格式都一樣,如下:
|labels 0 0 0 0 0 0 0 1 0 0 |features 0 0 0 0 0 0 0 0 00 0 0 0 0 ?0 0 0 0 0 0 0 0 0 0 0 84 185 159?
。。。。。。
151 60 36 0 0 ?0 0 0 0 222 254 254 254 254 241 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?
|labels 0 0 1 0 0 0 0 0 0 0 |features 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?
。。。。。。
對數(shù)據(jù)文件不熟悉的,和對CNTK神經(jīng)網(wǎng)絡(luò)不熟悉的,可以先看看這篇文章,寫的非常好很適合入門
探索 Microsoft CNTK 機器學(xué)習(xí)工具
2、CNTK C#神經(jīng)網(wǎng)絡(luò)創(chuàng)建
如果不知道CsharpTrain這個項目的,參見上一節(jié),本節(jié)是對該項目中有關(guān)MLP的部分進行分析。
對于例子使用來說,其他的都不重要,直接照抄現(xiàn)成的就行,下面分析神經(jīng)網(wǎng)絡(luò)建立部分以及一些重要參數(shù)
1)創(chuàng)建神經(jīng)網(wǎng)絡(luò)
如下創(chuàng)建一個單隱層的MLP網(wǎng)絡(luò),第一行的意思就是說,以輸入層網(wǎng)絡(luò)函數(shù)(scaledInput)為上一層,建立包括本層(100個節(jié)點,使用Sigmoid激活函數(shù))在內(nèi)的一個新的網(wǎng)絡(luò)函數(shù)(dense1?),命名為空(""),device表示是使用CPU還是GPU,也就是說,dense1這個新的網(wǎng)絡(luò)包括舊的網(wǎng)絡(luò)(只包含輸入層)和本層網(wǎng)絡(luò)(隱藏層)。
第二行的意思就是建立一個新的網(wǎng)絡(luò),包括dense1和本層(輸出層)。
兩行加起來就是建立一個包括輸入層、單隱層、輸出層共三層的一個MLP網(wǎng)絡(luò)。
Function dense1 = TestHelper.Dense(scaledInput, 100, device, Activation.Sigmoid, "");
Function? classifierOutput = TestHelper.Dense(dense1, numClasses, device, Activation.None, classifierName);
如下創(chuàng)建一個雙隱層的網(wǎng)絡(luò),第一個隱層包括100個節(jié)點,第二個隱層包括66個節(jié)點。
Function dense1 = TestHelper.Dense(scaledInput, 100, device, Activation.Sigmoid, "");
Function dense2 = TestHelper.Dense(dense1, 66, device, Activation.ReLU, "");
Function? classifierOutput = TestHelper.Dense(dense2, numClasses, device, Activation.None, classifierName);
對上面兩段進行對比就很容易明白是怎么回事了。
2)影響MLP模型識別率的重要參數(shù)
a、隱層層數(shù)
b、隱層節(jié)點數(shù)
c、激活函數(shù)
d、分組大?。╩inibatchSize)
單個樣本之間差別較大,而兩組平均之間差別就小,所以使用分組對模型參數(shù)改變就會小。用于隨機梯度下降(SGD)的loss評估中。
e、重復(fù)訓(xùn)練次數(shù)(epochs)
f、學(xué)習(xí)率(learningRatePerSample)
3、實驗及結(jié)論
實驗1
單隱層(200節(jié)點)、激活Sigmoid、epochs=5、minibatchsize=64、learningRatePerSample=0.003125、正確率為94.19%
實驗2
單隱層(100節(jié)點)、激活ReLu、epochs=20、minibatchsize=128、learningRatePerSample=0.003125、正確率為97.33%
還進行了其他許多單項測試,結(jié)論如下,對于MLP網(wǎng)絡(luò):
1)增加循環(huán)次數(shù)會提高正確率,例如5次改為10次會增加1個多點(以下均指百分點)
2)增加隱層節(jié)點不會提高正確率,例如100改為200
3)增加隱層層數(shù)不會提高正確率,實驗了一層、兩層、三層
4)增加minibatchsize,會提高正確率,例如32改為64會提高0.3個點
5)激活函數(shù)和學(xué)習(xí)率
ReLu對學(xué)習(xí)率很敏感,例如learningRatePerSample=0.003時很好,learningRatePerSample=0.03時很差,正確率會下降幾十個點;
Sigmoid對學(xué)習(xí)率不太敏感,0.03和0.003時只相差一兩個點。
下節(jié)我們用CNN訓(xùn)練MNIST,看看有何不同。