如何优化TensorFlow Einsum,使其支持p后任意维度的灵活矩阵乘法?
更灵活的TensorFlow einsum替代方案
针对你需要让 einsum 支持B中p之后任意数量维度的需求,这里提供几种更简洁健壮的实现方式:
方法1:tf.linalg.matmul + 维度重塑
利用批量矩阵乘法的特性,先合并B中p之后的维度,完成乘法后再展开,无需构造复杂的 einsum 字符串:
# 获取B中p之后的所有维度 suffix_dims = tf.shape(B)[pivot_axis+1:] # 将B重塑为 [..., p, -1],合并p后的所有维度 B_reshaped = tf.reshape(B, tf.concat([tf.shape(B)[:pivot_axis+1], [-1]], axis=0)) # 执行批量矩阵乘法:A([..., x, p]) × B_reshaped([..., p, flat_suffix]) result_reshaped = tf.linalg.matmul(A, B_reshaped) # 将结果展开回 [..., x, *suffix_dims] result = tf.reshape(result_reshaped, tf.concat([tf.shape(A)[:-1], suffix_dims], axis=0))
方法2:tf.tensordot 指定匹配轴
tensordot 可以直接指定要相乘的轴,逻辑更直观,无需字符串拼接:
# 匹配A的最后一维与B的pivot_axis轴 result = tf.tensordot(A, B, axes=([-1], [pivot_axis])) # 调整维度顺序,将B中p之后的维度移到x维度后方 batch_dims = tf.rank(A) - 2 new_order = tf.concat([ tf.range(batch_dims), [batch_dims], tf.range(batch_dims + 1, tf.rank(result)) ], axis=0) result = tf.transpose(result, new_order)
优化后的einsum写法(如果坚持用einsum)
你原来的字符串技巧可以优化为动态生成足够的字母,避免固定长度字符串的限制:
num_suffix = tf.shape(B).shape[0] - pivot_axis - 1 suffix = ''.join([chr(ord('a') + i) for i in range(num_suffix)]) result = tf.einsum(f"...xp,...p{suffix}->...x{suffix}", A, B)
内容的提问来源于stack exchange,提问作者cgreen
相关产品推荐
相关产品推荐

