不知大家在看论文代码的写详解写法时候是否会常常看见 torch.einsum(),这玩意儿看起来是代码真的抽象,但是技巧深入了解后发现它原来这么好用
一、Introeduction
einsum真名叫做爱因斯坦求和约定,常用用于简洁的写详解写法表示转置、内积、代码外积、技巧各种求和
先看看以下这个例子,常用有这样的写详解写法一段代码
R=torch.enisum('ik,jk->ij',A,B)
在Einsum中,箭头从左边到右边消失了什么参数,代码那公式前就加一个带什么参数的技巧求和符。本案例中消失了k,常用因此我们需要在加上对带k的写详解写法求和符,转化为数学公式如下
对数学敏感的代码小伙伴可能已经知道这个公式代表什么意思了,但是技巧作为像博主这样愚钝的还是画图看看是什么东西
画完图之后我们可以直观的知道这就是将两个矩阵每行向量进行求内积
此外,它的底层代码就是套了很多层的for循环,如果我们不用Einsum来实现以上的功能估计要写半天了
二、Skill
是不是感觉上面的公式很简单神奇,是的Einsum诞生的初衷就是为了简化矩阵的运算,因此博主记录了以下几个常用的矩阵运算用Einsum来实现。假设有以下四个矩阵
2.1 求某行、列、维度之和
# 行之和R=torch.enisum('ij->i',A)# 列之和R=torch.enisum('ij->j',A)# 某维度之和R=torch.enisum('ijklmn->n',D)
2.2 所有元素之和
# 所有元素之和R=torch.enisum('ijklmn->',D)
2.3 转置
# 转置R=torch.enisum('ij->ji',A)
2.4 内积
# 内积R=torch.enisum('ij,jk->ik',A,B)
2.5 外积
# 外积R=torch.enisum('ij,ik->jk',A,C)
2.6 灵活相乘
# 多维相乘R=torch.enisum('ij,jk,lj->jk',A,B,C)