对于Tensorflow 2.0上基于LSTM的Seq2Seq,推断期间解码器模型上的InvalidArgumentError

时间:2019-11-17 18:05:54

标签: python lstm tensorflow2.0 tf.keras seq2seq

  

版本:Python 3.6.9,Tensorflow 2.0.0,CUDA 10.0,CUDN 7.6.1,Nvidia驱动程序版本410.78。

我正在尝试将基于LSTM的Seq2Seq tf.keras模型移植到tensorflow 2.0

现在,当我尝试在解码器模型上调用predict时遇到以下错误(有关实际的推理设置代码,请参见下文)

就好像在期待一个单个单词作为自变量一样,但是我需要它来解码一个完整的句子(我的句子是单词索引的右填充序列,长度为24)

  

P.S。:该代码过去在 1.15版本上完全按原样工作

InvalidArgumentError:  [_Derived_]  Inputs to operation while/body/_1/Select_2 of type Select must have the same size and shape.
Input 0: [1,100] != input 1: [24,100]
     [[{{node while/body/_1/Select_2}}]]
     [[lstm_1_3/StatefulPartitionedCall]] [Op:__inference_keras_scratch_graph_45160]

Function call stack:
keras_scratch_graph -> keras_scratch_graph -> keras_scratch_graph

完整模型

enter image description here

ENCODER推断模型

enter image description here

DECODER推断模型

enter image description here

推理设置(实际发生错误的行)

重要信息:序列被右填充到 24 个元素,而 100 是每个单词嵌入的维数。这就是为什么错误消息(和打印件)显示输入形状为(24,100)的原因。

  

请注意,此代码在 CPU 上运行。在GPU上运行它会导致另一个错误,here

# original_keyword is a sample text string

with tf.device("/device:CPU:0"):

    # this method turns the raw string into a right-padded sequence
    query_sequence = keyword_to_padded_sequence_single(original_keyword)

    # no problems here
    initial_state = encoder_model.predict(query_sequence)

    print(initial_state[0].shape) # prints (24, 100)
    print(initial_state[1].shape) # (24, 100)

    empty_target_sequence = np.zeros((1,1))

    empty_target_sequence[0,0] = word_dict_titles["sos"]

    # ERROR HAPPENS HERE:
    # InvalidArgumentError:  [_Derived_]  Inputs to operation while/body/_1/Select_2 of type Select 
    # must have the same size and shape.  Input 0: [1,100] != input 1: [24,100]
    decoder_outputs, h, c = decoder_model.predict([empty_target_sequence] + initial_state)

我尝试过的事情

  • 禁用急切模式(这只会使训练慢得多,并且推理期间的错误保持不变)

  • 在将输入提供给预测函数之前重塑输入

  • 在调用LSTM层时手动计算(embedding_layer.compute_mask(inputs))和设置掩码

1 个答案:

答案 0 :(得分:1)

从我的模型体系结构中可以看到,initial_state是一系列张量为[(?, 100), (?, 100), (?, 100)]的张量。在您的情况下,未知尺寸固定为24。

然后,构建形状为(1, 1)的Numpy数组/ TF张量。您将其包装在列表中,并附加您的initial_state。因此,您将获得具有以下形状的张量列表:[(1, 1), (?, 100), (?, 100), (?, 100)]

您尝试将其作为输入传递到解码器模型,该模型需要3个形状为[(?, 24), (?, 100), (?, 100)]的输入(输入列表)。

从这开始看来似乎有问题...

但是,TF抱怨操作while/body/_1/Select_2的输入。 input 1应该来自您的任何initial_state张量(我们知道其形状为(24, 100))。 input 2似乎来自您的empty_target_sequence,其形状为(1, 1),形状可以是broadcasted(1, 100)。顺便说一句,奇怪的是,由于这两个维度的尺寸均为1 ...,它没有广播到(24, 100)

我建议在TensorBoard中检查您的图形。您应该能够找到混乱的操作并跟踪其输入张量。