【问题标题】:Difference in matrix multiplication tensorflow vs numpy矩阵乘法tensorflow与numpy的区别
【发布时间】:2017-06-30 19:42:07
【问题描述】:

我有一个案例,两个具有特定维度的矩阵的矩阵乘法在 numpy 中有效,但在 tensorflow 中无效。

x = np.ndarray(shape=(10,20,30), dtype = float)
y = np.ndarray(shape=(30,40), dtype = float)
z = np.matmul(x,y)
print("np shapes: %s x %s = %s" % (np.shape(x), np.shape(y), np.shape(z)))

这按预期工作并打印:

np shapes: (10, 20, 30) x (30, 40) = (10, 20, 40)

但是在 tensorflow 中,当我尝试将占位符和与上面的 numpy 数组形状相同的变量相乘时,出现错误

x = tf.placeholder(tf.float32, shape=(10,20,30))
y = tf.Variable(tf.truncated_normal([30,40], name='w'))
print("tf shapes: %s x %s" % (x.get_shape(), y.get_shape()))
tf.matmul(x,y)

结果

tf shapes: (10, 20, 30) x (30, 40)
InvalidArgumentError: 
Shape must be rank 2 but is rank 3 for 'MatMul_12' 
(op: 'MatMul') with input shapes: [10,20,30], [30,40].

为什么这个操作会失败?

【问题讨论】:

  • numpy matmul 在这里做什么?广播第二个条目到 10,20,30 并通过 (30,40) 做 10 个 20,30 的 matmuls?似乎 TF matmul 缺少广播,可能值得提交功能请求。您可以通过 y = tf.Variable(tf.truncated_normal([30,40], name='w')+tf.zeros((10,30,40))) 触发广播。相关问题(可能被错误关闭)--github.com/tensorflow/tensorflow/issues/216
  • matmul 这里的作用和np.einsum('ijk,kl->ijl', x, y)一样

标签: python numpy matrix tensorflow


【解决方案1】:

不知道为什么tf.matmul 不支持这种乘法(可能是核心开发者之一可以提供有意义的答案)。

但如果你只是希望能够以这种方式相乘张量,请查看tf.einsum 函数。它可以使用任意等级的张量。

【讨论】:

    【解决方案2】:

    正如 Dmytro 所建议的那样,tf.einsum 可用于将这两个数组相乘。

    x = np.ndarray(shape=(10,20,30), dtype = float)
    y = np.ndarray(shape=(30,40), dtype = float)
    

    这两个操作产生完全相同的结果:

    np.einsum('ijk,kl->ijl', x, y)
    np.matmul(x,y)
    

    并且对应的tensorflow操作也有效

    tf.einsum('ijk,kl->ijl', tf_x,tf_y)
    

    【讨论】:

      【解决方案3】:

      人们已经告诉过你,你可以使用tf.einsum() 来获得你想要的结果。

      import tensorflow as tf
      x = tf.random_normal([10, 20, 30])
      y = tf.random_normal([30, 40])
      z = tf.einsum('ijk,kl->ijl', x, y)
      

      tf.matmul() 不能按你预期的方式工作的原因写在文档中。

      输入必须是矩阵(或秩 > 2 的张量,表示 批量矩阵),具有匹配的内部尺寸,可能在之后 换位。

      在您的情况下,您有一个矩阵 y 和一个张量 x(等级 3 > 2)。在您的情况下,内部尺寸不匹配。如果你想,它们匹配,你需要有这样的东西:

      import tensorflow as tf
      a, b, c = 12, 50, 20
      x = tf.random_normal([a, b, c])
      y = tf.random_normal([a, c, b])
      z = tf.matmul(x, y)
      

      但显然它计算的不是你想要的东西。

      【讨论】:

        猜你喜欢
        • 2018-11-29
        • 1970-01-01
        • 2018-11-06
        • 2012-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多