【问题标题】:Why doesn't pytorch allow inplace operations on leaf variables?为什么 pytorch 不允许对叶变量进行就地操作?
【发布时间】:2022-01-19 14:50:06
【问题描述】:

所以如果我在 Pytorch 中运行这段代码:

x = torch.ones(2,2, requires_grad=True)
x.add_(1)

我会得到错误:

RuntimeError: 一个需要 grad 的叶变量正在就地操作中使用。

我知道 Pytorch 不允许对叶变量进行就地操作,而且我也知道有办法绕过这个限制。我不明白的是这条规则背后的哲学。为什么使用就地操作更改叶变量是错误的?

【问题讨论】:

    标签: python pytorch


    【解决方案1】:

    据我了解,每当您对使用 requires_grad=True 初始化的张量执行非传统操作时,Pytorch 都会抛出错误以确保它是故意的。例如,您通常只会使用 optimizer.step() 更新权重张量。

    再举一个例子,我在网络初始化期间尝试更新可反向传播的张量中的值时遇到了这个问题。

    self.weight_layer = nn.Parameter(data=torch.zeros(seq_length), requires_grad=True)
    self.weight_layer[true_ids == 1] = -1.2
    
    RuntimeError: a leaf Variable that requires grad is being used in an in-place operation.
    

    问题在于,因为requires_grad=True,网络不知道我仍在初始化这些值。如果这是您想要做的,将更新包装在 torch.no_grad 块中是一种解决方案:

    with torch.no_grad()
        self.weight_layer = nn.Parameter(data=torch.zeros(seq_length), requires_grad=True)
        self.weight_layer[true_ids == 1] = -1.2
    

    否则,您可以在完成初始化张量后设置requires_grad=True

    self.weight_layer = nn.Parameter(data=torch.zeros(seq_length))
    self.weight_layer[true_ids == 1] = -1.2
    self.weight_layer.requires_grad = True
    

    【讨论】:

    • 如果你用torch.no_grad()修改self.weight_layer[...]里面,会不会把“requires_grad=False”设置为self.weight_layer?
    • 不。 torch.no_grad() 的工作方式是,nn.Parameter 上的 requires_grad 属性永远不会被修改 - 即使在 torch.no_grad() 上下文中也是如此。
    【解决方案2】:

    对此的简单回答是,一旦 autograd 创建了图形,并且我们创建了作为图形输入的张量,autograd 将构建并跟踪您创建的张量上的每个操作。现在,由于这个张量有requires_grad=True,假设我在loss.backward() 之后进行了权重更新,autograd 可能正在考虑作为已经创建的图形的一部分,这需要渐变。这导致RuntimeError: a leaf Variable that requires grad is being used in an in-place operation. Autograd 很困惑,为什么作为计算图一部分的张量被用于外部/被用于其他一些操作/就地初始化它,这是一个问题

    如果我们简单地将代码放在 with torch.no_grad(): code here 我们禁用了梯度,因此本质上它向 autograd 发出信号,表明此操作不是我们动态图更新的一部分。

    PS:我将通过在 Medium 上写一篇博客来扩展这个答案

    【讨论】:

      猜你喜欢
      • 2019-01-19
      • 2018-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-13
      • 2011-08-18
      • 1970-01-01
      • 2020-11-22
      相关资源
      最近更新 更多