【问题标题】:Parameter-specific learning rate in PyTorchPyTorch 中的参数特定学习率
【发布时间】:2019-11-24 14:59:03
【问题描述】:

如何为网络中的每个特定参数(权重和偏差)设置学习率?

PyTorch's docs 我发现了这个:

optim.SGD([{'params': model.base.parameters()}, 
           {'params': model.classifier.parameters(), 'lr': 1e-3}], 
           lr=1e-2, momentum=0.9)

其中model.classifier.parameters(),定义了一组参数,得到的具体学习率为1e-3。

但是我怎样才能把它翻译成参数级别呢?

【问题讨论】:

    标签: deep-learning pytorch gradient-descent


    【解决方案1】:

    您可以通过使用参数名称设置学习率来设置特定参数的学习率,例如

    对于取自PyTorch forum的给定网络:

    class Net(nn.Module):
        def __init__(self):
            super(Net, self).__init__()
            self.layer1 = nn.Linear(1, 1)
            self.layer1.weight.data.fill_(1)
            self.layer1.bias.data.fill_(1)
            self.layer2 = nn.Linear(1, 1)
            self.layer2.weight.data.fill_(1)
            self.layer2.bias.data.fill_(1)
    
        def forward(self, x):
            x = self.layer1(x)
            return self.layer2(x)
    
    net = Net()
    for name, param in net.named_parameters():
        print(name)
    

    参数为:

    layer1.weight
    layer1.bias
    layer2.weight
    layer2.bias
    

    然后,您可以使用参数名称来设置它们的具体学习率,如下所示:

    optimizer = optim.Adam([
                {'params': net.layer1.weight},
                {'params': net.layer1.bias, 'lr': 0.01},
                {'params': net.layer2.weight, 'lr': 0.001}
            ], lr=0.1, weight_decay=0.0001)
    
    out = net(torch.Tensor([[1]]))
    out.backward()
    optimizer.step()
    print("weight", net.layer1.weight.data.numpy(), "grad", net.layer1.weight.grad.data.numpy())
    print("bias", net.layer1.bias.data.numpy(), "grad", net.layer1.bias.grad.data.numpy())
    print("weight", net.layer2.weight.data.numpy(), "grad", net.layer2.weight.grad.data.numpy())
    print("bias", net.layer2.bias.data.numpy(), "grad", net.layer2.bias.grad.data.numpy())
    

    输出:

    weight [[0.9]] grad [[1.0001]]
    bias [0.99] grad [1.0001]
    weight [[0.999]] grad [[2.0001]]
    bias [1.] grad [1.]
    

    【讨论】:

    • 感谢您的回答。是否甚至可以专门访问 conv 过滤器权重?
    • 你可以使用.weight.bias对应每一层(你可以像我一样通过循环.parameters()得到它的名字)用于conv层.
    • 我的意思是像这样访问内核中的每个参数:{'params': model.conv.weight[0, 0, 0, 0], 'lr': 0.1}。不幸的是,这给了我一个错误:ValueError: can't optimize a non-leaf Tensor
    • 我不确定在这种情况下是否可以这样做。我会检查是否可能。
    • 我可能找到了方法。需要新建一个优化器,把torch.optim.Adamstep方法中的最后一行改成:p.data.add_((-step_size * (exp_avg.type(torch.double) / denom.type(torch.double))).type(torch.float32))
    猜你喜欢
    • 2020-11-16
    • 2019-09-03
    • 2020-03-19
    • 1970-01-01
    • 2020-05-19
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    相关资源
    最近更新 更多