通过重复矩阵​​但下标不同来优化爱因斯坦求和

时间:2019-01-09 10:21:23

标签: algorithm numpy matrix matrix-multiplication numpy-einsum

免责声明:没有关于发布到数学堆栈交换或某种形式的消息。但是我从数学方面的主要朋友那里听说,他们并没有真正使用爱因斯坦求和法,但是我确实知道机器学习会大量使用爱因斯坦求和法。因此,我在此发布了这个问题(以优化算法性能)。

在研究矩阵计算(例如,至少需要多少个元素明智的乘法)时,我试图计算以下梯度:

high level equation

其中 ABC表示在其第一个轴上收缩三个矩阵(例如2x32x42x5变成3x4x5 2轴的总和)。基本上,它计算3矩阵收缩ABC相对于A的范数梯度。然后再次针对A计算该梯度的范数。

这等效于:

traditional writing

或简化一点(由autograd证明):

enter image description here

我们可以用爱因斯坦求和形式(由einsumnumpy等许多软件包的tensorflow函数使用)编写

np.einsum('ia,ib,ic,jb,jc,jd,je,kd,ke->ka', A, B, C, B, C, B, C, B, C)

在编写此代码时,我发现矩阵BC在求和中有点重复。我想知道我是否可以将那些“很多B和C”简化为某种矩阵功率?那应该使事情更快地达到对数。我尝试手动简化,但没有弄清楚。

非常感谢!如果我说的话不正确,请纠正我。

1 个答案:

答案 0 :(得分:0)

我发现我可以首先广播(即外部产品)B(形状为ib)和C(形状为ic)来获得{{1} }形状为BC的张量:

ibc

然后我可以用它的转置张量收缩它以获得平方矩阵:

BC = np.einsum('ib,ic->ibc', B, C)

此矩阵JUMP = np.einsum('ibc,cbj->ij', BC, BC.T) 是正方形的,其作用类似于“梯度跳跃”运算符,可跳跃梯度的顺序。例如,如果我想获得问题中提到的第二阶梯度,我可以简单地将此JUMP与第一阶梯度相乘来得到:

JUMP

要获得三阶,请将其乘以矩阵平方:

g2 = JUMP @ g1

要求阶,请乘以矩阵的阶幂(不是立方):

g3 = JUMP @ JUMP @ g1
相关问题