问题描述
我有一个矩阵,其形状为(TxK
和K << T
)。我想将其扩展为形状TxT
,并用i
步右移第i
行。
例如:
inputs: T= 5,and K = 3
1 2 3
1 2 3
1 2 3
1 2 3
1 2 3
expected outputs:
1 2 3 0 0
0 1 2 3 0
0 0 1 2 3
0 0 0 1 2
0 0 0 0 1
我的解决方案:
right_pad = T - K + 1
output = F.pad(input,(0,right_pad),'constant',value=0)
output = output.view(-1)[:-T].view(T,T)
我的解决方案将导致错误-gradient computation has been modified by an in-place operation
。有没有一种有效可行的方法来实现我的目标?
解决方法
您可以使用PyTorch逐列进行操作。
# input is a T * K tensor
input = torch.ones((T,K))
index = torch.tensor(np.linspace(0,T - 1,num=T,dtype=np.int64))
output = torch.zeros((T,T))
output[index,index] = input[:,0]
for k in range(1,K):
output[index[:-k],index[:-k] + k] = input[:-k,k]
print(output)
,
您的功能很好,也不是导致错误的原因(使用PyTorch 1.6.0
,如果您使用的是其他版本,请更新依赖项。
下面的代码可以正常工作:
import torch
import torch.nn as nn
import torch.nn.functional as F
T = 5
K = 3
inputs = torch.tensor(
[[1,2,3,],[1,requires_grad=True,dtype=torch.float,)
right_pad = T - K + 1
output = F.pad(inputs,(0,right_pad),"constant",value=0)
output = output.flatten()[:-T].reshape(T,T)
output.sum().backward()
print(inputs.grad)
请注意,由于您无法dtype
整数,我已将torch.float
明确指定为backprop
。
view
和slice
将永远不会中断反向传播,因为gradient
连接到单个值,无论它是否被视为{{1} }或未压缩的1D
等。这些未就地修改。就地修改破坏梯度可能是:
2D
此外,您的解决方案返回以下内容:
output[0,3] = 15.
因此您在左下角有一个tensor([[1.,2.,3.,0.,0.],[0.,1.,3.],2.],[3.,1.]],grad_fn=<ViewBackward>)
。如果这不是您所期望的,则应在3
之后添加以下行(与1
乘以上三角矩阵):
output = output.flatten()[:-T].reshape(T,T)
给出:
output *= torch.triu(torch.ones_like(output))
还有tensor([[1.,grad_fn=<AsStridedBackward>)
:
inputs.grad