【问题标题】:Pytorch gradients has not calculatedPytorch 梯度尚未计算
【发布时间】:2019-08-20 01:01:21
【问题描述】:

我创建了一个 NN。我在重新计算渐变时遇到问题。问题是我将 2 个张量 u @ v 标量相乘并将其中一个归一化。重要的是不能计算 h 的梯度。因此,我使用detach()。另外,在重新计算梯度的过程中,不应该考虑归一化(我不知道怎么做)。

import torch
from torch import nn


class Nn(nn.Module):
    def __init__(self):
        super(Nn, self).__init__()
        self.ln = nn.Linear(5, 5)

    def forward(self, x):
        v = self.ln(x)

        u = v.clone()
        h = v.clone()

        u /= u.norm()
        h = h.detach()
        h /= h.norm()

        res = torch.stack([torch.stack([u @ h, u @ h])])

        return res


def patches_generator():
    while True:
        decoder = torch.rand((5, ))
        target = torch.randint(2, (1,))
        yield decoder, target


net = Nn()

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters())

net.train()
torch.autograd.set_detect_anomaly(True)
for decoder, targets in patches_generator():
    optimizer.zero_grad()
    outputs = net(decoder)
    loss = criterion(outputs, targets)
    loss.backward()
    optimizer.step()

因此,我收到以下错误:

RuntimeError:梯度计算所需的变量之一有 已被就地操作修改:[torch.FloatTensor [9, 512, 1, 1]],即ReluBackward1的输出0,在版本3;预期的 版本 2 代替。提示:上面的回溯显示了 未能计算其梯度的操作。中的变量 问题在那里或以后的任何地方都被改变了。祝你好运!

【问题讨论】:

  • 这是整个代码吗?我没有看到错误引用的 Relu 层。
  • 这段代码有问题。我减少了它们
  • ReluBackward1 来自哪里?
  • nvm,这不相关,您可能只是从原始代码中复制了错误消息

标签: python pytorch


【解决方案1】:

问题是在这一行中应用于u 的就地除法运算符:

u /= u.norm()

改成

u = u / u.norm()

使代码运行。原因是就地操作符覆盖了这一行的中间结果

u = v.clone()

这使得 Pytorch 无法计算梯度。

(问题中的错误消息包含对ReluBackward1 层的引用,该层不在简化代码示例中。Pytorch ReLU 层有一个可选的in_place 参数,它在支持反向传播的同时使操作到位。这个通常有效,因为在顺序网络中,不需要区分 ReLU 激活的输出和权重的输出来计算梯度,但在更复杂的架构中,可能需要保留权重的输出。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-12
    • 1970-01-01
    • 2021-09-11
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多