在 PyTorch 中定义 Adam 优化器的最佳方式是什么?

What is the Best way to define Adam Optimizer in PyTorch?

对于大多数 PyTorch 代码,我们使用 Adam 优化器的以下定义,

optim = torch.optim.Adam(model.parameters(), lr=cfg['lr'], weight_decay=cfg['weight_decay'])

然而,经过反复试验,我发现Adam的以下定义给出了高出1.5 dB的PSNR,这是巨大的。

optim = torch.optim.Adam(
            [
                {'params': get_parameters(model, bias=False)},
                {'params': get_parameters(model, bias=True), 'lr': cfg['lr'] * 2, 'weight_decay': 0},
            ],
            lr=cfg['lr'],
            weight_decay=cfg['weight_decay'])

Model 是一个普通的 U-net,其参数在 initforward action 中定义,就像在任何其他 PyTorch 模型中一样。

get_parameters定义如下。

def get_parameters(model, bias=False):
    for k, m in model._modules.items():
        print("get_parameters", k, type(m), type(m).__name__, bias)
        if bias:
            if isinstance(m, nn.Conv2d):
                yield m.bias
        else:
            if isinstance(m, nn.Conv2d) or isinstance(m, nn.ConvTranspose2d):
                yield m.weight

有人可以解释为什么后一个定义比前一个定义好吗?

在第二种方法中,提供了不同的配置来更新权重和偏差。这是使用优化器 per-parameter options 完成的。

optim = torch.optim.Adam(
            [
                {'params': get_parameters(model, bias=False)},
                {'params': get_parameters(model, bias=True), 'lr': cfg['lr'] * 2, 'weight_decay': 0},
            ],
            lr=cfg['lr'],
            weight_decay=cfg['weight_decay'])

据此,偏差的学习率是权重的2倍,权重衰减为0。

现在,这样做的原因可能是网络没有正确学习。阅读更多 Why is the learning rate for the bias usually twice as large as the the LR for the weights?