some questions
1.使用pycharm远程连接服务器的python解释器进行调试时,如何调用远程的caffe?
在pycharm的run-->edit configurations-->Environment variables中,设置环境变量:
Name: PYTHONPATH
Value: 远程python解释器使用的caffe路径
2.caffe训练时loss=87.3365
- 原因分析
在softmax_loss_layer.cpp的源码中,是由label的非零维直接计算loss的
loss -= log(std::max(prob_data[i * dim + label_value * inner_num_ + j], Dtype(FLT_MIN)));
loss的最大值由FLT_MIN得到,FLT_MIN定义为1.17549435E-38F,这个数字的自然对数正好就是-87.3356,算loss时需要取负值,结果就得到87.3356。
这说明softmax计算得到的概率值出现了零(由于float类型所能表示的最小数值是10−38,比这个值还小的无法表示,只能是零)
而softmax是用指数函数计算的,指数函数的值都是大于零的。因此,我们有理由相信,计算过程中出现了float溢出等异常,出现了inf,nan等异常数值导致softmax输出为零
最后我们发现,当softmax之前的feature值过大时,由于softmax先求指数,会超出float数据范围,成为inf。inf与其他任何数值的和都是inf,softmax在做除法时任何正常范围的数值除以inf都会变为0。然后求loss时log一下就出现了87.3356这样的值。
解决方案1
总体上看,softmax输入的feature由两部分计算得到:一部分是输入数据,另部分是各层权重参数。
1、观察数据中是否有异常样本或异常label导致数据读取异常
2、调小初始化权重,以便使softmax输入的feature尽可能变小
3、降低学习率,这样就能减小权重参数的波动范围,从而减小权重变大的可能性。这条也是网上出现较多的方法。
4、如果有BN(batch normalization)层,finetune时最好不要冻结BN的参数,否则数据分布不一致时很容易使输出值变的很大。解决方案2
可以在solver里面设置:debug_info: true
打印出各个层的data和diff是什么值,一般这个时候那些值不是NAN(无效数字)就是INF(无穷大)。
可以尝试以下解决办法:
1、数据问题,检查数据的标签是否从0开始且连续
2、把学习率base_lr调低,然后batchsize也调高
3、中间层没有归一化,导致经过几层后,输出的值已经很小了,这个时候再计算梯度就会发散,所以可以在各个卷积层加入了BN层和SCALE层。
4、把data层的输入图片进行归一化,就是从0-255归一化到0-1,使用的参数是:
transform_param {
scale: 0.00390625//像素归一化,1/255
}
5、网络参数太多,网络太深,删掉几层看看,可能因为数据少,需要减少中间层的num_output
6、记得要shuffle数据,否则数据不够随机,几个batch之间的数据差异很小,一旦连续几个batch把loss调很小,然后就会导致loss突然变大。
7、如果是自己写的loss,查看loss写的对不对
8、更换不同显卡训练,排除显卡问题
3. pycharm调试caffe,加载模型时报错:Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
- 原因:修改了将pycaffe重新编译了,而Pycharm运行时所使用的python package环境与pycaffe编译时不一样,导致出现这个错误
- 解决方案:调整pycharm使用的python环境,使其与pycaffe编译时一致即可,问题解决。
2.some tricks
- caffe在测试和训练阶段,最好建立不同的prototxt文件
训练时需要:net_train.prototxt, net_solver.prototxt
测试时需要:net_inference.prototxt
solver.prototxt中参数在文件:
/home/yangshuai/projects/zhiji/caffe-segnet/src/caffe/proto/caffe.proto
中查看不要用
./build/tools/caffe train --solver=xxx
这种方式来跑代码, github上有一些原因,说是因为你这样子做的话,后面的deconvolution层是没有办法初始化的,会造成这些层的参数都为0,从而导致你的loss一直保持一个很大很大的数值不变动。
如果你遇到loss的数值不变化的情况,请改用solve.py文件来调用caffe训练,里面会有一些初始化这些参数的过程。自己修改好的源码和配置文件、网络结构等,最好用pascal voc数据先跑一遍,确定代码没有问题,再在自己的数据上训练。
caffe prototxt模型结构可视化的网址
http://ethereon.github.io/netscope/#/editor
caffe中的BN
在BVLC的Caffe实现中,BN层需要和Scale层配合使用。
BN层专门用来做“Normalization”操作,而后续的线性变换层,交给Scale层去做。
- batchnorm与scale配合使用实现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参数设置
(1)设置为False的话,更新全局统计量,对当前的mini-batch进行规范化时,不使用全局统计量,而使用当前batch的均值和方差。
(2)设置为True,使用全局统计量做规范化。
(3)这个变量默认随着当前网络在train或test phase而变化。当train时为false,当test时为true。