You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求与einsum全约简等价的N维tensordot通用实现方案

用tensordot实现任意N阶张量的全约简(等价于einsum('...,...'))

嘿,这个需求我太懂了!每次针对不同维度写einsum确实麻烦,用tensordot完全可以实现通用的任意N阶张量全约简,不用逐个维度编写代码。

核心思路

你用einsum('ijk,ijk', A, B)做的事情,本质是两个同形状张量对应位置元素相乘后,对所有元素求和。要让tensordot实现这个效果,只需要告诉它:把两个张量的所有对应轴都进行收缩(也就是一一配对求和)。

通用实现方法

对于任意同形状的N阶张量A和B,只需要获取它们的维度数ndim,然后给tensordot的axes参数传入两个包含所有轴序号的列表,或者直接传入维度数ndim(更简洁):

代码示例

import numpy as np

# 通用函数封装
def full_tensor_reduce(A, B):
    if A.shape != B.shape:
        raise ValueError("两个张量必须具有相同的形状!")
    ndim = A.ndim
    # 两种写法等价,选你喜欢的就行
    # 写法1:显式指定所有轴
    # return np.tensordot(A, B, axes=(list(range(ndim)), list(range(ndim))))
    # 写法2:直接传入维度数,更简洁
    return np.tensordot(A, B, axes=ndim)

验证等价性

我们可以用你给出的1D到4D例子来验证,结果和einsum完全一致:

# 1D测试
A_1D = np.random.rand(5)
B_1D = np.random.rand(5)
print(np.allclose(np.einsum('i,i', A_1D, B_1D), full_tensor_reduce(A_1D, B_1D)))  # True

# 2D测试
A_2D = np.random.rand(3,4)
B_2D = np.random.rand(3,4)
print(np.allclose(np.einsum('ij,ij', A_2D, B_2D), full_tensor_reduce(A_2D, B_2D)))  # True

# 3D测试
A_3D = np.random.rand(2,3,4)
B_3D = np.random.rand(2,3,4)
print(np.allclose(np.einsum('ijk,ijk', A_3D, B_3D), full_tensor_reduce(A_3D, B_3D)))  # True

# 4D测试
A_4D = np.random.rand(2,2,3,4)
B_4D = np.random.rand(2,2,3,4)
print(np.allclose(np.einsum('ijkl,ijkl', A_4D, B_4D), full_tensor_reduce(A_4D, B_4D)))  # True

为什么这样可行?

tensordot的axes参数有几种用法:

  • 当传入整数n时,表示将两个张量的前n个轴一一配对收缩;
  • 当传入两个列表(axes_a, axes_b)时,将axes_a中的轴和axes_b中的轴一一配对收缩。

对于N阶张量,不管用哪种写法,都是把两个张量的所有轴一一对应收缩,最终效果就是所有对应位置元素相乘后求和,和你用einsum写的全约简完全等价,而且不管N多大都能通用。

内容的提问来源于stack exchange,提问作者Saxodrum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:56:41