Pytorch 遇到运行时错误:梯度计算所需的变量之一已被就地操作修改

Pytorch 遇到运行时错误:梯度计算所需的变量之一已被就地操作修改,pytorch,backpropagation,autograd,Pytorch,Backpropagation,Autograd,调用.backward()时出现以下错误: 遇到运行时错误:梯度计算所需的变量之一已被就地操作修改 A = tensor([[[0, 0, 0, 0, 0],

调用.backward()时出现以下错误:

遇到运行时错误:梯度计算所需的变量之一已被就地操作修改

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]]])
代码如下:

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]]])
为了实现这一点,我们可以使用函数,该函数允许我们添加到索引列表中。由于它只支持一维运算,我们首先需要将
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)

什么是
X
Y
Z
?它们是数字列表还是张量列表?它们是涉及参数的运算的结果吗?X和Y是叶张量。Z是前一层的非叶张量。很好,在X,Y中有重复的指数吗?(例如,这对(1,1)是否出现了两次或更多次?)是的,这就是我需要总结它们的原因。例:(3,9,0.5),(3,9,0.4)应导致(3,9,0.9)A.形状([32,300,300])、X.形状、Y.形状([32,200])和Z.形状([32,200,1])。谢谢!事实上,这对不是唯一的,这就是为什么我需要总结它们。例:(3,9,0.5),(3,9,0.4)应该得到(3,9,0.9)@natasha_667我用一个解决方案更新了答案,该解决方案也适用于非唯一情况。谢谢!我在这里试过了,但在尺寸方面有个错误。我会真诚的,我还不明白你的解决方案!以下是实际尺寸:A.shape:([32300300])、X.shape、Y.shape:([32200])和Z.shape:([32200,1])。我知道了,我担心X和Y上可能有批量尺寸。我需要再次更新此尺寸。第三次有魅力@娜塔莎:我已经更新了答案,如果这回答了你的问题,请告诉我