【问题标题】:Pytorch Not Updating Variables in .step()Pytorch 不更新 .step() 中的变量
【发布时间】:2019-08-22 00:15:08
【问题描述】:

我正在尝试将旧代码转换为 PyTorch 代码作为实验。最终,我将对 10,000+ x 100 矩阵进行回归,适当地更新权重等等。

尝试学习,我正在慢慢扩大玩具示例。我正在使用以下示例代码碰壁。

import torch 
import torch.nn as nn 
import torch.nn.functional as funct  
from torch.autograd import Variable 



device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 

x_data = Variable( torch.Tensor( [ [1.0, 2.0], [2.0, 3.0], [3.0, 4.0] ] ), 
requires_grad=True )
y_data = Variable( torch.Tensor( [ [2.0], [4.0], [6.0] ] ) ) 

w = Variable( torch.randn( 2, 1, requires_grad=True ) )

b = Variable( torch.randn( 1, 1, requires_grad=True ) )


class Model(torch.nn.Module) :
    def __init__(self) :
        super( Model, self).__init__()
        self.linear = torch.nn.Linear(2,1) ## 2 features per entry. 1 output
    def forward(self, x2, w2, b2) :
        y_pred = x2 @ w2 + b2
        return y_pred


model = Model()

criterion = torch.nn.MSELoss( size_average=False )
optimizer = torch.optim.SGD( model.parameters(), lr=0.01 )

for epoch in range(10) :
    y_pred = model( x_data,w,b ) # Get prediction
    loss = criterion( y_pred, y_data ) # Calc loss
    print( epoch, loss.data.item() ) # Print loss
    optimizer.zero_grad() # Zero gradient 
    loss.backward() # Calculate gradients
    optimizer.step() # Update w, b

但是,这样做,我的损失总是一样的,调查显示我的 w 和 b 从未真正改变。我对这里发生的事情有点迷茫。

最终,我希望能够存储“新” w 和 b 的结果,以便在迭代和数据集之间进行比较。

【问题讨论】:

    标签: regression linear-regression pytorch prediction


    【解决方案1】:

    在我看来,这就像一个货物编程案例。

    请注意,您的Model 类没有在forward 中使用self,因此它实际上是一个“常规”(非方法)函数,而model 是完全无状态的。最简单的代码修复方法是通过将optimizer = torch.optim.SGD([w, b], lr=0.01) 创建为wb,使optimizer 知道它。我还把model改写成一个函数

    import torch
    import torch.nn as nn
    # torch.autograd.Variable is roughly equivalent to requires_grad=True
    # and is deprecated in PyTorch 1.0
    
    # your code gives not reason to have `requires_grad=True` on `x_data`
    x_data = torch.tensor( [ [1.0, 2.0], [2.0, 3.0], [3.0, 4.0] ])
    y_data = torch.tensor( [ [2.0], [4.0], [6.0] ] )
    
    w = torch.randn( 2, 1, requires_grad=True )
    b = torch.randn( 1, 1, requires_grad=True )
    
    def model(x2, w2, b2):
        return x2 @ w2 + b2
    
    criterion = torch.nn.MSELoss( size_average=False )
    optimizer = torch.optim.SGD([w, b], lr=0.01 )
    
    for epoch in range(10) :
        y_pred = model( x_data,w,b )
        loss = criterion( y_pred, y_data )
        print( epoch, loss.data.item() )
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    

    话虽如此,nn.Linear 旨在简化此过程。它会自动创建wb 的等效项,分别称为self.weightself.bias。此外,self.__call__(x) 等同于 Model 的转发定义,因为它返回 self.weight @ x + self.bias。也就是说,你也可以使用替代代码

    import torch
    import torch.nn as nn
    
    x_data = torch.tensor( [ [1.0, 2.0], [2.0, 3.0], [3.0, 4.0] ] )
    y_data = torch.tensor( [ [2.0], [4.0], [6.0] ] )
    
    model = nn.Linear(2, 1)
    
    criterion = torch.nn.MSELoss( size_average=False )
    optimizer = torch.optim.SGD(model.parameters(), lr=0.01 )
    
    for epoch in range(10) :
        y_pred = model(x_data)
        loss = criterion( y_pred, y_data )
        print( epoch, loss.data.item() )
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    

    其中model.parameters()可以用来枚举模型参数(相当于上面手动创建的列表[w, b])。要访问您的参数(加载、保存、打印等),请使用 model.weightmodel.bias

    【讨论】:

    • 谢谢!我会试一试。 PyTorch 看起来如此有用且如此强大,但目前适应起来有点棘手,所以我很欣赏这一点。我不只是使用 nn.Linear 的原因是,最终,我的放大版本将有更多的权重和因子以及其他东西,所以我正在尝试学习如何在没有一些捷径的情况下使用它。
    猜你喜欢
    • 2018-11-26
    • 2018-06-30
    • 2019-04-18
    • 1970-01-01
    • 2020-12-04
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    相关资源
    最近更新 更多