实际上,我很惊讶下面的代码可以运行。虽然我没有测试过,但我相信在版本
0.3.1
中,该代码会引发错误。基本上,我想要做的是将张量向量的某个位置设置为特定值,就像这样:
my_tensor[i] = 42
范例代码:
# test parameter a
a = torch.rand((2), requires_grad=True)
print('a ', a)
b = torch.rand(2)
# calculation
c = a + b
# performing in-place operation
c[0] = 0
print('c ', c)
s = torch.sum(c)
print('s ', s)
# calling backward()
s.backward()
# optimizer step
optim = torch.optim.Adam(params=[a], lr=0.5)
optim.step()
# changed parameter a
print('changed a', a)
输出:
a tensor([0.2441, 0.2589], requires_grad=True)
c tensor([0.0000, 1.1511], grad_fn=<CopySlices>)
s tensor(1.1511, grad_fn=<SumBackward0>)
changed a tensor([ 0.2441, -0.2411], requires_grad=True)
很明显,在版本 0.4.1
中,这个操作可以正常执行而不会出现警告或错误。
这是关于自动微分的文档中的文章:autograd-mechanics
在自动微分中支持原地操作是一个很困难的问题,因此我们大多数情况下不鼓励使用它们。Autograd 的积极缓存释放和重用使其非常高效,并且实际上很少有需要通过原地操作来降低内存使用的情况。除非你正在承受巨大的内存压力,否则可能永远不需要使用它们。
但即使它可以工作,在大多数情况下建议不要使用原地操作。
所以我的问题是:
使用原地操作会对性能产生多大影响?
在想要将张量的一个元素设置为特定值的情况下,如何避免使用原地操作?
谢谢!