使用tensorflow构建seq2seq模型时出现错误

我正在尝试理解tensorflow中seq2seq.py文件中定义的seq2seq模型。我使用了从tensorflow附带的translate.py示例中复制的一些代码。我不断遇到相同的错误,并且实在不明白错误的来源。

重现错误的最小代码示例:

import tensorflow as tffrom tensorflow.models.rnn import rnn_cellfrom tensorflow.models.rnn import seq2seqencoder_inputs = []decoder_inputs = []for i in xrange(350):      encoder_inputs.append(tf.placeholder(tf.int32, shape=[None],                                              name="encoder{0}".format(i)))for i in xrange(45):    decoder_inputs.append(tf.placeholder(tf.int32, shape=[None],                                         name="decoder{0}".format(i)))model = seq2seq.basic_rnn_seq2seq(encoder_inputs,                                  decoder_inputs,rnn_cell.BasicLSTMCell(512))

在评估最后一行时我得到的错误(我在python解释器中交互式地评估它):

    >>>  Traceback (most recent call last):      File "<stdin>", line 1, in <module>      File "/tmp/py1053173el", line 12, in <module>      File "/usr/local/lib/python2.7/dist-packages/tensorflow/models/rnn/seq2seq.py", line 82, in basic_rnn_seq2seq        _, enc_states = rnn.rnn(cell, encoder_inputs, dtype=dtype)      File "/usr/local/lib/python2.7/dist-packages/tensorflow/models/rnn/rnn.py", line 85, in rnn        output_state = cell(input_, state)      File "/usr/local/lib/python2.7/dist-packages/tensorflow/models/rnn/rnn_cell.py", line 161, in __call__        concat = linear.linear([inputs, h], 4 * self._num_units, True)      File "/usr/local/lib/python2.7/dist-packages/tensorflow/models/rnn/linear.py", line 32, in linear        raise ValueError("Linear is expecting 2D arguments: %s" % str(shapes))    ValueError: Linear is expecting 2D arguments: [[None], [None, 512]]

我怀疑错误出在我这边:) 顺便说一句,文档和教程真的很好,但序列到序列模型的示例代码(英语到法语的翻译示例)相当密集。你还得在文件之间跳来跳去才能理解发生了什么。至少我好几次在代码中迷失了方向。

在这里,一个构建和训练基本seq2seq模型的最小示例(可能是在一些玩具数据上)将非常有帮助。有人知道这是否已经存在于某个地方吗?

编辑我已经根据@Ishamael的建议修复了上面的代码(意味着没有错误返回)(见下文),但在这个修复版本中仍然有一些不清楚的地方。我的输入是一系列长度为2的实值向量。我的输出是一系列长度为22的二进制向量。我的tf.placeholder代码不应该如下所示吗? (编辑 是的)

tf.placeholder(tf.float32, shape=[None,2],name="encoder{0}".format(i))tf.placeholder(tf.float32, shape=[None,22],name="encoder{0}".format(i))

我还不得不将上面的tf.int32改为tf.float32。因为我的输出是二进制的。对于我的解码器的tf.placeholder,这不应该是tf.int32吗?但如果我这样做,tensorflow又会抱怨。我不确定这背后的推理是什么。

我的隐藏层的尺寸在这里是512。

完整的修复代码

import tensorflow as tffrom tensorflow.models.rnn import rnn_cellfrom tensorflow.models.rnn import seq2seqencoder_inputs = []decoder_inputs = []for i in xrange(350):      encoder_inputs.append(tf.placeholder(tf.float32, shape=[None,512],                                          name="encoder{0}".format(i)))for i in xrange(45):    decoder_inputs.append(tf.placeholder(tf.float32, shape=[None,512],                                         name="decoder{0}".format(i)))model = seq2seq.basic_rnn_seq2seq(encoder_inputs,                                  decoder_inputs,rnn_cell.BasicLSTMCell(512))

回答:

大多数模型(seq2seq也不例外)期望它们的输入是批次的,所以如果你的逻辑输入的形状是[n],那么你将用作模型输入的张量的形状应该是[batch_size x n]。在实践中,形状的第一维通常被省略为None,并在运行时推断为批次大小。

由于seq2seq的逻辑输入是一组数字,因此实际的张量形状应该是[None, input_sequence_length]。所以修复后的代码看起来应该是这样的:

input_sequence_length = 2; # 你的输入序列中一个向量的长度for i in xrange(350):      encoder_inputs.append(tf.placeholder(tf.int32, shape=[None, input_sequence_length],                                              name="encoder{0}".format(i)))

(然后对解码器做同样的事情)

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注