我在PyTorch中有两个张量,z
是一个形状为(n_samples, n_features, n_views)
的3d张量,其中n_samples
是数据集中的样本数,n_features
是每个样本的特征数,n_views
是描述相同(n_samples, n_features)
特征矩阵但具有其他值的不同视图数
我还有另一个2d张量b
,形状为(n_samples, n_views)
,其目的是在不同视图中重新缩放样本的所有特征。换句话说,它封装了同一示例中每个视图的特征的重要性。
例如:
import torch
z = torch.Tensor(([[2,3], [1,1], [4,5]],
[[2,2], [1,2], [7,7]],
[[2,3], [1,1], [4,5]],
[[2,3], [1,1], [4,5]]))
b = torch.Tensor(([1, 0],
[0, 1],
[0.2, 0.8],
[0.5, 0.5]))
print(z.shape, b.shape)
>>>torch.Size([4, 3, 2]) torch.Size([4, 2])
我想通过z
和b
之间的运算得到第三个r
形的张量(n_samples, n_features)
。
一种可能的解决办法是:
b = b.unsqueeze(1)
r = z * b
r = torch.sum(r, dim=-1)
print(r, r.shape)
>>>tensor([[2.0000, 1.0000, 4.0000],
[2.0000, 2.0000, 7.0000],
[2.8000, 1.0000, 4.8000],
[2.5000, 1.0000, 4.5000]]) torch.Size([4, 3])
使用torch.matmul()
是否可能达到同样的结果?。我已经尝试了很多次来排列两个向量的维数,但都没有用
是的,那是可能的。如果两个运算符中都有多个批次维度,则可以使用广播。在这种情况下,每个操作数的最后两个维度被解释为矩阵大小。(我建议在documentation中查找。)
因此,您需要为向量
b
增加一个维度,使其成为n x 1
“矩阵”(列向量):或者,^{} 也使这一点非常简单
einsum
是一个非常强大的操作,可以做很多事情:你可以排列张量维度,沿着它们求和,或者执行标量积,不管有没有广播。它来源于物理学中常用的Einstein summation convention。粗略的想法是给歌剧的每个维度命名,然后使用这些名称定义输出应该是什么样子。我认为最好读一下documentation。在我们的例子中,我们有一个4 x 3 x 2
张量和一个4 x 2
张量。所以让我们称第一张量的维数为ijk
。这里i
和k
应该被视为与第二张量的维数相同,因此这一张量可以被描述为ik
。最后,输出应该是ij
(它应该是4 x 3
张量)。从这个“签名”ijk, ik -> ij
可以清楚地看出,维度i
被保留,维度k
必须“求和/相乘”(标量积)相关问题 更多 >
编程相关推荐