Tensorflow:成本的张量列表

时间:2016-01-02 20:06:01

标签: python list machine-learning tensorflow

我正在尝试使用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()是否包含张量值列表,或者是否有一些特殊的张量对象需要它们?

2 个答案:

答案 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()

enter image description here

作为tensorflow-beginner,我还没有找到处理RNN的统一方式/最佳实践方法,但如上所述,我确定不建议这样做。喜欢你的脚本作为一个非常好的介绍,谢谢你的片段。此外,现在还有implementation of scan and RNN-tuple-friendliness的问题,所以要小心