【问题标题】:Gradient disappearing after first epoch in manual linear regression手动线性回归中第一个时期后梯度消失
【发布时间】:2019-01-07 04:29:51
【问题描述】:

我是 Pytorch 的新手,我一直在学习教程并玩弄玩具示例。我只想制作一个超级简单的模型来更好地处理 autograd,但我遇到了问题。

我正在尝试训练线性回归模型,但一直遇到以下错误,

---------------------------------------------------------------------- 

RuntimeError                              Traceback (most recent call last)
<ipython-input-80-ba5ca34a3a54> in <module>()
      9   loss = torch.dot(delta, delta)
     10 
---> 11   loss.backward()
     12   with torch.no_grad():
     13     w, b = w - learning_rate*w.grad.data, b - learning_rate*b.grad.data

/usr/local/lib/python3.6/dist-packages/torch/tensor.py in backward(self, gradient, retain_graph, create_graph)
     91                 products. Defaults to ``False``.
     92         """
---> 93         torch.autograd.backward(self, gradient, retain_graph, create_graph)
     94 
     95     def register_hook(self, hook):

/usr/local/lib/python3.6/dist-packages/torch/autograd/__init__.py in backward(tensors, grad_tensors, retain_graph, create_graph, grad_variables)
     87     Variable._execution_engine.run_backward(
     88         tensors, grad_tensors, retain_graph, create_graph,
---> 89         allow_unreachable=True)  # allow_unreachable flag
     90 
     91 

RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

供参考,代码在这里,

# dataset for training
X = torch.randn(100, 3)
y = -3*X[:,0] + 2.2*X[:,1] + 0.002*X[:,2] + 1

w = torch.randn(3, requires_grad=True, dtype=torch.float)  # model weights
b = torch.randn(1, requires_grad=True, dtype=torch.float)  # model bias


num_epochs = 10
learning_rate = 1e-4

for i in range(num_epochs):

  y_hat = torch.mv(X, w) + b
  delta = y_hat - y
  loss = torch.dot(delta, delta)

  loss.backward()
  with torch.no_grad():
    w, b = w - learning_rate*w.grad, b - learning_rate*b.grad

问题似乎是在第一个时期之后,渐变属性设置为无,但我有点困惑为什么会这样。

如果我在更新权重后尝试将梯度归零,则会出现类似的错误。

【问题讨论】:

    标签: pytorch


    【解决方案1】:

    答案就在locally disabling gradient computation。正如您在第一个示例中所见,使用 torch.no_grad() 上下文管理器执行的计算会产生 requires_grad == False 的张量。由于您创建了“新鲜”wb 而不是就地更新它们,因此这些张量在第一次迭代后失去了 requires_grad 属性,并且您在第二次迭代中得到错误。一个简单的解决方法是重新启用渐变

    with torch.no_grad(): 
        w, b = w - learning_rate*w.grad, b - learning_rate*b.grad 
        w.requires_grad_(True) 
        b.requires_grad_(True) 
    

    如果你在 pytorch optim 模块中查找优化器的来源,例如 SGD,你会发现它们使用了就地操作符,例如 add_。你可以用这种方式重写你的循环

    with torch.no_grad(): 
        w.sub_(learning_rate*w.grad)
        b.sub_(learning_rate*b.grad)
    

    不会触及requires_grad 标志,因为张量保持其“身份” - 只需更改值。在这种情况下,您需要记住在每次迭代中调用w.zero_grad()b.zero_grad(),否则梯度值将保持累加增长。

    【讨论】:

    • 太棒了!非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    • 2022-07-27
    • 1970-01-01
    • 1970-01-01
    • 2021-01-18
    • 2020-10-05
    • 1970-01-01
    相关资源
    最近更新 更多