Keras 示例中使用整数序列的词级模型导致`expected ndim=3, found ndim=4`错误

我正在尝试实现Keras博客中列出的奖励部分 -> 如果我想使用整数序列的词级模型怎么办?的示例代码,链接在这里

为了便于稍后从加载的模型中重新连接到推理模型,我给层标记了名称。我认为我已经按照他们的示例模型进行了操作:

# 定义一个输入序列并处理它 - 其中形状为(时间步长,特征数)
encoder_inputs = Input(shape=(None, src_vocab), name='enc_inputs')
# 添加一个嵌入层来处理整数编码的单词,以便在LSTM层之前赋予一些“意义”
encoder_embedding = Embedding(src_vocab, latent_dim, name='enc_embedding')(encoder_inputs)
# return_state构造函数参数配置RNN层以返回一个列表,其中第一项是输出,
# 后续项目是内部RNN状态。这用于恢复编码器的状态。
encoder_outputs, state_h, state_c = LSTM(latent_dim, return_state=True, name='encoder_lstm')(encoder_embedding)
# 我们丢弃`encoder_outputs`,只保留状态。
encoder_states = [state_h, state_c]
# 设置解码器,使用`encoder_states`作为RNN的初始状态。
decoder_inputs = Input(shape=(None, target_vocab), name='dec_inputs')
decoder_embedding = Embedding(target_vocab, latent_dim, name='dec_embedding')(decoder_inputs)
# return_sequences构造函数参数,配置RNN以返回其完整的输出序列(而不是
# 仅返回最后一个输出,这是默认行为)。
decoder_lstm = LSTM(latent_dim, return_sequences=True, name='dec_lstm')(decoder_embedding, initial_state=encoder_states)
decoder_outputs = Dense(target_vocab, activation='softmax', name='dec_outputs')(decoder_lstm)
# 组装模型
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)

但是我得到了

ValueError: Input 0 is incompatible with layer encoder_lstm: expected ndim=3, found ndim=4

在这一行

encoder_outputs, state_h, state_c = LSTM(...

我遗漏了什么?还是博客上的示例假设我跳过了某个步骤?

更新:

我正在使用以下方式进行训练:

X = [source_data, target_data]
y = offset_data(target_data)
model.fit(X, y, ...)

更新2:

我仍然没有完全解决问题。我已经像上面那样定义了decoder_lstmdecoder_outputs,并修正了输入。当我从h5文件加载模型并构建我的推理模型时,我尝试使用训练model连接:

decoder_inputs = model.input[1]  # dec_inputs (Input(shape=(None,)))
# decoder_embedding = model.layers[3]  # dec_embedding (Embedding(target_vocab, latent_dim))
target_vocab = model.output_shape[2]
decoder_state_input_h = Input(shape=(latent_dim,), name='input_3')  # 命名以避免冲突
decoder_state_input_c = Input(shape=(latent_dim,), name='input_4')
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]
# 使用训练模型中的decoder_lstm
# decoder_lstm = LSTM(latent_dim, return_sequences=True)
decoder_lstm = model.layers[5] # dec_lstm
decoder_outputs, state_h, state_c = decoder_lstm(decoder_inputs, initial_state=decoder_states_inputs)

但是我得到了一个错误

ValueError: Input 0 is incompatible with layer dec_lstm: expected ndim=3, found ndim=2

尝试传递decoder_embedding而不是decoder_inputs也失败了。

我正在尝试适应lstm_seq2seq_restore.py的示例,但它不包括嵌入层的复杂性。

更新3:

当我使用decoder_outputs, state_h, state_c = decoder_lstm(decoder_embedding, ...)来构建推理模型时,我已经确认decoder_embeddingEmbedding类型的对象,但得到了:

ValueError: Layer dec_lstm was called with an input that isn't a symbolic tensor. Received type: <class 'keras.layers.embeddings.Embedding'>. Full input: [<keras.layers.embeddings.Embedding object at 0x1a1f22eac8>, <tf.Tensor 'input_3:0' shape=(?, 256) dtype=float32>, <tf.Tensor 'input_4:0' shape=(?, 256) dtype=float32>]. All inputs to the layer should be tensors.

此模型的完整代码在Bitbucket上。


回答:

问题出在Input层的输入形状上。一个嵌入层接受一系列整数作为输入,这些整数对应于句子中单词的索引。由于这里句子中的单词数量不固定,因此您必须将Input层的输入形状设置为(None,)

我认为您将它与模型中没有嵌入层的情况混淆了,因此模型的输入形状是(timesteps, n_features),以使其与LSTM层兼容。

更新:

您需要首先将decoder_inputs传递给嵌入层,然后将生成的输出张量传递给decoder_lstm层,像这样:

decoder_inputs = model.input[1] # (Input(shape=(None,)))
# 将输入传递给嵌入层
decoder_embedding = model.get_layer(name='dec_embedding')(decoder_inputs) # ...
decoder_lstm = model.get_layer(name='dec_lstm') # dec_lstm
decoder_outputs, state_h, state_c = decoder_lstm(decoder_embedding, ...)

更新2:

在训练时,创建decoder_lstm层时,您需要设置return_state=True

decoder_lstm, _, _ = LSTM(latent_dim, return_sequences=True, return_state=True, name='dec_lstm')(decoder_embedding, initial_state=encoder_states)

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

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