PyTorch优化器正则化问题:偏置(bias)不需要正则化(weight decay) / 如何分离网络参数中的偏置(bias)?

问题描述

截至目前,PyTorch中有一个潜在的不合理之处,即pytorch优化器中的正则化会将所有可训练参数都进行正则化,而理论上,偏置(bias)是没有必要进行正则化的(反而会限制模型的能力)。以Adam优化器为例,我们在模型的训练开始之前,一般会这样定义优化器:

optimizer = torch.optim.Adam(net.parameters(), lr=0.01, weight_decay=0.0001)

其中weight_decay为正则化项的系数。如上定义,模型在训练时,模型的所有参数(即net.parameters())都将被正则化,而我们希望其中的偏置(bias)不要被正则化。怎么办?

解决方案

pytorch的torch.optim.Adam的第一个参数接受一个可学习参数的迭代器(或列表),同时还可以是字典。如下

optimizer = torch.optim.Adam([
    {'params': net.layer.weight, 'weight_decay': 0.0001},
    {'params': net.layer.bias}
], lr=0.01)

如上指定了可学习参数net.layer.bias(这是网络中的一个偏置参数)的学习率lr0.01weight_decay0(也就是没有正则化项)。

对于非常简单的模型,我们可以手动把可学习参数写成如上代码中的字典形式,但对于比较复杂的模型很难手动一个一个的分离出来。通过分析发现,对于比较复杂的模型,其中所有的偏置参数的名字中都含有子串"bias",如下测试:
在这里插入图片描述
其中named_parameters()函数可以获取当前模型中所有的参数(含不可训练的参数)。于是,我们可以这样分离出偏置参数:

bias_list = (p for name, p in net.named_parameters() if 'bias' in name)

注意细节,这里用的是圆括号()而不是[],因为[]默认是列表,会主动进行一次遍历并返回这个列表,而()返回值为迭代器,只有当被动的迭代它时它才会去计算。话句话说就是[]复杂度高一倍。

最终,我们的优化器如下定义即可实现仅weight正则化而bias取消正则化

optimizer = torch.optim.Adam([
    {'params': (p for name, p in net.named_parameters() if 'bias' not in name), 'weight_decay': 0.0001},
    {'params': (p for name, p in net.named_parameters() if 'bias' in name)}
], lr=0.01)
  • 10
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪的期许

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值