2017-02-12 183 views
3

我有兩個矩陣與某些維度的矩陣乘法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

回答

1

不知道爲什麼tf.matmul不支持這種乘法(可能是核心開發人員可以提供有意義的答案之一)。

但是,如果你只是想能夠以這種方式乘以張量,看看tf.einsum功能。它可以以任意級別的張量運行。

0

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

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

但很明顯,它不計算你想要的東西。