我有一个a
具有三个维度的张量。第一个维度对应 minibatch 大小,第二个维度对应序列长度,第三个维度对应特征维度。例如,
>>> a = torch.arange(1, 13, dtype=torch.float).view(2,2,3) # Consider the values of a to be random
>>> a
tensor([[[ 1., 2., 3.],
[ 4., 5., 6.]],
[[ 7., 8., 9.],
[10., 11., 12.]]])
Run Code Online (Sandbox Code Playgroud)
我有第二个二维张量。它的第一维对应于小批量大小,第二维对应于序列长度。它包含 的第三维索引范围内的值a
。a
s 第三维的大小为 3,因此b
可以包含值 0、1 或 2。例如,
>>> b = torch.LongTensor([[0, 2],[1,0]])
>>> b
tensor([[0, 2],
[1, 0]])
Run Code Online (Sandbox Code Playgroud)
我想获得一个张量c
,其形状为b
并包含a
由 引用的所有值b
。在上面的场景中,我想要:
c = torch.empty(2,2)
c[0,0] = a[0, 0, b[0,0]]
c[1,0] = a[1, 0, b[1,0]]
c[0,1] = a[0, 1, b[0,1]]
c[1,1] = a[1, 1, b[1,1]]
>>> c
tensor([[ 1., 5.],
[ 8., 10.]])
Run Code Online (Sandbox Code Playgroud)
如何c
快速创建张量?此外,我还希望 c 是可微的(能够使用.backprob()
)。我对 pytorch 不太熟悉,所以我不确定是否存在可区分的版本。
作为替代方案,除了c
具有与b
我相同的形状之外,还可以使用c
具有相同形状的a
,只有零,但在由b
1引用的位置。然后,我可以繁殖a
并c
获得微张量。
像下面这样:
c = torch.zeros(2,2,3, dtype=torch.float)
c[0,0,b[0,0]] = 1
c[1,0,b[1,0]] = 1
c[0,1,b[0,1]] = 1
c[1,1,b[1,1]] = 1
>>> a*c
tensor([[[ 1., 0., 0.],
[ 0., 5., 0.]],
[[ 0., 8., 0.],
[10., 0., 0.]]])
Run Code Online (Sandbox Code Playgroud)
让我们先声明必要的变量:(注意requires_grad
在a
的初始化中,我们将使用它来确保可微性)
a = torch.arange(1,13,dtype=torch.float32,requires_grad=True).reshape(2,2,3)
b = torch.LongTensor([[0, 2],[1,0]])
Run Code Online (Sandbox Code Playgroud)
让我们重塑a
并压缩小批量和序列维度:
temp = a.reshape(-1,3)
Run Code Online (Sandbox Code Playgroud)
所以temp
现在看起来像:
tensor([[ 1., 2., 3.],
[ 4., 5., 6.],
[ 7., 8., 9.],
[10., 11., 12.]], grad_fn=<AsStridedBackward>)
Run Code Online (Sandbox Code Playgroud)
b
请注意,现在可以在 的每一行中使用 的每个值temp
来获得所需的输出。现在我们做:
c = temp[range(len(temp )),b.view(-1)].view(b.size())
Run Code Online (Sandbox Code Playgroud)
请注意我们如何索引temp
,range(len(temp ))
来选择每一行和 1D b
ieb.view(-1)
来获取相应的列。最后.view(b.size())
使该数组的大小与 相同b
。
c
如果我们现在打印:
tensor([[ 1., 6.],
[ 8., 10.]], grad_fn=<ViewBackward>)
Run Code Online (Sandbox Code Playgroud)
的存在grad_fn=..
表明c
需要梯度,即它是可微的。
归档时间: |
|
查看次数: |
2247 次 |
最近记录: |