caffe训练模型踩到的几个坑

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值