regression - Pytorch 不更新 .step() 中的变量
问题描述
我正在尝试将旧代码转换为 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 的结果,以便在迭代和数据集之间进行比较。
解决方案
对我来说,这看起来像是货物编程的案例。
请注意,您的Model
类没有使用self
in forward
,因此它实际上是一个“常规”(非方法)函数,并且model
完全是无状态的。对您的代码最简单的修复方法是通过将其创建为 来optimizer
了解w
和。我也重写为一个函数b
optimizer = torch.optim.SGD([w, b], lr=0.01)
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
旨在简化此过程。它会自动创建一个等价的w
和,分别b
称为self.weight
和self.bias
。此外,self.__call__(x)
等同于您的 forward 的定义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()
wheremodel.parameters()
可用于枚举模型参数(相当于[w, b]
上面手动创建的列表)。要访问您的参数(加载、保存、打印等),请使用model.weight
和model.bias
。
推荐阅读
- java - Wiremock JSON 响应模板 - 查询中的查询
- excel - Selenium - NG-IF 还是 Next Element?
- mysql - 使用通配符选择以特定字符开头的名称不起作用
- arrays - 排序数组并维护索引
- c++ - Fuse 回调在某些 Azure API 调用上永远挂起
- c# - 使用 GZipStream 压缩字符串而不使用 Base64
- django - 用多对一关系序列化模型中的字段
- python - Python-Selenium-WebDriver 该页面正在滚动过去的元素而不“单击”它们,即使驱动程序应该
- c# - 在 VS2019 中无法将任何共享项目添加到解决方案中
- antlr4 - 为什么 Antlr4 无法解析 C 语法中 FunctionDefinitionContext 的声明符