pytorch中的多维张量点积
Multi-dimensional tensor dot product in pytorch
我有两个形状为 (8, 1, 128) 的张量,如下所示。
q_s.shape
Out[161]: torch.Size([8, 1, 128])
p_s.shape
Out[162]: torch.Size([8, 1, 128])
以上两个张量表示一批八个 128 维向量。我想要批次 q_s
与批次 p_s
的点积。我怎样才能做到这一点?我尝试使用 torch.tensordot
函数如下。它也按预期工作。但它也做了额外的工作,这是我不希望它做的。请参见以下示例。
dt = torch.tensordot(q_s, p_s, dims=([1,2], [1,2]))
dt
Out[176]:
tensor([[0.9051, 0.9156, 0.7834, 0.8726, 0.8581, 0.7858, 0.7881, 0.8063],
[1.0235, 1.5533, 1.2155, 1.2048, 1.3963, 1.1310, 1.1724, 1.0639],
[0.8762, 1.3490, 1.2923, 1.0926, 1.4703, 0.9566, 0.9658, 0.8558],
[0.8136, 1.0611, 0.9131, 1.1636, 1.0969, 0.9443, 0.9587, 0.8521],
[0.6104, 0.9369, 0.9576, 0.8773, 1.3042, 0.7900, 0.8378, 0.6136],
[0.8623, 0.9678, 0.8163, 0.9727, 1.1161, 1.6464, 0.9765, 0.7441],
[0.6911, 0.8392, 0.6931, 0.7325, 0.8239, 0.7757, 1.0456, 0.6657],
[0.8493, 0.8174, 0.8041, 0.9013, 0.8003, 0.7451, 0.7408, 1.1771]],
grad_fn=<AsStridedBackward>)
dt.shape
Out[177]: torch.Size([8, 8])
正如我们所见,这会生成大小为 (8,8) 的张量,其中我想要的点积位于对角线上。是否有任何不同的方法来获得更小的所需形状张量 (8,1),它只包含位于上述结果对角线上的元素。 更清楚地说,位于对角线上的元素是我们想要的正确要求的点积,作为两个批次的点积。索引 [0][0] 处的元素是 q_s[0] 和 p_s[0] 的点积。索引 [1][1] 处的元素是 q_s[1] 和 p_s[1] 的点积,依此类推。
有没有更好的方法在pytorch中得到想要的点积?
你可以直接做:
a = torch.rand(8, 1, 128)
b = torch.rand(8, 1, 128)
torch.sum(a * b, dim=(1, 2))
# tensor([29.6896, 30.4994, 32.9577, 30.2220, 33.9913, 35.1095, 32.3631, 30.9153])
torch.diag(torch.tensordot(a, b, dim=([1,2], [1,2])))
# tensor([29.6896, 30.4994, 32.9577, 30.2220, 33.9913, 35.1095, 32.3631, 30.9153])
如果你在总和中设置 axis=2
你将得到一个形状为 (8, 1)
的张量。
我有两个形状为 (8, 1, 128) 的张量,如下所示。
q_s.shape
Out[161]: torch.Size([8, 1, 128])
p_s.shape
Out[162]: torch.Size([8, 1, 128])
以上两个张量表示一批八个 128 维向量。我想要批次 q_s
与批次 p_s
的点积。我怎样才能做到这一点?我尝试使用 torch.tensordot
函数如下。它也按预期工作。但它也做了额外的工作,这是我不希望它做的。请参见以下示例。
dt = torch.tensordot(q_s, p_s, dims=([1,2], [1,2]))
dt
Out[176]:
tensor([[0.9051, 0.9156, 0.7834, 0.8726, 0.8581, 0.7858, 0.7881, 0.8063],
[1.0235, 1.5533, 1.2155, 1.2048, 1.3963, 1.1310, 1.1724, 1.0639],
[0.8762, 1.3490, 1.2923, 1.0926, 1.4703, 0.9566, 0.9658, 0.8558],
[0.8136, 1.0611, 0.9131, 1.1636, 1.0969, 0.9443, 0.9587, 0.8521],
[0.6104, 0.9369, 0.9576, 0.8773, 1.3042, 0.7900, 0.8378, 0.6136],
[0.8623, 0.9678, 0.8163, 0.9727, 1.1161, 1.6464, 0.9765, 0.7441],
[0.6911, 0.8392, 0.6931, 0.7325, 0.8239, 0.7757, 1.0456, 0.6657],
[0.8493, 0.8174, 0.8041, 0.9013, 0.8003, 0.7451, 0.7408, 1.1771]],
grad_fn=<AsStridedBackward>)
dt.shape
Out[177]: torch.Size([8, 8])
正如我们所见,这会生成大小为 (8,8) 的张量,其中我想要的点积位于对角线上。是否有任何不同的方法来获得更小的所需形状张量 (8,1),它只包含位于上述结果对角线上的元素。 更清楚地说,位于对角线上的元素是我们想要的正确要求的点积,作为两个批次的点积。索引 [0][0] 处的元素是 q_s[0] 和 p_s[0] 的点积。索引 [1][1] 处的元素是 q_s[1] 和 p_s[1] 的点积,依此类推。
有没有更好的方法在pytorch中得到想要的点积?
你可以直接做:
a = torch.rand(8, 1, 128)
b = torch.rand(8, 1, 128)
torch.sum(a * b, dim=(1, 2))
# tensor([29.6896, 30.4994, 32.9577, 30.2220, 33.9913, 35.1095, 32.3631, 30.9153])
torch.diag(torch.tensordot(a, b, dim=([1,2], [1,2])))
# tensor([29.6896, 30.4994, 32.9577, 30.2220, 33.9913, 35.1095, 32.3631, 30.9153])
如果你在总和中设置 axis=2
你将得到一个形状为 (8, 1)
的张量。