5

我正在尝试在 Keras 中使用 LSTM 构建 seq2seq 模型。目前正在研究英语到法语对数据集 - 10k 对(原始数据集有 147k 对)。在尝试预测给定输入序列模型的输出时完成训练后,无论输入序列如何,都预测相同的输出。还为编码器和解码器使用单独的嵌入层。我观察到的是,预测的词只不过是数据集中最常见的词,它们按频率的降序显示。例如:“我认识你”、“我们可以走吗?”、“摆脱它”——对于所有这些输入序列,输出是——“je suis en train”(所有三个输出相同)。

任何人都可以帮助我,这可能是模型表现得这样的原因。我错过了一些基本的东西吗?

我尝试使用batchsize = 32,epoch = 50,maxinp = 8,maxout = 8,embeddingsize = 100。

    encoder_inputs = Input(shape=(None, GLOVE_EMBEDDING_SIZE), name='encoder_inputs')
    encoder_lstm1 = LSTM(units=HIDDEN_UNITS, return_state=True, name="encoder_lstm1" , stateful=False, dropout=0.2)
    encoder_outputs, encoder_state_h, encoder_state_c = encoder_lstm1(encoder_inputs)

    encoder_states = [encoder_state_h, encoder_state_c]

    decoder_inputs = Input(shape=(None, GLOVE_EMBEDDING_SIZE), name='decoder_inputs')
    decoder_lstm = LSTM(units=HIDDEN_UNITS, return_sequences=True, return_state=True, stateful=False, 
                        name='decoder_lstm', dropout=0.2)
    decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states)
    decoder_dense = Dense(self.num_decoder_tokens, activation='softmax', name='decoder_dense')
    decoder_outputs = decoder_dense(decoder_outputs)

    self.model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
    print(self.model.summary())

    self.model.compile(optimizer='rmsprop', loss='categorical_crossentropy')

    Xtrain, Xtest, Ytrain, Ytest = train_test_split(input_texts_word2em, self.target_texts, test_size=0.2, random_state=42)


    train_gen = generate_batch(Xtrain, Ytrain, self)
    test_gen = generate_batch(Xtest, Ytest, self)

    train_num_batches = len(Xtrain) // BATCH_SIZE
    test_num_batches = len(Xtest) // BATCH_SIZE

    self.model.fit_generator(generator=train_gen, steps_per_epoch=train_num_batches,
                epochs=NUM_EPOCHS,
                verbose=1, validation_data=test_gen, validation_steps=test_num_batches ) #, callbacks=[checkpoint])        

    self.encoder_model = Model(encoder_inputs, encoder_states)


    decoder_state_inputs = [Input(shape=(HIDDEN_UNITS,)), Input(shape=(HIDDEN_UNITS,))]
    decoder_outputs, state_h, state_c = decoder_lstm(decoder_inputs, initial_state=decoder_state_inputs)
    decoder_states = [state_h, state_c]
    decoder_outputs = decoder_dense(decoder_outputs)
    self.decoder_model = Model([decoder_inputs] + decoder_state_inputs, [decoder_outputs] + decoder_states)

更新::我在 147k 数据集上运行了 5 个 epoch,每个输入的结果都不同。谢谢您的帮助。

但是,现在我正在使用另一个数据集运行相同的模型,其中输入和输出序列在清理(删除停用词和其他内容)后分别包含平均单词数为 170 和 100。这个数据集有大约 30k 条记录,如果我运行 50 个 epoch,每个测试句子的结果都是相同的。那么我的下一个选择是什么让我尝试。我期待不同的输入至少有不同的输出(即使它是错误的),但相同的输出会增加更多的挫败感,无论模型是否学习不正确。有答案吗??

4

1 回答 1

0

当网络没有训练足够的 epoch 时,正确设置的基于 LSTM 的编码器-解码器 (Seq2Seq) 可能会为任何输入产生相同的输出。只需将我的 epoch 数量从 200 减少到 30,我就可以可靠地重现“无论输入什么都相同的愚蠢输出”结果。

可能令人困惑的一件事是,当您从 30 到 150 个 epoch 时,默认准确度度量似乎没有太大改善。但是,如果您将 Seq2Seq 用于聊天机器人或翻译任务,则 BLEU 分数之类的东西更相关。更相关的是你自己对回答的“现实主义”的评价。这些评估是在推理时完成的,而不是在训练期间完成的——但它们会影响您对模型是否已充分训练的评估。

要考虑的另一件事是,就我而言,训练数据是康奈尔大学的电影对话。聊天机器人对话应该是有帮助的——电影对话没有这样的要求——它只是应该很有趣。所以我们在训练和使用之间确实存在不匹配。

无论如何,这里是在 30 与 150 个 epoch 之后训练的完全相同的网络的示例,它们响应相同的输入。

30 个时代

在此处输入图像描述

150 个时代

在此处输入图像描述

在这种情况下,报告的默认 keras.Model.fit() 准确度从 0.2118(30 个 epoch 之后)变为 0.2243(150 个之后),但显然输入现在变得不同了。如果这是一个分类器,而我们只是查看训练准确性(而不查看样本推断),我们可能会合理地假设所有这些额外的训练时期都是毫无意义的。

但是这样想——例如,评估模型将鸟的图片分类为带有标记数据的鸟的能力,与评估模型封装句子或短语概念的能力和评估模型的能力完全不同。用形成连贯思想的字符序列进行适当的响应,因此默认的训练指标没有那么有用。

当我们看到波动的准确性时,我们可能会怀疑的另一件事是我们的学习率太高或适应性不足。我正在使用 rmsprop - 也许亚当会解决这个问题?但在与 Adam 进行 30 个 epoch 后,acc 为 0.2085 并开始振荡。

在这一点上,看看我的结果,很明显,电影对话的训练只会产生电影对话式的文本,这在本质上没有帮助,也不容易根据“准确性”进行评估。你会期望电影对话有“生命的火花”——独创性、意想不到的、角色之间的语气差异等等。所以在这一点上,如果我想要一个更好的聊天机器人,我需要更多适用的训练数据。

于 2021-12-27T15:37:43.493 回答