如何测试使用教师强制训练的模型

Posted

技术标签:

【中文标题】如何测试使用教师强制训练的模型【英文标题】:How to test a model trained using teacher forcing 【发布时间】:2019-11-09 12:23:46 【问题描述】:

我使用 keras 训练了一个 seq2seq 模型 (keras.models.Model)。模型的 X 和 y 是 [X_encoder, X_decoder] 和 y 即编码器和解码器输入和标签的列表(注意解码器输入 X_decoder 是 'y' 比实际y。基本上,教师强迫)。

所以我现在的问题是在训练之后,当涉及到我没有任何标签的实际预测时,如何为我的输入提供“X_decoder”?还是我要训练其他东西?

如果有帮助的话,这是模型定义的 sn-p:)

# Encoder
encoder_inputs = Input(batch_shape=(batch_size, max_len,), dtype='int32')
encoder_embedding = embedding_layer(encoder_inputs)
encoder_LSTM = CuDNNLSTM(hidden_dim, return_state=True, stateful=True)
encoder_outputs, state_h, state_c = encoder_LSTM(encoder_embedding)

# Decoder
decoder_inputs = Input(shape=(max_len,), dtype='int32')
decoder_embedding = embedding_layer(decoder_inputs)
decoder_LSTM = CuDNNLSTM(hidden_dim, return_state=True, return_sequences=True)
decoder_outputs, _, _ = decoder_LSTM(decoder_embedding, initial_state=[state_h, state_c])

# Output
outputs = TimeDistributed(Dense(vocab_size, activation='softmax'))(decoder_outputs)
model = Model([encoder_inputs, decoder_inputs], outputs)

# model fitting:
model.fit([X_encoder, X_decoder], y, steps_per_epoch=int(number_of_train_samples/batch_size),
epochs=epochs)

【问题讨论】:

一种非常常见的方法是让模型生成序列样本,只需为给定的encoder input 为解码器提供一些噪声。从这个样本中选择最正确的序列,进行一些编辑,然后用这个序列训练模型decoder input 好的,我有点听从你说的,但我还有一些问题。那么从噪声解码器输入中选择最正确的序列是手动的吗?用这个解码器训练模型也会在已经训练好的模型之上,对吧?另外,如果我无论如何选择一个随机噪声并重新训练模型以获得更好的结果,这比“不”使用教师强制有什么好处?像这样几乎类似于在正常 RNN 中发生的情况,您将预测输出与下一个输入放在一起 是的,它是手动的;你可以使用一些自动化的方法是可能的。您必须生成完整的序列,查看错误在哪里纠正它们并将正确的序列反馈回模型。我和老师强迫没有太大区别。不同之处在于您的解码器将在推理模式下运行;您会将编码器的隐藏状态和一些噪声传递给解码器,它会尝试预测输出序列。您将使用解码器生成的最佳副本(或其变体)来进一步微调系统。 【参考方案1】:

通常,当你训练一个 seq2seq 模型时,decoder_inputs 的第一个标记是一个特殊的<start> 标记。所以当你尝试生成一个句子时,你会这样做

first_token = decoder(encoder_state, [<start>])
second_token = decoder(encoder_state, [<start>, first_token])
third_token = decoder(encoder_state, [<start>, first_token, second_token])
...

您执行此递归,直到您的解码器生成另一个特殊标记 - &lt;end&gt;;然后你停下来。

这是一个非常粗糙的 Python 解码器,适用于您的模型。它效率低下,因为它一遍又一遍地读取输入,而不是记住 RNN 状态 - 但它确实有效。

input_seq = # some array of token indices
result = np.array([[START_TOKEN]])
next_token = -1
for i in range(100500):
    next_token = model.predict([input_seq, result])[0][-1].argmax()
    if next_token == END_TOKEN:
        break
    result = np.concatenate([result, [[next_token]]], axis=1)
output_seq = result[0][1:] # omit the first INPUT_TOKEN

更有效的解决方案是输出 RNN 状态以及每个令牌,并使用它来生成下一个令牌。

【讨论】:

以上是关于如何测试使用教师强制训练的模型的主要内容,如果未能解决你的问题,请参考以下文章

两个张量之间差异的损失函数

如何针对训练好的模型使用测试数据?

如何使用交叉验证来确定使用训练、验证和测试集的最终模型

如何将使用 PCA 和随机森林训练的模型应用于测试数据?

如何使用测试数据计算 R 中训练模型的 MSE?

如何在训练有素的 SVD 模型上验证测试集?