【问题标题】:How to assign a new value to a pytorch Variable without breaking backpropagation?如何在不破坏反向传播的情况下为 pytorch 变量分配新值?
【发布时间】:2018-12-17 16:34:41
【问题描述】:

我有一个 pytorch 变量,用作模型的可训练输入。在某些时候,我需要手动重新分配此变量中的所有值。

如何在不中断与损失函数的连接的情况下做到这一点?

假设当前值为[1.2, 3.2, 43.2],我只是希望它们变为[1,2,3]


编辑

在我问这个问题的时候,我还没有意识到 PyTorch 没有 Tensorflow 或 Keras 那样的静态图。

在 PyTorch 中,训练循环是手动进行的,您需要在每个训练步骤中调用所有内容。 (没有占位符 + 静态图的概念供以后提供数据)。

因此,我们不能“破坏图形”,因为我们将使用新变量再次执行所有进一步的计算。我担心发生在 Keras 而不是 PyTorch 中的问题。

【问题讨论】:

  • “不中断连接”是什么意思?一般来说,网络的输入无论如何都有requires_grad=False,因此不会反向传播。
  • 这个是require_grad=True(故意)。假设我想改变一个层的权重。
  • 那么是输入还是层权重?只是分配一个不同的张量来代替旧的张量吗?只要计算图(反向传播)需要,旧的就会保留
  • 分配不同的张量不是一种选择(除非我不明白这意味着什么)。我想重新分配 var 的值,使其保持在同一个图中。

标签: pytorch


【解决方案1】:

您可以使用张量的data 属性来修改值,因为对data 的修改不会影响图形。
因此,图形仍然是完整的,data 属性本身的修改对图形没有影响。 (data 上的操作和更改不会被 autograd 跟踪,因此不会出现在图中)

由于您没有给出示例,因此此示例基于您的评论声明:
'假设我想更改图层的权重。'
我在这里使用了普通张量,但这对于层的 weight.databias.data 属性同样适用。

这是一个简短的例子:

import torch
import torch.nn.functional as F



# Test 1, random vector with CE
w1 = torch.rand(1, 3, requires_grad=True)
loss = F.cross_entropy(w1, torch.tensor([1]))
loss.backward()
print('w1.data', w1)
print('w1.grad', w1.grad)
print()

# Test 2, replacing values of w2 with w1, before CE
# to make sure that everything is exactly like in Test 1 after replacing the values
w2 = torch.zeros(1, 3, requires_grad=True)
w2.data = w1.data
loss = F.cross_entropy(w2, torch.tensor([1]))
loss.backward()
print('w2.data', w2)
print('w2.grad', w2.grad)
print()

# Test 3, replace data after computation
w3 = torch.rand(1, 3, requires_grad=True)
loss = F.cross_entropy(w3, torch.tensor([1]))
# setting values
# the graph of the previous computation is still intact as you can in the below print-outs
w3.data = w1.data
loss.backward()

# data were replaced with values from w1
print('w3.data', w3)
# gradient still shows results from computation with w3
print('w3.grad', w3.grad)

输出:

w1.data tensor([[ 0.9367,  0.6669,  0.3106]])
w1.grad tensor([[ 0.4351, -0.6678,  0.2326]])

w2.data tensor([[ 0.9367,  0.6669,  0.3106]])
w2.grad tensor([[ 0.4351, -0.6678,  0.2326]])

w3.data tensor([[ 0.9367,  0.6669,  0.3106]])
w3.grad tensor([[ 0.3179, -0.7114,  0.3935]])

这里最有趣的部分是w3。在调用backward 时,这些值将替换为w1 的值。
但梯度是基于 CE 函数计算的,其值为原始w3。替换的值对图表没有影响。 所以图连接没有断开,替换对图有没有影响。我希望这就是你要找的东西!

【讨论】:

  • 不是真的......这与图表“断开”,它没有用,因为新数据不会被训练。我想“在图表中”更改数据,并让所有内容都像以前一样可以使用新值进行训练。示例:如果权重不参与图表,我为什么要更改层的权重?更改权重的唯一原因是它们取代了旧的权重。
  • @DanielMöller 感谢您的反馈!您如何得出新数据不会被训练的结论?只有更换权重的过程没有记录在图表中,没有任何东西是断开的。但是,替换后的权重应该被视为从一开始就存在以供将来计算。但我想我并没有真正理解你在寻找什么。您能否为您的问题添加一个具有预期结果的小示例?
  • 您明显更改了 w3 的数据,但通过查看其梯度,它并没有在图表中生效。
  • 嗯...如果我想让新数据生效,我必须重建图表。我认为这是 pytorch 工作的唯一方式?
  • 是的,实际上并没有直接与图形本身交互的方法。
猜你喜欢
  • 1970-01-01
  • 2011-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-26
  • 1970-01-01
  • 2011-08-19
  • 1970-01-01
相关资源
最近更新 更多