使用TensorFlow构建Seq2Seq模型时出现错误

15

我正在尝试理解tensorflow中seq2seq.py定义的seq2seq模型。我从随tensorflow提供的translate.py示例中复制一些代码。我一直得到同样的错误,但真的不明白它来自哪里。

一个最小化的代码示例以重现错误:

import tensorflow as tf
from tensorflow.models.rnn import rnn_cell
from tensorflow.models.rnn import seq2seq

encoder_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 tf
from tensorflow.models.rnn import rnn_cell
from tensorflow.models.rnn import seq2seq

encoder_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))

我现在正试图学习tf中的seq2seq。您的编码器词汇表大小为350,解码器为45吗? - Soubriquet
2个回答

8
大多数模型(seq2seq也不例外)期望它们的输入是批量的,因此如果您的逻辑输入形状为[n],那么您将用作模型输入的张量的形状应该是[batch_size x n]。实际上,形状的第一个维度通常被省略为None并在运行时推断出批处理大小。
由于seq2seq的逻辑输入是数字向量,实际张量形状应为[None, input_sequence_length]。因此,固定代码应该如下所示:
input_sequence_length = 2; # the length of one vector in your input sequence

for i in xrange(350):  
    encoder_inputs.append(tf.placeholder(tf.int32, shape=[None, input_sequence_length],
                                              name="encoder{0}".format(i)))

(然后对解码器执行相同的操作)

谢谢你的帮助!根据你的建议,我编辑了上面的问题并添加了一些额外的问题。512是我的隐藏层的大小。我猜你的意思是tf.placeholder中的数字应该反映我的输入和输出向量的大小,而不是隐藏层的大小? - user1782011
是的,我怀疑它不应该是512,但错误消息让我感到困惑 :) 我想我读错了。你修复代码的方式实际上是正确的。我不确定int32float问题,但请注意,basic_rnn_seq2seq有一个参数dtype,默认为float32。尝试将其设置为int32,然后将输入也更改为int32--但我对该参数没有完全理解,所以这只是一个猜测。 - Ishamael
此外,通常最好的做法是在遇到新问题时提出新的问题,而不是编辑原先的问题,这样当人们搜索答案和问题时,可以保持简单并覆盖单个问题。 - Ishamael
非常感谢您的输入! - user1782011

1
在翻译模块中有一个自测方法,显示其最小使用量。[这里]
我刚刚使用了自测方法。
python translate.py --self_test 1

嘿,自测确实很有帮助;但是我的主要痛点在于seq2seq_model.py。我仍然不明白为什么我的上面的代码示例失败了:( - user1782011

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接