some questions
1.使用pycharm遠(yuǎn)程連接服務(wù)器的python解釋器進(jìn)行調(diào)試時(shí)喊暖,如何調(diào)用遠(yuǎn)程的caffe惫企?
在pycharm的run-->edit configurations-->Environment variables中,設(shè)置環(huán)境變量:
Name: PYTHONPATH
Value: 遠(yuǎn)程python解釋器使用的caffe路徑
2.caffe訓(xùn)練時(shí)loss=87.3365
- 原因分析
在softmax_loss_layer.cpp的源碼中陵叽,是由label的非零維直接計(jì)算loss的
loss -= log(std::max(prob_data[i * dim + label_value * inner_num_ + j], Dtype(FLT_MIN)));
loss的最大值由FLT_MIN得到雅任,F(xiàn)LT_MIN定義為1.17549435E-38F,這個(gè)數(shù)字的自然對(duì)數(shù)正好就是-87.3356咨跌,算loss時(shí)需要取負(fù)值沪么,結(jié)果就得到87.3356。
這說(shuō)明softmax計(jì)算得到的概率值出現(xiàn)了零(由于float類型所能表示的最小數(shù)值是10?38锌半,比這個(gè)值還小的無(wú)法表示禽车,只能是零)
而softmax是用指數(shù)函數(shù)計(jì)算的,指數(shù)函數(shù)的值都是大于零的刊殉。因此殉摔,我們有理由相信,計(jì)算過(guò)程中出現(xiàn)了float溢出等異常记焊,出現(xiàn)了inf逸月,nan等異常數(shù)值導(dǎo)致softmax輸出為零
最后我們發(fā)現(xiàn),當(dāng)softmax之前的feature值過(guò)大時(shí)遍膜,由于softmax先求指數(shù)碗硬,會(huì)超出float數(shù)據(jù)范圍,成為inf瓢颅。inf與其他任何數(shù)值的和都是inf恩尾,softmax在做除法時(shí)任何正常范圍的數(shù)值除以inf都會(huì)變?yōu)?。然后求loss時(shí)log一下就出現(xiàn)了87.3356這樣的值挽懦。
解決方案1
總體上看翰意,softmax輸入的feature由兩部分計(jì)算得到:一部分是輸入數(shù)據(jù),另部分是各層權(quán)重參數(shù)信柿。
1冀偶、觀察數(shù)據(jù)中是否有異常樣本或異常label導(dǎo)致數(shù)據(jù)讀取異常
2、調(diào)小初始化權(quán)重渔嚷,以便使softmax輸入的feature盡可能變小
3进鸠、降低學(xué)習(xí)率,這樣就能減小權(quán)重參數(shù)的波動(dòng)范圍圃伶,從而減小權(quán)重變大的可能性堤如。這條也是網(wǎng)上出現(xiàn)較多的方法蒲列。
4、如果有BN(batch normalization)層搀罢,finetune時(shí)最好不要凍結(jié)BN的參數(shù)蝗岖,否則數(shù)據(jù)分布不一致時(shí)很容易使輸出值變的很大。解決方案2
可以在solver里面設(shè)置:debug_info: true
打印出各個(gè)層的data和diff是什么值榔至,一般這個(gè)時(shí)候那些值不是NAN(無(wú)效數(shù)字)就是INF(無(wú)窮大)抵赢。
可以嘗試以下解決辦法:
1、數(shù)據(jù)問(wèn)題唧取,檢查數(shù)據(jù)的標(biāo)簽是否從0開(kāi)始且連續(xù)
2铅鲤、把學(xué)習(xí)率base_lr調(diào)低,然后batchsize也調(diào)高
3枫弟、中間層沒(méi)有歸一化邢享,導(dǎo)致經(jīng)過(guò)幾層后,輸出的值已經(jīng)很小了淡诗,這個(gè)時(shí)候再計(jì)算梯度就會(huì)發(fā)散骇塘,所以可以在各個(gè)卷積層加入了BN層和SCALE層。
4韩容、把data層的輸入圖片進(jìn)行歸一化款违,就是從0-255歸一化到0-1,使用的參數(shù)是:
transform_param {
scale: 0.00390625//像素歸一化群凶,1/255
}
5插爹、網(wǎng)絡(luò)參數(shù)太多,網(wǎng)絡(luò)太深请梢,刪掉幾層看看赠尾,可能因?yàn)閿?shù)據(jù)少,需要減少中間層的num_output
6溢陪、記得要shuffle數(shù)據(jù)萍虽,否則數(shù)據(jù)不夠隨機(jī)睛廊,幾個(gè)batch之間的數(shù)據(jù)差異很小形真,一旦連續(xù)幾個(gè)batch把loss調(diào)很小,然后就會(huì)導(dǎo)致loss突然變大超全。
7咆霜、如果是自己寫(xiě)的loss,查看loss寫(xiě)的對(duì)不對(duì)
8嘶朱、更換不同顯卡訓(xùn)練蛾坯,排除顯卡問(wèn)題
3. pycharm調(diào)試caffe,加載模型時(shí)報(bào)錯(cuò):Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
- 原因:修改了將pycaffe重新編譯了疏遏,而Pycharm運(yùn)行時(shí)所使用的python package環(huán)境與pycaffe編譯時(shí)不一樣脉课,導(dǎo)致出現(xiàn)這個(gè)錯(cuò)誤
- 解決方案:調(diào)整pycharm使用的python環(huán)境救军,使其與pycaffe編譯時(shí)一致即可,問(wèn)題解決倘零。
2.some tricks
- caffe在測(cè)試和訓(xùn)練階段唱遭,最好建立不同的prototxt文件
訓(xùn)練時(shí)需要:net_train.prototxt, net_solver.prototxt
測(cè)試時(shí)需要:net_inference.prototxt
solver.prototxt中參數(shù)在文件:
/home/yangshuai/projects/zhiji/caffe-segnet/src/caffe/proto/caffe.proto
中查看不要用
./build/tools/caffe train --solver=xxx
這種方式來(lái)跑代碼, github上有一些原因,說(shuō)是因?yàn)槟氵@樣子做的話,后面的deconvolution層是沒(méi)有辦法初始化的,會(huì)造成這些層的參數(shù)都為0,從而導(dǎo)致你的loss一直保持一個(gè)很大很大的數(shù)值不變動(dòng)。
如果你遇到loss的數(shù)值不變化的情況,請(qǐng)改用solve.py文件來(lái)調(diào)用caffe訓(xùn)練,里面會(huì)有一些初始化這些參數(shù)的過(guò)程呈驶。自己修改好的源碼和配置文件拷泽、網(wǎng)絡(luò)結(jié)構(gòu)等,最好用pascal voc數(shù)據(jù)先跑一遍袖瞻,確定代碼沒(méi)有問(wèn)題司致,再在自己的數(shù)據(jù)上訓(xùn)練。
caffe prototxt模型結(jié)構(gòu)可視化的網(wǎng)址
http://ethereon.github.io/netscope/#/editor
caffe中的BN
在BVLC的Caffe實(shí)現(xiàn)中聋迎,BN層需要和Scale層配合使用脂矫。
BN層專門(mén)用來(lái)做“Normalization”操作,而后續(xù)的線性變換層霉晕,交給Scale層去做羹唠。
- batchnorm與scale配合使用實(shí)現(xiàn)bn的功能:
layer {
bottom: "conv1"
top: "conv1"
name: "bn_conv1"
type: "BatchNorm"
batch_norm_param {
use_global_stats: true
}
}
layer {
bottom: "conv1"
top: "conv1"
name: "scale_conv1"
type: "Scale"
scale_param {
bias_term: true
}
}
- BN層的use_global_stats參數(shù)設(shè)置
(1)設(shè)置為False的話,更新全局統(tǒng)計(jì)量娄昆,對(duì)當(dāng)前的mini-batch進(jìn)行規(guī)范化時(shí)佩微,不使用全局統(tǒng)計(jì)量,而使用當(dāng)前batch的均值和方差萌焰。
(2)設(shè)置為T(mén)rue哺眯,使用全局統(tǒng)計(jì)量做規(guī)范化。
(3)這個(gè)變量默認(rèn)隨著當(dāng)前網(wǎng)絡(luò)在train或test phase而變化扒俯。當(dāng)train時(shí)為false奶卓,當(dāng)test時(shí)為true。