【问题标题】:Very simple optim.SGD training loop not working as expected - PyTorch非常简单的 optim.SGD 训练循环无法按预期工作 - PyTorch
【发布时间】:2020-03-03 15:19:00
【问题描述】:

我一直在阅读 PyTorch 文档,并且一直在尝试找出 MSELoss 和 autograd。我尝试创建一个非常简单的训练循环,它采用两个随机张量并更新每个张量中的值,以便tensor1 中的所有值之和加上tensor2 中的所有值之和加起来为某个目标数。在我的示例中,我使用了 100。以下是我的实现方式:

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

loss = nn.MSELoss()
tensor1 = torch.randn(3, 5, requires_grad=True)
tensor2 = torch.randn(3, 5, requires_grad=True)
target_sum = torch.FloatTensor(torch.Tensor([100]))
optimizer = optim.SGD([nn.Parameter(tensor1), nn.Parameter(tensor2)], lr=1e-4)
print(str(tensor1.sum().item()) + str(tensor2.sum().item()))
for i in range(100):
    pred = tensor1.sum() + tensor2.sum()
    optimizer.zero_grad()
    loss(pred, target_sum).backward
    optimizer.step()
print(str(tensor1.sum().item()) + str(tensor2.sum().item()))

训练循环之前和训练循环之后的张量总和是相同的,但我应该看到总和增加并接近 100。我不确定我在这里缺少什么。我认为这可能与我的优化器有关,因为训练循环几乎直接来自文档示例。我是 PyTorch 的新手,感谢您的帮助!

【问题讨论】:

    标签: python pytorch tensor loss-function autograd


    【解决方案1】:

    使用 abs(pred - target_sum) 计算 loss,因为 predtarget_sum 是标量。此外,删除优化定义中的 nn.Parameter() 包装器。 这就是我所做的。

    In [22]: import torch.nn as nn 
        ...: import torch 
        ...: import torch.optim as optim 
        ...:  
        ...: tensor1 = torch.randn(3, 5, requires_grad=True) 
        ...: tensor2 = torch.randn(3, 5, requires_grad=True) 
        ...: target_sum = 100 
        ...: optimizer = optim.SGD([tensor1, tensor2], lr=1e-2) 
        ...: print(tensor1.sum().item() + tensor2.sum().item()) 
        ...: for i in range(1000): 
        ...:     pred = tensor1.sum() + tensor2.sum() 
        ...:     optimizer.zero_grad() 
        ...:     loss = abs((pred-target_sum)) 
        ...:     loss.backward() 
        ...:     optimizer.step() 
        ...: print(tensor1.sum().item()+ tensor2.sum().item())
    

    这个循环前后的结果如下

    -0.777163028717041
    100.02290725708008
    

    【讨论】:

    • 这似乎不起作用,我什至尝试将迭代次数增加到 1,000,000 次,训练后总和仍然保持不变。
    • 等等,如果你只有predtarget_sum 作为标量值,你为什么要使用MSELoss(),你只需要loss = abs(pred, target_sum)loss.backward(),不是吗? MSELoss(0 实际上进行批处理,您需要为其提供第一个维度为批次的张量。
    • 好的,我现在明白了,删除优化定义中 tensor1 和 tensor2 周围的 nn.Parameter() 包装器,它将起作用。
    • 成功了!为什么在张量周围添加 nn.Parameter() 会使张量在训练期间无法更新?
    • 我必须检查一下,一旦我得到具体的答案,我一定会告诉你的。但这只是我觉得不对劲。当你积极地做某事时,这种直觉就会得到发展。但我肯定会很快回复你。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-26
    • 2022-06-17
    • 2019-01-30
    • 2021-09-12
    • 1970-01-01
    相关资源
    最近更新 更多