今天總結(jié)一下搜到的一些知識:
感謝
http://blog.csdn.net/roslei/article/details/52807699
http://blog.csdn.net/u013066730/article/details/53764155
http://blog.csdn.net/qq_26898461/article/details/50445392
卷積神經(jīng)網(wǎng)絡(luò)(CNN)中的一些特殊層
Batch Normalization
意義: 網(wǎng)絡(luò)訓(xùn)練時盯蝴,用來加速收斂速度
提醒: 已經(jīng)將BN集成為一個layer了,使用時需要和scale層一起使用
訓(xùn)練的時候利凑,將BN層的use_global_stats設(shè)置為false巷挥; 測試的時候?qū)?use_global_stats設(shè)置為true积糯,不然訓(xùn)練的時候會報“NAN”或者模型不
收斂 – 師兄的經(jīng)驗(yàn)快集,我還沒試驗(yàn)過
用法: 詳見 [殘差神經(jīng)網(wǎng)絡(luò)](https://github.com/KaimingHe/deep-
residual-networks/blob/master/prototxt/ResNet-50-deploy.prototxt)的
使用
Dropout
意義: 防止模型過擬合;訓(xùn)練模型時拴疤,隨機(jī)讓網(wǎng)絡(luò)某些隱含層節(jié)點(diǎn)的
權(quán)重不工作(不工作的那些節(jié)點(diǎn)可以暫時認(rèn)為不是網(wǎng)絡(luò)結(jié)構(gòu)的一部
分骚揍,但是它的權(quán)重得保留下來字管,只是暫時不更新而已,因?yàn)橄麓螛颖?輸入時它可能又得工作了)
用法:
layer {
name: “drop7”
type: “Dropout”
bottom: “fc7-conv”
top: “fc7-conv”
dropout_param {
dropout_ratio: 0.5
}
}
ReLU
意義: 激活函數(shù)的一種信不;對于給定的一個輸入值x嘲叔,如果x > 0,
ReLU層的輸出為x抽活,如果x < 0硫戈,ReLU層的輸出為0。
提醒: 可選參數(shù)negative_slope下硕,此參數(shù)使得x < 0時丁逝,ReLU層的輸
出為negative_slope * x;目前已經(jīng)有了ReLU的進(jìn)化版 – [PReLU]
(https://arxiv.org/abs/1502.01852)
用法:
layer {
name: “relu1”
type: “ReLU”
bottom: “conv1”
top: “conv1”
relu_param{
negative_slope: [默認(rèn):0]
}
}
PReLU
意義: ReLu的進(jìn)化版梭姓;霜幼。
提醒: 在負(fù)半軸的輸出乘以一個系數(shù),而這個系數(shù)是可學(xué)習(xí)的(你可
以為其指定學(xué)習(xí)率)誉尖,其中value是系數(shù)的初始值罪既,channel_shared
指定是否在各個通道間共享這個系數(shù)。 據(jù)說有的實(shí)驗(yàn)更快更好地收
斂,但有的實(shí)驗(yàn)準(zhǔn)確率卻有所下降 - 具體效果還是得以具體實(shí)驗(yàn)為準(zhǔn)
(自己沒有用過琢感,不加評論
-用法:
layer {
name: “relu1”
type: “PReLU”
bottom: “conv1”
top: “conv1”
param {
lr_mult: 1
decay_mult: 0
}
prelu_param {
filler: {
value: 0.33 #: 默認(rèn)為0.25
}
channel_shared: false
}
}
Solver最優(yōu)化方法
Solver的流程:
- 設(shè)計(jì)好需要優(yōu)化的對象丢间,以及用于學(xué)習(xí)的訓(xùn)練網(wǎng)絡(luò)和用于評估的測試網(wǎng)絡(luò)。(通過調(diào)用另外一個配置文件prototxt來進(jìn)行)
- 通過forward和backward迭代的進(jìn)行優(yōu)化來跟新參數(shù)驹针。
- 定期的評價測試網(wǎng)絡(luò)烘挫。 (可設(shè)定多少次訓(xùn)練后,進(jìn)行一次測試)
- 在優(yōu)化過程中顯示模型和solver的狀態(tài)
在每一次的迭代過程中柬甥,solver做了這幾步工作:
1饮六、調(diào)用forward算法來計(jì)算最終的輸出值,以及對應(yīng)的loss
2暗甥、調(diào)用backward算法來計(jì)算每層的梯度
3喜滨、根據(jù)選用的slover方法捉捅,利用梯度進(jìn)行參數(shù)更新
4撤防、記錄并保存每次迭代的學(xué)習(xí)率、快照棒口,以及對應(yīng)的狀態(tài)寄月。
net: "examples/mnist/lenet_train_test.prototxt"
test_iter: 100
test_interval: 500
base_lr: 0.01
momentum: 0.9
type: SGD
weight_decay: 0.0005
lr_policy: "inv"
gamma: 0.0001
power: 0.75
display: 100
max_iter: 20000
snapshot: 5000
snapshot_prefix: "examples/mnist/lenet"
solver_mode: CPU
接下來,我們對每一行進(jìn)行詳細(xì)解譯:
net: "examples/mnist/lenet_train_test.prototxt"
設(shè)置深度網(wǎng)絡(luò)模型无牵。每一個模型就是一個net漾肮,需要在一個專門的配置文件中對net進(jìn)行配置,每個net由許多的layer所組成茎毁。注意的是:文件的路徑要從caffe的根目錄開始克懊,其它的所有配置都是這樣。
也可用train_net和test_net來對訓(xùn)練模型和測試模型分別設(shè)定七蜘。例如:
train_net: "examples/hdf5_classification/logreg_auto_train.prototxt"
test_net: "examples/hdf5_classification/logreg_auto_test.prototxt"
接下來第二行:
test_iter: 100
這個要與test layer中的batch_size結(jié)合起來理解谭溉。mnist數(shù)據(jù)中測試樣本總數(shù)為10000,一次性執(zhí)行全部數(shù)據(jù)效率很低橡卤,因此我們將測試數(shù)據(jù)分成幾個批次來執(zhí)行扮念,每個批次的數(shù)量就是batch_size。假設(shè)我們設(shè)置batch_size為100碧库,則需要迭代100次才能將10000個數(shù)據(jù)全部執(zhí)行完柜与。因此test_iter設(shè)置為100。執(zhí)行完一次全部數(shù)據(jù)嵌灰,稱之為一個epoch
test_interval: 500
測試間隔弄匕。也就是每訓(xùn)練500次,才進(jìn)行一次測試沽瞭。
base_lr: 0.01
lr_policy: "inv"
gamma: 0.0001
power: 0.75
這四行可以放在一起理解迁匠,用于學(xué)習(xí)率的設(shè)置。只要是梯度下降法來求解優(yōu)化,都會有一個學(xué)習(xí)率柒瓣,也叫步長儒搭。base_lr用于設(shè)置基礎(chǔ)學(xué)習(xí)率,在迭代的過程中芙贫,可以對基礎(chǔ)學(xué)習(xí)率進(jìn)行調(diào)整搂鲫。怎么樣進(jìn)行調(diào)整,就是調(diào)整的策略磺平,由lr_policy來設(shè)置魂仍。
lr_policy可以設(shè)置為下面這些值,相應(yīng)的學(xué)習(xí)率的計(jì)算為:
- fixed: 保持base_lr不變.
- step: 如果設(shè)置為step,則還需要設(shè)置一個stepsize, 返回 base_lr * gamma ^ (floor(iter / stepsize)),其中iter表示當(dāng)前的迭代次數(shù)
- exp: 返回base_lr * gamma ^ iter拣挪, iter為當(dāng)前迭代次數(shù)
- inv: 如果設(shè)置為inv,還需要設(shè)置一個power, 返回base_lr * (1 + gamma * iter) ^ (- power)
- multistep: 如果設(shè)置為multistep,則還需要設(shè)置一個stepvalue擦酌。這個參數(shù)和step很相似,step是均勻等間隔變化菠劝,而multistep則是根據(jù) stepvalue值變化
- poly: 學(xué)習(xí)率進(jìn)行多項(xiàng)式誤差, 返回 base_lr (1 - iter/max_iter) ^ (power)
- sigmoid: 學(xué)習(xí)率進(jìn)行sigmod衰減赊舶,返回 base_lr ( 1/(1 + exp(-gamma * (iter - stepsize))))
multistep示例:
base_lr: 0.01
momentum: 0.9
weight_decay: 0.0005
# The learning rate policy
lr_policy: "multistep"
gamma: 0.9
stepvalue: 5000
stepvalue: 7000
stepvalue: 8000
stepvalue: 9000
stepvalue: 9500
接下來的參數(shù):
momentum :0.9
上一次梯度更新的權(quán)重
type: SGD
優(yōu)化算法選擇。這一行可以省掉赶诊,因?yàn)槟J(rèn)值就是SGD笼平。總共有六種方法可選擇舔痪,在本文的開頭已介紹寓调。
weight_decay: 0.0005
權(quán)重衰減項(xiàng),防止過擬合的一個參數(shù)锄码。
display: 100
每訓(xùn)練100次夺英,在屏幕上顯示一次。如果設(shè)置為0滋捶,則不顯示痛悯。
max_iter: 20000
最大迭代次數(shù)。這個數(shù)設(shè)置太小炬太,會導(dǎo)致沒有收斂灸蟆,精確度很低。設(shè)置太大亲族,會導(dǎo)致震蕩炒考,浪費(fèi)時間。
snapshot: 5000snapshot_prefix: "examples/mnist/lenet"
快照霎迫。將訓(xùn)練出來的model和solver狀態(tài)進(jìn)行保存斋枢,snapshot用于設(shè)置訓(xùn)練多少次后進(jìn)行保存,默認(rèn)為0知给,不保存瓤帚。snapshot_prefix設(shè)置保存路徑描姚。
還可以設(shè)置snapshot_diff,是否保存梯度值戈次,默認(rèn)為false,不保存轩勘。
也可以設(shè)置snapshot_format,保存的類型怯邪。有兩種選擇:HDF5 和BINARYPROTO 绊寻,默認(rèn)為BINARYPROTO
solver_mode: CPU
設(shè)置運(yùn)行模式。默認(rèn)為GPU,如果你沒有GPU,則需要改成CPU,否則會出錯悬秉。
注意:以上的所有參數(shù)都是可選參數(shù)澄步,都有默認(rèn)值。根據(jù)solver方法(type)的不同和泌,還有一些其它的參數(shù)村缸,在此不一一列舉。
caffe總共提供了六種優(yōu)化方法:
- Stochastic Gradient Descent (type: "SGD")
- AdaDelta (type: "AdaDelta")
- Adaptive Gradient (type: "AdaGrad")
- Adam (type: "Adam")
- Nesterov’s Accelerated Gradient (type: "Nesterov") and
RMSprop (type: "RMSProp")
1武氓、Stochastic gradient descent(SGD)
隨機(jī)梯度下降(Stochastic gradient descent)是在梯度下降法(gradient descent)的基礎(chǔ)上發(fā)展起來的梯皿,梯度下降法也叫最速下降法,具體原理在網(wǎng)易公開課《機(jī)器學(xué)習(xí)》中聋丝,吳恩達(dá)教授已經(jīng)講解得非常詳細(xì)索烹。SGD在通過負(fù)梯度
的線性組合來更新W工碾,迭代公式如下:
如果v(t)初始值為0弱睦,v(t+1)的方向就與梯度的負(fù)方向相同,那么會加速優(yōu)化渊额,又由于u<1况木,所以在n多次后可近似看成v1 的 n次方,那么v(t+1)也會變化很小旬迹,那時也正是梯度變化很小的時候火惊,所以這種方式還是很有用的。 其中奔垦,
在深度學(xué)習(xí)中使用SGD,比較好的初始化參數(shù)的策略是把學(xué)習(xí)率設(shè)為0.01左右(base_lr: 0.01)筐咧,在訓(xùn)練的過程中鸯旁,如果loss開始出現(xiàn)穩(wěn)定水平時噪矛,對學(xué)習(xí)率乘以一個常數(shù)因子(gamma),這樣的過程重復(fù)多次铺罢。
對于momentum艇挨,一般取值在0.5--0.99之間。通常設(shè)為0.9韭赘,momentum可以讓使用SGD的深度學(xué)習(xí)方法更加穩(wěn)定以及快速雷袋。
關(guān)于更多的momentum,請參看Hinton的《A Practical Guide to Training Restricted Boltzmann Machines》辞居。
實(shí)例:
base_lr: 0.01
lr_policy: "step"
gamma: 0.1
stepsize: 1000
max_iter: 3500
momentum: 0.9
lr_policy設(shè)置為step,則學(xué)習(xí)率的變化規(guī)則為 base_lr * gamma ^ (floor(iter / stepsize))
即前1000次迭代楷怒,學(xué)習(xí)率為0.01; 第1001-2000次迭代,學(xué)習(xí)率為0.001; 第2001-3000次迭代瓦灶,學(xué)習(xí)率為0.0001鸠删,第3001-3500次迭代,學(xué)習(xí)率為10-5
上面的設(shè)置只能作為一種指導(dǎo)贼陶,它們不能保證在任何情況下都能得到最佳的結(jié)果刃泡,有時候這種方法甚至不work。如果學(xué)習(xí)的時候出現(xiàn)diverge(比如碉怔,你一開始就發(fā)現(xiàn)非常大或者NaN或者inf的loss值或者輸出)烘贴,此時你需要降低base_lr的值(比如,0.001)撮胧,然后重新訓(xùn)練桨踪,這樣的過程重復(fù)幾次直到你找到可以work的base_lr。
2芹啥、AdaDelta
AdaDelta是一種”魯棒的學(xué)習(xí)率方法“锻离,是基于梯度的優(yōu)化方法(like SGD)。
具體的介紹文獻(xiàn):
M. Zeiler ADADELTA: AN ADAPTIVE LEARNING RATE METHOD. arXiv preprint, 2012.
示例:
net: "examples/mnist/lenet_train_test.prototxt"
test_iter: 100
test_interval: 500
base_lr: 1.0
lr_policy: "fixed"
momentum: 0.95
weight_decay: 0.0005
display: 100
max_iter: 10000
snapshot: 5000
snapshot_prefix: "examples/mnist/lenet_adadelta"
solver_mode: GPU
type: "AdaDelta"
delta: 1e-6
從最后兩行可看出墓怀,設(shè)置solver type為Adadelta時汽纠,需要設(shè)置delta的值。
3傀履、AdaGrad
自適應(yīng)梯度(adaptive gradient)是基于梯度的優(yōu)化方法(like SGD)
具體的介紹文獻(xiàn):
Duchi, E. Hazan, and Y. Singer. Adaptive Subgradient Methods for Online Learning and Stochastic Optimization. The Journal of Machine Learning Research, 2011.
示例:
net: "examples/mnist/mnist_autoencoder.prototxt"
test_state: { stage: 'test-on-train' }
test_iter: 500
test_state: { stage: 'test-on-test' }
test_iter: 100
test_interval: 500
test_compute_loss: true
base_lr: 0.01
lr_policy: "fixed"
display: 100
max_iter: 65000
weight_decay: 0.0005
snapshot: 10000
snapshot_prefix: "examples/mnist/mnist_autoencoder_adagrad_train"
# solver mode: CPU or GPU
solver_mode: GPU
type: "AdaGrad"
4虱朵、Adam
是一種基于梯度的優(yōu)化方法(like SGD)。
具體的介紹文獻(xiàn):
D. Kingma, J. Ba. Adam: A Method for Stochastic Optimization. International Conference for Learning Representations, 2015.
5钓账、NAG
Nesterov 的加速梯度法(Nesterov’s accelerated gradient)作為凸優(yōu)化中最理想的方法碴犬,其收斂速度非掣味希快颁井。
具體的介紹文獻(xiàn):
I. Sutskever, J. Martens, G. Dahl, and G. Hinton. On the Importance of Initialization and Momentum in Deep Learning. Proceedings of the 30th International Conference on Machine Learning, 2013.
示例:
net: "examples/mnist/mnist_autoencoder.prototxt"
test_state: { stage: 'test-on-train' }
test_iter: 500
test_state: { stage: 'test-on-test' }
test_iter: 100
test_interval: 500
test_compute_loss: true
base_lr: 0.01
lr_policy: "step"
gamma: 0.1
stepsize: 10000
display: 100
max_iter: 65000
weight_decay: 0.0005
snapshot: 10000
snapshot_prefix: "examples/mnist/mnist_autoencoder_nesterov_train"
momentum: 0.95
# solver mode: CPU or GPU
solver_mode: GPU
type: "Nesterov"
6、RMSprop
RMSprop是Tieleman在一次 Coursera課程演講中提出來的逞敷,也是一種基于梯度的優(yōu)化方法(like SGD)
具體的介紹文獻(xiàn):
T. Tieleman, and G. Hinton. RMSProp: Divide the gradient by a running average of its recent magnitude. COURSERA: Neural Networks for Machine Learning.Technical report, 2012.
示例:
net: "examples/mnist/lenet_train_test.prototxt"
test_iter: 100
test_interval: 500
base_lr: 1.0
lr_policy: "fixed"
momentum: 0.95
weight_decay: 0.0005
display: 100
max_iter: 10000
snapshot: 5000
snapshot_prefix: "examples/mnist/lenet_adadelta"
solver_mode: GPU
type: "RMSProp"
rms_decay: 0.98
最后兩行惕蹄,需要設(shè)置rms_decay值蚯涮。