caffe固定网络权重参数------遇到BatchNorm层和Scale层的时候

通常的做法:

实现的关键变量是:propagate_down 含义:表示当前层的梯度是否向前传播
比如有4个全连接层A->B->C->D
    a. 你希望C层的参数不会改变,C前面的AB层的参数也不会改变,这种情况也就是D层的梯度不往前反向传播到D层的输入blob(也就是C层的输出blob 没有得到梯度),你可以通过设置D层的propagate_down为false来做到。
         propagate_down的数量与输入blob的数量相同,假如你某个层有2个输入blob,那么你应该在该layer的Param里面写上两行:
         propagate_down : 0    # 第1个输入blob不会得到反向传播的梯度
         propagate_down : 0    # 第2个输入blob不会得到反向传播的梯度
         这样的话,你这个layer的梯度就不会反向传播啦,前面的所有layer的参数也就不会改变了
    b. 你希望C层的参数不会改变,但是C前面的AB层的参数会改变,这种情况,只是固定了C层的参数,C层得到的梯度依然会反向传播给前面的B层。只需要将对应的参数blob的学习率调整为0:
在layer里面加上param { lr_mult: 0 }就可以了,比如全连接层里面:
layer {
    type: "InnerProduct"
    param { # 对应第1个参数blob的配置,也就是全连接层的参数矩阵的配置
         lr_mult: 0 # 学习率为0,其他参数可以看caffe.proto里面的ParamSpec这个类型
    }
    param { # 对应第2个参数blob的配置,也就是全连接层的偏置项的配置
        lr_mult: 0 # 学习率为0
    }
}

 

但是遇到BatchNorm层和Scale层的时候,不论使用上面哪种方式固定权重参数,都会发现网络最终出来的值会有细微的变化,这种变化如果是利用新的数据进行微调,可以称为有益的变化,但是如果是在旧模型上增加新的分支,同时保留原来分支的性能,或者说进行KD训练的时候用来固定老师模型的权重的时候,这样的变化就是有害的。解决方式如下:

首先是BatchNorm层,除了将三个参数blob的学习率都设为0以外,看proto的说明:

  • use_global_stats:如果为真,则使用保存的均值和方差,否则采用滑动平均计算新的均值和方差。该参数缺省的时候,如果是测试阶段则等价为真,如果是训练阶段则等价为假。

   

所以需要特别注意的一件事就是:

如果在训练模型的过程中,需要固定batch norm层的参数,不能光设置局部的lr_mult为0,还需要将use_global_stats设置为true

 

也就是说,如果要固定batchnorm层的参数,不能光设置学习率为0,或者后面层的梯度不往前传播,还需要将use_global_stats的值设置为true,才能保证该层的参数没有任何改变。

 

另外,Scale层也有学习率:

layer {

 name: "scale_conv1"

    type: "Scale"

    bottom: "conv1"

    top: "conv1"

   

    param {

      lr_mult: 0

      decay_mult: 0

    }

    param {

      lr_mult: 0

      decay_mult: 0

    }

    scale_param {

        bias_term: true

    }

}

只要按照以上将scale的学习率置为0即可

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值