我想为每个参数的最低级别设置特定的学习率。 即内核权重和偏差中的每个值都应该有自己的学习率。
我可以像这样指定过滤器的学习率:
optim = torch.optim.SGD([{'params': model.conv1.weight, 'lr': 0.1},], lr=0.01)
但是当我想降低一个级别时,就像这样:
optim = torch.optim.SGD([{'params': model.conv1.weight[0, 0, 0, 0], 'lr': 0.1},], lr=0.01)
我收到错误:ValueError: can't optimize a non-leaf Tensor
我还尝试指定与过滤器形状相同的学习率,例如'lr': torch.ones_like(model.conv1.weight)
,但这也没有成功。
有没有办法使用torch.optim
来做到这一点?
我可能已经找到了解决方案。由于只能输入 Conv 层的整个权重和偏差,我们需要插入一个与权重/偏差张量形状相同的学习率。
下面是一个使用torch.optim.Adam
的示例:
torch.optim.CustomAdam([{'params': param, 'lr': torch.ones_like(param, requires_grad=False) * lr}
for name, param in model.named_parameters()])
然后我们必须更改优化器本身中的一行。为此,我创建了一个自定义优化器:
class CustomAdam(torch.optim.Adam):
def step(self, closure=None):
...
# change the last line: p.data.addcdiv_(-step_size, exp_avg, denom) to
p.data.add_((-step_size * (exp_avg / denom)))
一个简单的技巧是创建一个名为learning_rate
的新张量,它的大小与模型相同。然后,当您应用梯度时,您将gradients
张量与learning_rate
张量相乘。请让我知道这是否适合您。