這個(gè)例子可以說(shuō)是caffe的入門之作亏狰,但里面包含的CNN知識(shí)已經(jīng)十分豐富放刨,值得入門者深深思考贡羔,會(huì)發(fā)現(xiàn)其中的很多美妙之處葵袭。
寫這篇文章來(lái)記錄自己的學(xué)習(xí)之旅涵妥。
首先這個(gè)例子的結(jié)構(gòu): ? lenet(模型)+mnist(數(shù)據(jù))
其中mnist數(shù)據(jù)主要由兩個(gè)函數(shù)處理:
1.下載二進(jìn)制文件:
???? cd caffe???? ./data/mnist/get_mnist.sh
下載下來(lái)的文件有四個(gè):
2.將這些二進(jìn)制文件轉(zhuǎn)換為caffe支持的LEVELDB或者LMDB:
? ? $./examples/mnist/create_mnist.sh
Lenet結(jié)構(gòu):
lenet結(jié)構(gòu)簡(jiǎn)單坡锡,但是已經(jīng)具備了一個(gè)CNN網(wǎng)絡(luò)最基本的具備的元素了蓬网。以下為它的訓(xùn)練結(jié)構(gòu):
其中窒所,圖片經(jīng)卷積后輸出大小的計(jì)算公式為:
原圖:N*N ? ?
?fliter: F*F ? ? ? ? ? ? ??
?stride:S ? ? ? ? ? ? ? ? ? ?
?padding:P
輸出的圖片大小為M*M? ? ? ? ? M= (N-F+2P/S+1
?注意這里的不適用 :不同方向上不同stride以及padding的卷積。
那么caffe是如何定義這個(gè)模型的:在caffe中模型的描述文件為example/mnist/data/lenet_train_val.prototxt帆锋,正是caffe的依賴包:protobuffer將模型的定義讀取到內(nèi)存中吵取。
我們來(lái)看一看這個(gè)文件:
很容易看懂,caffe層的定義和積木一樣锯厢,很清楚說(shuō)明上一層是什么皮官,下一層是什么,
讓我感興趣的是卷積層的定義:
其中实辑,weight的初始化使用了xavier填充器捺氢,
“Xavier”初始化方法是一種很有效的神經(jīng)網(wǎng)絡(luò)初始化方法,是由Xavier Glorot 和 Yoshua Bengio在2010提出的剪撬,第一次接觸到這個(gè)是在自編碼器的權(quán)值初始化看到的:
使用原因:
如果深度學(xué)習(xí)模型的權(quán)重初始化得太小摄乒,那么信號(hào)在每層間傳遞時(shí)將會(huì)逐漸縮小而難以產(chǎn)生作用,而如果初始化得太大残黑,那信號(hào)將在每一層傳遞時(shí)逐漸過(guò)度放大而最終發(fā)散失效馍佑。
Xavier初始化目的就為了初始化深度學(xué)習(xí)網(wǎng)絡(luò)時(shí)讓權(quán)重不大不小,具體得推導(dǎo)過(guò)程以后專門寫一篇梨水。
簡(jiǎn)單來(lái)說(shuō):主要為了使得權(quán)值的分布符合:
上面的話是lenet的基本模型拭荤,而具體訓(xùn)練的話仍需要我們另外定義的超參數(shù):
訓(xùn)練模型的超參數(shù)存于 ./example/mnist/lenet_solver.prototxt
我們來(lái)看一看里面的內(nèi)容:
首先很明顯這里使用了SGD的優(yōu)化方法,故對(duì)于每個(gè)batch冰木,loss函數(shù)應(yīng)為:
?根據(jù)dataloss的不同定義穷劈,以及正則化方式選擇的不同笼恰,展開(kāi)式子也不同踊沸。這個(gè)部分以后也會(huì)寫一篇文章來(lái)記錄下已經(jīng)學(xué)過(guò)的內(nèi)容。
SGD的最普通式子:
caffe 這里用到是:
很有趣有人說(shuō)是受了牛頓的啟發(fā)社证,加入這個(gè)m(monentum)逼龟,為尋優(yōu)加入了慣性的影響,所以當(dāng)梯度下降的時(shí)候追葡,在誤差平面存在平坦區(qū)的時(shí)候腺律,SGD能更快學(xué)習(xí)。以后將會(huì)好好研究
另一個(gè)有趣的是學(xué)習(xí)速率的衰減策略:
這里使用的是inv宜肉,且gamma設(shè)置為0.0001匀钧,power為0.75
所用公式為:base_lr= base_lr *(1+gamma*iter)^(power)
caffe同時(shí)提供了其他的學(xué)習(xí)速率改變方法:
//? ? - fixed: always return base_lr.
//????-?step:?return?base_lr?*?gamma?^?(floor(iter?/?step))
//????-?exp:?return?base_lr?*?gamma?^?iter
//????-?inv:?return?base_lr?*?(1?+?gamma?*?iter)?^?(-?power)
//????-?multistep:?similar?to?step?but?it?allows?non?uniform?steps?defined?by
//??????stepvalue
//????-?poly:?the?effective?learning?rate?follows?a?polynomial?decay,?to?be
//??????zero?by?the?max_iter.?return?base_lr?(1?-?iter/max_iter)?^?(power)
//????-?sigmoid:?the?effective?learning?rate?follows?a?sigmod?decay
//??????return?base_lr?(?1/(1?+?exp(-gamma?*?(iter?-?stepsize))))
在matlab繪圖中得到:
訓(xùn)練開(kāi)始:
$./examples/mnist/train_lenet.sh
建立,迭代10000次谬返,下面為輸出
最后的模型快照存于caffe/examples/mnist/下