在Pytorch中手动更新权重


import torch
import math

# Create Tensors to hold input and outputs.
x = torch.linspace(-math.pi, math.pi, 2000)
y = torch.sin(x)
# For this example, the output y is a linear function of (x, x^2, x^3), so
# we can consider it as a linear layer neural network. Let's prepare the
# tensor (x, x^2, x^3).
p = torch.tensor([1, 2, 3])
xx = x.unsqueeze(-1).pow(p)
model = torch.nn.Sequential(
    torch.nn.Linear(3, 1),
    torch.nn.Flatten(0, 1)
)
loss_fn = torch.nn.MSELoss(reduction='sum')
learning_rate = 1e-6

然后打印权重

parameters = list(model.parameters())
print(parameters)

结果:

[Parameter containing:
tensor([[ 0.0407,  0.2680, -0.1148]], requires_grad=True), Parameter containing:
tensor([-0.0132], requires_grad=True)]
y_pred = model(xx)
loss = loss_fn(y_pred, y)
model.zero_grad()
loss.backward()

更新权重:

with torch.no_grad():  
    for param in model.parameters():
        param -= 1e-6 * param.grad

list(model.parameters())
[Parameter containing:
 tensor([[ 0.0532,  0.2472, -0.0393]], requires_grad=True),
 Parameter containing:
 tensor([-0.0167], requires_grad=True)]

权重已更新。我很困惑。这怎么可能呢?我认为只是参数for循环中的变量发生了变化,而不是model.parameters()。

但是当代码改变一个位

with torch.no_grad():  
    for param in model.parameters():
        param -= 1e-6

权重没有变化。我猜它和有关param。grad。你们能给我解释一下吗?

循环内的param变量引用 model.parameters()的每个元素。因此,更新param与更新model.parameters()的元素是一样的。

至于你的第二个例子,我认为递减1e-6是不够的,你看到的效果。试试param -= 1.,看看这对model.parameters()是否有影响。

最新更新