pytorch中的param_groups到底是什么意思?

Too*_*nia 3 pytorch learning-rate

我想在训练期间更新 pytorch 中与每个权重矩阵和每个偏差相对应的学习率。这里这里的答案以及我在网上找到的许多其他答案都谈到使用模型来做到这一点,param_groups据我所知,该模型应用分组学习率,而不是特定于层权重/偏差。我还想在训练期间更新学习率,而不是预先设置它们torch.optim

任何帮助表示赞赏。

jod*_*dag 10

模型参数的更新由 PyTorch 中的优化器处理。定义优化器时,您可以选择将模型参数划分为不同的组,称为参数组。每个参数组可以有不同的优化器设置。例如,一组参数的学习率为 0.1,另一组参数的学习率为 0.01。

要执行您所要求的操作,您只需使每个参数属于不同的参数组即可。您需要某种方法来跟踪哪个参数组对应于哪个参数。一旦您定义了不同组的优化器,您就可以随时更新学习率,包括在训练时。

例如,假设我们有以下简单的线性模型

import torch
import torch.nn as nn
import torch.optim as optim


class LinearModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.layer1 = nn.Linear(10, 20) 
        self.layer2 = nn.Linear(20, 1)

    def forward(self, x): 
        return self.layer2(self.layer1(x))


model = LinearModel()
Run Code Online (Sandbox Code Playgroud)

假设我们希望根据以下方式初始化每个可训练参数的学习率:

learning_rates = { 
    'layer1.weight': 0.01,
    'layer1.bias': 0.1,
    'layer2.weight': 0.001,
    'layer2.bias': 1.0}
Run Code Online (Sandbox Code Playgroud)

当我们初始化优化器时,我们可以使用这个字典为每个参数定义不同的学习率。

# Build param_group where each group consists of a single parameter.
# `param_group_names` is created so we can keep track of which param_group
# corresponds to which parameter.
param_groups = []
param_group_names = []
for name, parameter in model.named_parameters():
    param_groups.append({'params': [parameter], 'lr': learning_rates[name]})
    param_group_names.append(name)

# optimizer requires default learning rate even if its overridden by all param groups
optimizer = optim.SGD(param_groups, lr=10)
Run Code Online (Sandbox Code Playgroud)

或者,我们可以省略该'lr'条目,并且每个参数组都将使用默认学习率进行初始化(lr=10在本例中)。

在训练时,如果我们想要更新学习率,我们可以通过迭代每个学习率optimizer.param_groups并更新'lr'每个学习率的条目来实现。例如,在下面的简化训练循环中,我们在每一步之前更新学习率。

for i in range(10):
    output = model(torch.zeros(1, 10))
    loss = output.sum()
    optimizer.zero_grad()
    loss.backward()

    # we can change the learning rate whenever we want for each param group
    print(f'step {i} learning rates')
    for name, param_group in zip(param_group_names, optimizer.param_groups):
        param_group['lr'] = learning_rates[name] / (i + 1)
        print(f'    {name}: {param_group["lr"]}')

    optimizer.step()
Run Code Online (Sandbox Code Playgroud)

打印

step 0 learning rates
    layer1.weight: 0.01
    layer1.bias: 0.1
    layer2.weight: 0.001
    layer2.bias: 1.0
step 1 learning rates
    layer1.weight: 0.005
    layer1.bias: 0.05
    layer2.weight: 0.0005
    layer2.bias: 0.5
step 2 learning rates
    layer1.weight: 0.0033333333333333335
    layer1.bias: 0.03333333333333333
    layer2.weight: 0.0003333333333333333
    layer2.bias: 0.3333333333333333
step 3 learning rates
    layer1.weight: 0.0025
    layer1.bias: 0.025
    layer2.weight: 0.00025
    layer2.bias: 0.25
step 4 learning rates
    layer1.weight: 0.002
    layer1.bias: 0.02
    layer2.weight: 0.0002
    layer2.bias: 0.2
step 5 learning rates
    layer1.weight: 0.0016666666666666668
    layer1.bias: 0.016666666666666666
    layer2.weight: 0.00016666666666666666
    layer2.bias: 0.16666666666666666
step 6 learning rates
    layer1.weight: 0.0014285714285714286
    layer1.bias: 0.014285714285714287
    layer2.weight: 0.00014285714285714287
    layer2.bias: 0.14285714285714285
step 7 learning rates
    layer1.weight: 0.00125
    layer1.bias: 0.0125
    layer2.weight: 0.000125
    layer2.bias: 0.125
step 8 learning rates
    layer1.weight: 0.0011111111111111111
    layer1.bias: 0.011111111111111112
    layer2.weight: 0.00011111111111111112
    layer2.bias: 0.1111111111111111
step 9 learning rates
    layer1.weight: 0.001
    layer1.bias: 0.01
    layer2.weight: 0.0001
    layer2.bias: 0.1
Run Code Online (Sandbox Code Playgroud)