2016-01-02 43 views
5

我正嘗試在Tensor Flow中使用LSTM。我在網上找到了一個在線教程,其中包含一組序列,目標函數由LSTM的最後一個輸出和已知值組成。不過,我想讓我的目標函數使用每個輸出的信息。具體來說,我想有LSTM學習組序列(即學習所有的單詞在句子中的字母):Tensorflow:成本的張量列表

cell = rnn_cell.BasicLSTMCell(num_units) 
inputs = [tf.placeholder(tf.float32,shape=[batch_size,input_size]) for _ in range(seq_len)] 
result = [tf.placeholder(tf.float32, shape=[batch_size,input_size]) for _ in range(seq_len)] 

W_o = tf.Variable(tf.random_normal([num_units,input_size], stddev=0.01))  
b_o = tf.Variable(tf.random_normal([input_size], stddev=0.01)) 

outputs, states = rnn.rnn(cell, inputs, dtype=tf.float32) 

losses = [] 

for i in xrange(len(outputs)): 
    final_transformed_val = tf.matmul(outputs[i],W_o) + b_o 
    losses.append(tf.nn.softmax(final_transformed_val)) 

cost = tf.reduce_mean(losses) 

這樣做將導致錯誤:

TypeError: List of Tensors when single Tensor expected 

如何我應該解決這個問題嗎? tf.reduce_mean()是否接受張量值列表,還是有一些特殊張量對象需要它們?

回答

3

在你的代碼中,losses是一個Python列表。 TensorFlow的reduce_mean()需要一個張量,而不是Python列表。

losses = tf.reshape(tf.concat(1, losses), [-1, size]) 

其中規模是你正在採取softmax的值的數量應該做你想做的。見concat()

但是,我注意到你的代碼中有一點似乎有點奇怪,就是你有一個輸入佔位符列表,而the TensorFlow Tutorial中的代碼使用3階張量輸入。你的輸入是一個2階張量的列表。我建議查看教程中的代碼,因爲它幾乎完全符合您的要求。

該教程的主要文件之一是here。特別是,第139行是他們創造成本的地方。 關於您的輸入,第90和91行是輸入和目標占位符的設置位置。這兩行的主要內容是整個序列以一個佔位符而不是佔位符列表的形式傳入。

請參閱ptb_word_lm.py文件中的第120行以查看它們的拼接位置。

+1

明白了,我誤解了。我刪除了我的答案:)你可能想在你的文章中顯示教程中的代碼示例,因爲它可能會幫助新手(我也想了解它)。 – Will

+1

我正在討論的代碼位於https://tensorflow.googlesource.com/tensorflow/+/master/tensorflow/models/rnn/ptb/ptb_word_lm.py#139,關於輸入的部分位於第90行,文件。該文件的第90行中的num_steps與OP代碼中的seq_len相同(粗略)。你會建議內聯整個__init__方法,還是隻提供鏈接到文件? –

+0

啊,我明白了,是的,這是一個非常大的方法。我認爲這個文件的鏈接,有一些相關的文字和一些解釋,會使它變得最清楚。你的文章似乎是一個很好的起點,但是看到OP代碼部分不正確的部分的「正確示例」對我的想法會非常有幫助。 我有時使用的另一種策略是隻粘貼整個方法/類,但用'#...'替換不相關的行來縮短它。 – Will

2

工作例如,檢查notebook

import tensorflow as tf 
from tensorflow.models.rnn import rnn, rnn_cell 
print(tf.__version__) 
#> 0.8.0 

batch_size = 2 
output_size = input_size = 2 
seq_len  = 10 
num_units = 2 

cell = rnn_cell.BasicLSTMCell(num_units) 
inputs = [tf.placeholder(tf.float32, shape=[batch_size,input_size ]) for _ in xrange(seq_len)] 
result = [tf.placeholder(tf.float32, shape=[batch_size,output_size]) for _ in xrange(seq_len)] 

W_o = tf.Variable(tf.random_normal([num_units,input_size], stddev=0.01))  
b_o = tf.Variable(tf.random_normal([input_size],   stddev=0.01)) 

outputs, states = rnn.rnn(cell, inputs, dtype=tf.float32) 

losses = [] 

for i in xrange(seq_len): 
    final_transformed_val = tf.matmul(outputs[i],W_o) + b_o 
    losses.append(tf.squared_difference(result[i],final_transformed_val)) 

losses = tf.reshape(tf.concat(1, losses), [-1, seq_len]) 
cost = tf.reduce_mean(losses) 

要在行動中看到這一點,你可以喂圖在哈克的方式:

import matplotlib.pyplot as plt 
import numpy as np 

step = tf.train.AdamOptimizer(learning_rate=0.01).minimize(cost) 
sess = tf.InteractiveSession() 

sess.run(tf.initialize_all_variables()) 

costs = [] 

# EXAMPLE 
# Learn cumsum over each sequence in x 
# | t  | 0 | 1 | 2 | 3 | 4 | ...| 
# |----------|---|---|---|---|----|----| 
# | x[:,0,0] | 1 | 1 | 1 | 1 | 1 | ...| 
# | x[:,0,1] | 1 | 1 | 1 | 1 | 1 | ...| 
# |   | | | | | | | 
# | y[:,0,0] | 1 | 2 | 3 | 4 | 5 | ...| 
# | y[:,0,1] | 1 | 2 | 3 | 4 | 5 | ...| 

n_iterations = 300 
for _ in xrange(n_iterations): 
    x = np.random.uniform(0,1,[seq_len,batch_size,input_size]) 
    y = np.cumsum(x,axis=0) 

    x_list = {key: value for (key, value) in zip(inputs, x)} 
    y_list = {key: value for (key, value) in zip(result, y)} 

    err,_ = sess.run([cost, step], feed_dict=dict(x_list.items()+y_list.items())) 
    costs.append(err) 

plt.plot(costs) 
plt.show() 

enter image description here

由於tensorflow,初學者我還沒有找到處理RNN的統一方式/最佳實踐方式,但如上所述,我相信這不被推薦。喜歡你的腳本作爲一個非常好的介紹,謝謝你的片段。還有,現在正在進行的操作是implementation of scan and RNN-tuple-friendliness,所以要小心