免责声明:我确实虽然发布到数学堆栈交换或某种类型。但我从我主修数学的 friend 那里听说,他们并没有真正经常使用爱因斯坦求和,但我确实知道机器学习使用了很多。因此我在这里发布了这个问题(作为优化算法性能)。
在研究矩阵计算时(例如至少需要多少个元素乘法),我试图计算以下梯度:
其中 ABC
表示在第一轴上收缩三个矩阵(例如 2x3
、2x4
和 2x5
变成 3x4x5
,2
轴相加)。基本上,它计算 3 矩阵收缩 ABC
相对于 A
的范数梯度。然后再次计算关于 A
的梯度范数。
这相当于:
或者简化一点(通过autograd
证明):
我们可以用 Einstein Summation 形式写这个(被很多包的 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”简化为某种矩阵幂?那应该使事情以对数方式更快。我尝试手动简化但没有弄清楚。
非常感谢!如果我说的不正确,请纠正我。
最佳答案
我发现我可以先广播(即外积)B
(形状ib
)和C
(形状ic
) 得到 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
为了得到四次序,乘以它的矩阵四次方(不是立方):
g4 = np.linalg.matrix_power(JUMP, 4) @ g1
关于algorithm - 优化具有重复矩阵但下标不同的爱因斯坦求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54107864/