Python 带有整数序列的Keras示例字级模型给出“预期ndim=3,发现ndim=4`

Python 带有整数序列的Keras示例字级模型给出“预期ndim=3,发现ndim=4`,python,machine-learning,keras,lstm,word-embedding,Python,Machine Learning,Keras,Lstm,Word Embedding,我正在尝试在奖金部分列出的上实现Keras单词级示例->如果我想使用带整数序列的单词级模型怎么办? 我已经用名称标记了层,以帮助我稍后将层从加载的模型重新连接到推理模型。我想我遵循了他们的示例模型: # Define an input sequence and process it - where the shape is (timesteps, n_features) encoder_inputs = Input(shape=(None, src_vocab), name='enc_input

我正在尝试在奖金部分列出的上实现Keras单词级示例->如果我想使用带整数序列的单词级模型怎么办?

我已经用名称标记了层,以帮助我稍后将层从加载的模型重新连接到推理模型。我想我遵循了他们的示例模型:

# Define an input sequence and process it - where the shape is (timesteps, n_features)
encoder_inputs = Input(shape=(None, src_vocab), name='enc_inputs')
# Add an embedding layer to process the integer encoded words to give some 'sense' before the LSTM layer
encoder_embedding = Embedding(src_vocab, latent_dim, name='enc_embedding')(encoder_inputs)
# The return_state constructor argument configures a RNN layer to return a list where the first entry is the outputs
# and the next entries are the internal RNN states. This is used to recover the states of the encoder.
encoder_outputs, state_h, state_c = LSTM(latent_dim, return_state=True, name='encoder_lstm')(encoder_embedding)
# We discard `encoder_outputs` and only keep the states.
encoder_states = [state_h, state_c]

# Set up the decoder, using `encoder_states` as initial state of the RNN.
decoder_inputs = Input(shape=(None, target_vocab), name='dec_inputs')
decoder_embedding = Embedding(target_vocab, latent_dim, name='dec_embedding')(decoder_inputs)
# The return_sequences constructor argument, configuring a RNN to return its full sequence of outputs (instead of
# just the last output, which the defaults behavior).
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)
# Put the model together
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

所以,我还是不太明白。我有如上定义的
解码器lstm
解码器输出
,并固定了输入。当我从
h5
文件加载我的模型并构建我的推理模型时,我尝试用

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')  # named to avoid conflict
decoder_state_input_c = Input(shape=(latent_dim,), name='input_4')
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]
# Use decoder_lstm from the training model
# 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
尝试传递
解码器\u嵌入
而不是
解码器\u输入
也会失败

我试图改编的例子,但它不包括嵌入层的复杂性

更新3

当我使用
decoder\u outputs,state\u h,state\u c=decoder\lstm(decoder\u embedding,…)
来构建推理模型时,我已经确认
decoder\u embedding
embedding
类型的对象,但我得到:

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.
ValueError:使用非符号张量的输入调用层declstm。收到的类型:。完整输入:[,]。层的所有输入都应该是张量。

此模型的完整代码已打开。

问题在于
input
层的输入形状。嵌入层接受一系列整数作为输入,这些整数对应于句子中的单词索引。因为这里句子中的字数不是固定的,所以必须将
input
层的输入形状设置为
(无,)

我认为您将其误认为我们的模型中没有嵌入层,因此模型的输入形状是
(timesteps,n_features)
,以使其与LSTM层兼容

更新:

您需要首先将
解码器\u输入
传递到嵌入层,然后将结果输出张量传递到
解码器\u lstm
层,如下所示:

decoder_inputs = model.input[1] # (Input(shape=(None,)))
# pass the inputs to the embedding layer
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:

在培训期间,当创建
解码器\u lstm
层时,您需要设置
返回\u state=True

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

谢谢-修复了我的输入!我的
encoder\u输入
decoder\u输入
现在都是整数,但由于
decoder\u嵌入
是一个密集层,它仍然需要3-dims。那么我是不是只偏移整数,然后一个热的?有没有办法避免对
解码器输出进行一次热编码?@NicCottrell
解码器嵌入
不是一个密集层;相反,它是一个嵌入层。它就像一个查找表:你给它单词的索引,它给你相应的单词向量。所以它需要一个整数数组作为输入,正如我说的,它对应于一个句子中的单词索引。@NicCottrell我的评论有意义吗?还有什么困惑吗?我还在挣扎。我用更多的代码片段更新了这个问题。任何帮助都将不胜感激@NicCottrell
dec_lstm
层的输入是
dec_嵌入
层。您确定在这种情况下也会出现错误吗?上面写着什么?确保正确检索图层。由于您已在图层上分配了名称,请尝试通过
model使用其名称检索图层。获取图层(name=layer\u name)
,而不是使用索引。让我知道结果。