pytorch einsum, numpy einsum

什么是einsum?

爱因斯坦求和约定:

https://zhuanlan.zhihu.com/p/101157166
https://en.wikipedia.org/wiki/Einstein_notation

为什么用?

简洁, 强大

具体例子

pytorch和numpy一样的,这里以pytorch为例.

矩阵乘矩阵, C = A x B

eg1. (ij, jk -> ik), 实际上就是

[ C ] i k = ∑ j [ A ] i j × [ B ] j k [C]_{ik} = \sum_{j} [A]_{ij} \times [B]_{jk} [C]ik=j[A]ij×[B]jk

>>> A = torch.Tensor([[1,1],[2,2]])
>>> B = torch.Tensor([[1,-1],[-1,1]])
>>> torch.einsum("ij, jk -> ik", A, B)
tensor([[0., 0.],
        [0., 0.]])

eg2. (mij, jk -> mik), 相当于在eg1中的m个A分别乘以B,得到m个相应的C

>>> mA = torch.stack([a, a+1, a+2], dim=0)
>>> mA
tensor([[[1., 1.],
         [2., 2.]],

        [[2., 2.],
         [3., 3.]],

        [[3., 3.],
         [4., 4.]]])
>>> mA.shape
torch.Size([3, 2, 2])
>>> B = torch.Tensor([[1,1],[1,1]])
>>> torch.einsum("mij, jk -> mik", mA, B)
tensor([[[2., 2.],
         [4., 4.]],

        [[4., 4.],
         [6., 6.]],

        [[6., 6.],
         [8., 8.]]])

矩阵乘向量

eg3. (mij, j -> mi).

>>> b = torch.Tensor([1,-1])
>>> torch.einsum("mij, j -> mi", mA, b)
tensor([[0., 0.],
        [0., 0.],
        [0., 0.]])

eg4. (bnf, n -> bf).

相当于对n个f维向量加权求和.

>>> 
a = torch.arange(12).reshape(3,2,2).float()
print(a)
weighted = 2 * torch.ones(2)
print(weighted)
b = torch.einsum('bnf, n -> bf', a, weighted)
print(b)
print(b.shape)
>>>
output:
tensor([[[ 0.,  1.],
         [ 2.,  3.]],

        [[ 4.,  5.],
         [ 6.,  7.]],

        [[ 8.,  9.],
         [10., 11.]]])
tensor([2., 2.])
tensor([[ 4.,  8.],
        [20., 24.],
        [36., 40.]])
torch.Size([3, 2])

高维Tensor乘法

eg5. (bnft, knm -> bkmft).

看起来有点复杂,其实很简单:
bnft相当于b个mA, knm 相当于k个B,那么bkmft,相当于b个mA分别乘以k个B。

但是你会发现,mA是三维的(nft),B是二维的(nm),这其实等同于eg2。

观察最后的结果(bkmft)里,bk就是b个mA乘以k个B,所以一共有b*k个tensor运算结果,存到了b维和k维。

剩下的mft = nft *nm,实际上要让这个等式成立,必须要变成mft = mn * nft, 即nm转置为mn,然后 分别乘以t个nf,即,t个矩阵乘法: m n × n f = m f mn \times nf = mf mn×nf=mf

>>> mA.shape
torch.Size([3, 2, 2])
>>> bmA = torch.stack([mA,-mA], dim=0)
>>> bmA.shape
torch.Size([2, 3, 2, 2])
>>> B = torch.Tensor([[1,1],[1,-1]])
>>> kB = torch.stack([B,B,B],dim=1)
>>> kB.shape
torch.Size([2, 3, 2])
>>> torch.einsum("bnft, lnm -> blmft", bmA, lB).shape
torch.Size([2, 2, 2, 2, 2])
>>> torch.mm(kB[1].transpose(0,1), bmA[0,:,:,0])
tensor([[ 6.,  9.],
        [-6., -9.]])
>>> torch.einsum("bnft, knm -> bkmft", bmA, kB)[0,1,:,:,0]
tensor([[ 6.,  9.],
        [-6., -9.]])

从最后两个code可以看到,用kB中的第二个(index=1)B,进行转置后,乘以第一个mA中的第一个nf,即(t这个维度取第一个,index=0)的结果,等同于einsum结果中对应位置的矩阵(即b=0,k=1,t=0)。

eg6. (bkmft, k -> bmft). 高维Tensor乘以向量。

相当于对左边的 b ∗ k b*k bk m f t mft mft 进行了一个加权求和(权重会乘以每一个元素),权重就是右边的k维向量。

>>> C = torch.einsum("bnft, knm -> bkmft", bmA, kB)
>>> b = torch.Tensor([1, 2]) # 权重第一个mft就是1,第二个mft就是2.
>>> torch.einsum("bkmft, k -> bmft", C, b)
tensor([[[[ 18.,  18.],
          [ 27.,  27.]],

         [[ -6.,  -6.],
          [ -9.,  -9.]]],


        [[[-18., -18.],
          [-27., -27.]],

         [[  6.,   6.],
          [  9.,   9.]]]])
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
PyTorch中的`torch.einsum`函数是一个用于执行张量运算的强大工具。它可以根据指定的公式对输入张量进行操作,并生成输出张量。 引用\[1\]中提供了一些常见的用法示例。例如,可以使用`torch.einsum`计算矩阵的行和、列和以及某个维度的和。例如,可以使用`torch.einsum('ij->i', A)`计算矩阵A的行和,使用`torch.einsum('ij->j', A)`计算矩阵A的列和,使用`torch.einsum('ijklmn->n', D)`计算张量D在某个维度上的和。 引用\[2\]中提供了一些更复杂的用法示例。例如,可以使用`torch.einsum('ij,jk->ik', A, B)`计算矩阵A和B的内积,使用`torch.einsum('ij,ik->jk', A, C)`计算矩阵A和C的外积,使用`torch.einsum('ij,jk,lj->jk', A, B, C)`进行多维张量相乘。 引用\[3\]中提供了一个高阶张量运算的示例。在这个示例中,使用`np.einsum('ijk,jil->kl', a, b)`计算了两个3阶张量a和b的乘积,并生成了一个2阶张量o。这个示例中的公式解析为对i和j进行求和,然后将结果存储在输出张量的k和l位置上。 总之,`torch.einsum`是一个非常灵活和强大的函数,可以用于执行各种张量运算。它可以根据指定的公式对输入张量进行操作,并生成输出张量。 #### 引用[.reference_title] - *1* *2* [【Pytorch写代码技巧--EinsumEinsum详解+常用写法](https://blog.csdn.net/ccaoshangfei/article/details/126995397)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Pytorch中, torch.einsum详解。](https://blog.csdn.net/a2806005024/article/details/96462827)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值