在 Python 中使用 einsum 函数时,评估一个表达式的最低成本收缩顺序是非常重要的,因为它可以大大减少计算时间和内存消耗。下面是一些可以帮助评估最低成本收缩顺序的建议:
-
查看表达式中各个维度的形状和出现次数,以确定哪些维度需要收缩,哪些维度需要保留。
-
将表达式表示为一个图形,将维度的乘法表示为边缘,将各条边的加权节点表示为表达式中的各个维度,将边缘的权重表示为表达式中各个维度出现的次数。
-
使用现有的最低成本收缩顺序算法来评估图形的最低成本收缩顺序,其中包括 butler、greedy、optimal 等算法。
-
使用得到的最低成本收缩顺序来确定表达式中的各个维度的顺序,并计算表达式的结果。
下面是两个示例说明,说明如何使用上面的方法来评估表达式的最低成本收缩顺序。
- 假设有一个表达式,表示两个矩阵相乘并保留第一维和第三维:
np.einsum('ijk,ikm->ijm', A, B)
我们可以表示表达式为一个图形,如下所示:
k m
==== ====
/ / \
i | Aij Aikm |
\ \____/
==== ====
j k
在上面的图形中,我们看到 A 矩阵的第二维和 B 矩阵的第一维需要收缩,而 A 矩阵的第一维和 B 矩阵的第二维需要保留。因此,我们可以使用 einsum 的参数字符串 ik,jkm->ijm
来评估表达式的最低成本收缩顺序。在这个参数字符串中,我们首先收缩了 A 矩阵的第二维和 B 矩阵的第一维,然后保留了 A 矩阵的第一维和 B 矩阵的第二维。
- 假设有一个表达式,表示两个矩阵相乘并保留第一维和第四维:
np.einsum('ijkl,lmn->ijmn', A, B)
我们可以表示表达式为一个图形,如下所示:
k n
==== ====
/ / \
i | Aijk Blmn |
\ \____/
==== ====
j m
在上面的图形中,我们看到 A 矩阵的第二维和 B 矩阵的第一维需要收缩,而 A 矩阵的第一维和 B 矩阵的第三维需要保留。但这个表达式本身有两个维度需要保存,我们需要进一步评估最低成本的收缩顺序。
使用现有的最低成本收缩顺序算法,如 greedy 算法,可以得到最低成本收缩顺序为 ik,klmn->ijmn
。在这个参数字符串中,我们首先收缩了 A 矩阵的第二维和 B 矩阵的第一维,然后保留了 A 矩阵的第一维和 B 矩阵的第三维。最终,我们还需要在限定时间内验证最低成本的收缩顺序是否正确。