矩阵乘法tensorflow与numpy的区别

问题描述:

我有两个矩阵与某些维度的矩阵乘法numpy工作,但在tensorflow中不起作用的情况。矩阵乘法tensorflow与numpy的区别

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]. 

为什么此操作失败?

+0

numpy matmul在这里做什么?广播第二次进入10,20,30和20,30到10乘以(30,40)?似乎TF matmul缺少广播,可能值得提交功能请求。你可以通过执行'y = tf.Variable(tf.truncated_normal([30,40],name ='w')+ tf.zeros((10,30,40)))''触发广播。相关问题(可能由于错误而关闭) - https://github.com/tensorflow/tensorflow/issues/216 –

+0

matmul在这里与'np.einsum('ijk,kl-> ijl',x,y) ' – Kuba

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

但是,如果你只是想能够以这种方式乘以张量,看看tf.einsum功能。它可以以任意级别的张量运行。

正如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) 

人已经告诉你了,你可以用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) 

但很明显,它不计算你想要的东西。