Encounter the RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation
Encounter the RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation
调用 .backward() 时出现以下错误:
遇到运行时错误:梯度计算所需的变量之一已被原地操作修改
代码如下:
for i, j, k in zip(X, Y, Z):
A[:, i, j] = A[:, i, j] + k
我试过 .clone()、torch.add() 等。
请帮忙!
评论后我对你想要完成的事情有点困惑。使用您在评论中提供的尺寸,您提供的代码给我一个错误
Traceback (most recent call last):
A[:, i, j] = A[:, i, j] + k
RuntimeError: The size of tensor a (32) must match the size of tensor b (200) at non-singleton dimension 0
但这就是我认为你想要做的,如果有错请在评论中纠正我...
给定张量X
、Y
和Z
,X
、Y
和Z
的每个条目对应一个坐标 (x,y) 和值 z。您想要的是在坐标 (x,y) 处将 z 添加到 A
。在大多数情况下,批处理维度保持独立,但不清楚您发布的代码中的情况。现在这就是我假设你想要做的。
例如,假设 A
包含全零且形状为 3x4x5,而 X
、Y
的形状为 3x3,而 Z
的形状为 3x3x1。对于此示例,我们假设 A
包含所有开始的零,并且 X
、Y
和 Z
具有以下值
X = tensor([[1, 2, 3],
[1, 2, 3],
[2, 2, 2]])
Y = tensor([[1, 2, 3],
[1, 2, 3],
[1, 1, 1]])
Z = tensor([[[0.1], [0.2], [0.3]],
[[0.4], [0.5], [0.6]],
[[0.7], [0.8], [0.9]]])
那么我们期望A
在操作后具有以下值
A = tensor([[[0, 0, 0, 0, 0],
[0, 0.1, 0, 0, 0],
[0, 0, 0.2, 0, 0],
[0, 0, 0, 0.3, 0]],
[[0, 0, 0, 0, 0],
[0, 0.4, 0, 0, 0],
[0, 0, 0.5, 0, 0],
[0, 0, 0, 0.6, 0]],
[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 2.4, 0, 0, 0],
[0, 0, 0, 0, 0]]])
为了实现这一点,我们可以使用 index_add
函数,它允许我们添加到索引列表中。由于这仅支持一维运算,我们首先需要将 X
、Y
转换为扁平张量 A
的线性索引。之后我们可以取消展平到原来的形状。
layer_size = A.shape[1] * A.shape[2]
index_offset = torch.arange(0, A.shape[0] * layer_size, layer_size).unsqueeze(1)
indices = (X * A.shape[2] + Y) + index_offset
A = A.view(-1).index_add(0, indices.view(-1), Z.view(-1)).view(A.shape)
调用 .backward() 时出现以下错误:
遇到运行时错误:梯度计算所需的变量之一已被原地操作修改
代码如下:
for i, j, k in zip(X, Y, Z):
A[:, i, j] = A[:, i, j] + k
我试过 .clone()、torch.add() 等。
请帮忙!
评论后我对你想要完成的事情有点困惑。使用您在评论中提供的尺寸,您提供的代码给我一个错误
Traceback (most recent call last):
A[:, i, j] = A[:, i, j] + k
RuntimeError: The size of tensor a (32) must match the size of tensor b (200) at non-singleton dimension 0
但这就是我认为你想要做的,如果有错请在评论中纠正我...
给定张量X
、Y
和Z
,X
、Y
和Z
的每个条目对应一个坐标 (x,y) 和值 z。您想要的是在坐标 (x,y) 处将 z 添加到 A
。在大多数情况下,批处理维度保持独立,但不清楚您发布的代码中的情况。现在这就是我假设你想要做的。
例如,假设 A
包含全零且形状为 3x4x5,而 X
、Y
的形状为 3x3,而 Z
的形状为 3x3x1。对于此示例,我们假设 A
包含所有开始的零,并且 X
、Y
和 Z
具有以下值
X = tensor([[1, 2, 3],
[1, 2, 3],
[2, 2, 2]])
Y = tensor([[1, 2, 3],
[1, 2, 3],
[1, 1, 1]])
Z = tensor([[[0.1], [0.2], [0.3]],
[[0.4], [0.5], [0.6]],
[[0.7], [0.8], [0.9]]])
那么我们期望A
在操作后具有以下值
A = tensor([[[0, 0, 0, 0, 0],
[0, 0.1, 0, 0, 0],
[0, 0, 0.2, 0, 0],
[0, 0, 0, 0.3, 0]],
[[0, 0, 0, 0, 0],
[0, 0.4, 0, 0, 0],
[0, 0, 0.5, 0, 0],
[0, 0, 0, 0.6, 0]],
[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 2.4, 0, 0, 0],
[0, 0, 0, 0, 0]]])
为了实现这一点,我们可以使用 index_add
函数,它允许我们添加到索引列表中。由于这仅支持一维运算,我们首先需要将 X
、Y
转换为扁平张量 A
的线性索引。之后我们可以取消展平到原来的形状。
layer_size = A.shape[1] * A.shape[2]
index_offset = torch.arange(0, A.shape[0] * layer_size, layer_size).unsqueeze(1)
indices = (X * A.shape[2] + Y) + index_offset
A = A.view(-1).index_add(0, indices.view(-1), Z.view(-1)).view(A.shape)