张量流(或 numpy)中特定维度的矩阵乘法

Matrix multiplication over specific dimensions in tensorflow (or numpy)

我希望我在这里没有遗漏任何明显的东西,但是我搜索了 inter-webs 无济于事,最后来这里问...
这是对我想做的事情的一个非常枯燥和简单的描述:
假设我有一个形状为 (20, 40, 3, 5) 的张量和另一个形状为 (20, 40, 5, 7) 的张量。前两个维度大小将保持原样,并且有意使两个张量相同。另一方面,last 两个维度将被(矩阵)相乘,matmul 样式。这意味着我得到的张量将具有 (20, 40, 3, 7) 的形状。怎么办??
我意识到理论上我可以在前两个维度上循环并直接使用 tf.matmul(),但由于运行时间、效率、模型训练器和 GPU 全球抗议以及我的良心,这是绝对不行的任何重量 :-)。

很遗憾,我忽略了 "not what I need" 以下选项:
tf.tensordot 会给我一个形状为 (20, 40, 3, 20, 40, 7) 的输出。不好。
tf.scan 只有在我正确阅读它的情况下才适用于第一个维度(也许适用于 RNNs?反正不是我的情况)。
tf.matmul 适用于等级 >= 2 的张量,但分别在最后一个维度和第一个维度上的工作方式类似于 @。再一次,不是我的情况。

再说一遍 - 这怎么能做到?
numpy 帮助我找到正确方向的答案也很有帮助,但我最终需要 tf 实施。

在此先感谢,如果我遗漏了一些愚蠢的东西,我们深表歉意。


以下比较接近我的需要,但不太清楚,所以单独写:
前两个维度是图像的空间维度。最后两个实际上是方矩阵,通过 tf.contrib.distributions.fill_triangular 获得,并且正在相乘(连同其中一个的适当转置)以获得与每个空间坐标相关联的协方差矩阵。我不知道这是否有任何帮助,但它至少提供了一些背景信息。此外,也可能存在也可能不存在批次维度,但我假设解决 4-D 张量情况就足够普遍了。

张贴此以供将来参考:
来自 numpy matmul 文档:

If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.

对于维度 >2,它将把它视为一堆矩阵,尝试 matmul 最后 2 个维度,结果是 np array 作为 OP 所需。
例如:

import numpy as np

A = np.ones((1,2,1,2))
B = np.ones((1,2,2,1))

print(A.shape)
print(B.shape)
print(np.matmul(A,B).shape)

结果:

(1, 2, 1, 2)
(1, 2, 2, 1)
(1, 2, 1, 1)