2017-05-05 62 views
2

假設我有一個輸入張量如下:如何循環遍歷TensorFlow中的可變長度佔位符?

x_inputs = tf.placeholder(tf.float32, shape=[1, None], name='x_inputs') 

這與可變長度輸入的佔位符。

另外,我有嵌入基質:

embeddings = tf.Variable(
    tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0), 
    name='embeddings') 

我想查找的輸入序列的每個元素的嵌入物,並將其添加在一起以建立一個單一的嵌入矢量。同樣的事情也來(在python):

embed = tf.zeros([batch_size, embedding_size]) 

for element in range(num_inputs): 
    embed += tf.nn.embedding_lookup(embeddings, 
            tf.cast(x_inputs[:, element], tf.int32)) 

如果num_inputs是固定的,一切正常。 問題是num_inputs的值在訓練過程中發生了變化,我需要在圖形內計算它。我不知道如何根據x_inputs中的輸入值計算圖中上面的for loop

回答

3

tf.nn.embeddings_lookup能夠處理可變尺寸的參數:

x_inputs = tf.placeholder(tf.int32, shape=[1, None], name='x_inputs') 
embeddings = tf.constant([[1,2,3], [4,5,6], [7,8,9]]) 

iterSession = tf.InteractiveSession() 

embed = tf.squeeze(tf.nn.embeddings_lookup(embeddings, x_inputs)) 

iterSession.run(embed, feed_dict={x_inputs: [[0, 1, 0, 2]]}) 
# array([[1, 2, 3], 
#  [4, 5, 6], 
#  [1, 2, 3], 
#  [7, 8, 9]], dtype=int32) 

iterSession.run(tf.reduce_sum(embed, axis=0), feed_dict={x_inputs: [[0, 1, 0, 2]]}) 
# array([13, 17, 21], dtype=int32) 

注意x_inputs是類型tf.int32的直接,避免了鑄造。


如果你想要的長度是執行過程中的動態和使用的嵌入物爲例,你可以使用tf.foldl寫:

embed = tf.foldl(lambda a, x: a + tf.nn.embedding_lookup(embeddings, x), 
       tf.reshape(x_inputs, (-1,)), 
       initializer=[[0, 0, 0]]) 
iterSession.run(embed, feed_dict={x_inputs: [[0, 1, 0, 2]]}) 
# array([[13, 17, 21]], dtype=int32) 
+0

謝謝。我不明白'tf.squeeze'的作用,你的代碼與單一長度的輸入不兼容,例如:sess.run(tf.reduce_sum(embed,axis = 0),feed_dict = {x_inputs:[[0] ]}) 返回「6」! – AmirHJ

+0

@AmirHJ啊,對。我已經放入了「擠壓」來移除單個1-D軸。但是,它默認情況下會貪婪行爲,並刪除找到的任何1個大小的尺寸。然而,我們可以指定'tf.squeeze'(即第一級)擺脫哪個軸,並且它應該與1-sized輸入兼容。 –

+0

Ahaa,問題出在'tf.reduced_sum'的'axis'參數上,最終代碼如下: 'embeds = tf.nn.embedding_lookup(embeddings,x_inputs)'然後'embed = tf.reduce_sum(embeds ,axis = 1)' 謝謝@musically_ut – AmirHJ