caffe训练流程简介:
..\..\bin\caffe.exe train --solver=.\solver.prototxt -weights .\test.caffemodel
1)这里caffe.exe中第一个参数为train表示训练,如果为test表示进行测试
2)不论是finetune还是从头开始的训练,都必须指明solver文件,这个用--solver 指明。下面会介绍finetune时,solver文件的修改以及对应的trian_val和 deploy的修改 。
3)finetune必须指明进行微调的caffemodel,这个用-weights指明。
训练碰到的问题:
1、预训练模型
在caffe中,预训练模型在脚本中设置,有时候拿到的预训练模型跟改过的prototxt对应不上,
预训练的模型根据你当前网络的layer_name进行匹配参数,不是像pytorch一样可以按照尺寸加载。例如加入预训练原始网络的第一个卷积层name是conv1,而你自己的第一个卷积层网络name是Convolution1,那么这个层在预网络中的参数就不会被匹配调用。
在实际使用时,有些层修改以后,尺寸与预训练模型对应不上,对应的name需要修改,否则会报错尺寸不匹配。
2、随机初始化后学习率设置过小。
由于caffe输出层不匹配,所以进行了些许修改,然后在之前的基础上重新训练,结果就导致训练结果收敛速度非常慢。一度以为是冻结参数,模型不学习。
3、固定部分参数,只训练最后FC层,或者是训练指定的层。
应用时,为了保证部分分支结果不变,需要将共享浅层特征提取的backbone参数固定,只训练个别分支参数。有两种方式:
(1)只固定当前层,该层前后层都正常更新,这里只需要设置:
batchnormal层中有三个参数:均值、方差和滑动系数,训练时这三个参数是通过当前的数据计算得到的,不通过反向传播更新,因此必须将lr_mult和decay_mult都设置为0。
#这里对应的param 参数均设置为0即可
#其中卷积参数一个,FC层参数两个,BN参数三个,分别设置。
layer {
name: "conv2/bn"
type: "BatchNorm"
bottom: "conv2_out"
top: "conv2_bn"
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
}
(2)该层正常更新,但是该层前面的参数均不更新。
layer {
name: "conv2/bn"
type: "Convolution"
bottom: "conv2_in1"
bottom: "conv2_in2"
top: "conv2_out"
# propagate_down的数量与输入blob的数量相同,
# 假设某个层有2个输入blob,那么你应该在该layer的Param里面写上两行:
propagate_down : 0 # 第1个输入blob不会得到反向传播的梯度
propagate_down : 0 # 第2个输入blob不会得到反向传播的梯度
param {
lr_mult: 0
decay_mult: 0
}
}
4、lr_mult和decay_mult
这里解释下, lr_mult和 decay_mult分别是学习率和正则化的权重参数,当令 lr_mult = x 时,相当于该层的学习率为 solver.prototxt 中的 base_lr * x,当没有设置 lr_mult 和 decay_mult 时,默认等于 1,也就是该层的参数按照 base_lr 进行学习;某一层 lr_mult 和 decay_mult 都设为 0,该层的参数不更新权重。
decay_mult是正则化的权重,防止过拟合用的。为了防止模型参数太复杂导致过拟合,一般在目标函数计算的时候加入了正则项,所谓的weight_decay其实就是正则项前面的那个权值,设置偏大可以令模型在学习过程中约束参数的复杂程度。
而在caffe当中,除了全局设置的学习率lr和权重衰减项也就是weight_decay,每一个需要学习参数的layer都还有局部的加权值,分别是lr_mult和decay_mult,而对于卷积层的话,w和b都属于可以学习的参数,所以在学习更新中他们都有属于自己的lr_mult和decay_mult。
对于参数use_global_stats:如果为真,则使用保存的均值和方差,否则采用滑动平均计算新的均值和方差。该参数缺省的时候,如果是测试阶段则等价为真,如果是训练阶段则等价为假(采用滑动平均计算新的均值和方差)。
由于BN层中会做归一化处理,因此BN层前的那个卷积层应当将bias关闭。因为BN的操作会做一个减去均值的操作,因此卷积层有没有bias都会被这个减法操作去除掉,所以这时候bias不起作用,因此将其关闭可以减少参数量且不影响模型准确率。
此外,caffe的Scale层不需要对两个参数正则化,因此 decay_mult: 0
5、训练出现NAN和87.3365。
网上查了下大概有以下几个原因:降低学习率,提高batchsize;输入归一化;查看输入数据、标签是否有异常;数据shuffle;batch normalization的设置,将batch normaliztion的use_global_stats由true改成false。
我这里原因是因为更换了激活函数,tanh更换为relu导致,妥协了又换回去了。
6、caffe训练训练慢,loss收敛慢
因为常年浸泡在pytorch中,没想到caffe训练收敛的超级慢,当时也有我数据的原因。刚开始测试,数据的结果趋向于一致,还以为是设置错误,后来发现是收敛慢以后,增大学习率,增大 lr_mult,多训练会结果就正常了。
网上查了下这个还挺常见的,
数据集记得打乱,不然很可能不收敛。
如果出现不收敛的问题,可以把solver里的lr设的小一点,一般从0.01开始,如果出现loss=nan了就不断往小调整
还有一些别人踩的坑:数据集类别号要从0开始,一定要连续。
参考文档:
https://blog.csdn.net/weixin_43593330/article/details/108347536
https://blog.csdn.net/weixin_41770169/article/details/87191442
https://blog.csdn.net/nongfu_spring/article/details/51514040