免责声明:我没有关于发布到数学堆栈交换或某种形式的消息。但是我从数学方面的主要朋友那里听说,他们并没有真正使用爱因斯坦求和法,但是我确实知道机器学习会大量使用爱因斯坦求和法。因此,我在此发布了这个问题(以优化算法性能)。
在研究矩阵计算(例如,至少需要多少个元素明智的乘法)时,我试图计算以下梯度:
其中 ABC
表示在其第一个轴上收缩三个矩阵(例如2x3
,2x4
和2x5
变成3x4x5
2
轴的总和)。基本上,它计算3矩阵收缩ABC
相对于A
的范数梯度。然后再次针对A
计算该梯度的范数。
这等效于:
或简化一点(由autograd
证明):
我们可以用爱因斯坦求和形式(由einsum
,numpy
等许多软件包的tensorflow
函数使用)编写
np.einsum('ia,ib,ic,jb,jc,jd,je,kd,ke->ka', A, B, C, B, C, B, C, B, C)
在编写此代码时,我发现矩阵B
和C
在求和中有点重复。我想知道我是否可以将那些“很多B和C”简化为某种矩阵功率?那应该使事情更快地达到对数。我尝试手动简化,但没有弄清楚。
非常感谢!如果我说的话不正确,请纠正我。
答案 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