我正在尝试使用Tensor Flow中的LSTM。我在网上找到了一个教程,其中包含一组序列,目标函数由LSTM的最后一个输出和已知值组成。但是,我希望我的目标函数使用每个输出的信息。具体来说,我试图让LSTM学习一系列序列(即在一个句子中学习单词中的所有字母)。:
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()
是否包含张量值列表,或者是否有一些特殊的张量对象需要它们?
答案 0 :(得分:3)
在您的代码中,losses
是一个Python列表。 TensorFlow的reduce_mean()
需要一个张量,而不是Python列表。
losses = tf.reshape(tf.concat(1, losses), [-1, size])
其中size是您使用softmax的值的数量应该是您想要的。见concat()
但是,我在你的代码中注意到的一点似乎有点奇怪,就是你有一个输入的占位符列表,而the TensorFlow Tutorial中的代码使用3个张量的输入。您的输入是订单2张量的列表。我建议查看教程中的代码,因为它几乎完全符合您的要求。
该教程中的一个主要文件是here。特别是,139行是他们创造成本的地方。 关于输入,第90行和第91行是设置输入和目标占位符的位置。这两行中的主要内容是整个序列在单个占位符中传递,而不是与占位符列表一起传递。
请参阅ptb_word_lm.py文件中的第120行,了解它们在何处进行连接。
答案 1 :(得分: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)
要查看此操作,您可以用hacky方式提供图表:
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()
作为tensorflow-beginner,我还没有找到处理RNN的统一方式/最佳实践方法,但如上所述,我确定不建议这样做。喜欢你的脚本作为一个非常好的介绍,谢谢你的片段。此外,现在还有implementation of scan and RNN-tuple-friendliness的问题,所以要小心