Tensorflow 和 Keras:LSTM 在 seq2seq 问题上表现不佳,解决方案清晰

Tensorflow & Keras: LSTM performs bad on seq2seq problem with clear solution

我正在学习机器翻译的 tensorflow 和 seq2seq 问题。 为此,我给了我以下任务:

我创建了一个 Excel,包含不同类型的随机日期,例如:

  1. 05.09.2192
  2. martes, 07 de mayo de 2329
  3. 2129 年 12 月 30 日星期五

在我的数据集中,每种类型都出现了 1000 次。这些是我的火车 (X) 值。 我的目标 (Y) 值总是占一半:

另外一半是这样的:

为了使模型能够区分这两个 Y 值,另一个上下文信息 (C) 以文本形式给出:

  1. Ausgeschrieben(写出来)
  2. 基准(日期)

所以有些行看起来像这样:

所以我的目标是创建一个模型,它能够将任何日期类型“翻译”为德语日期类型,例如05.09.2192.

数据集包含 34.000 对。

为了解决这个问题,我使用基于字符的分词器将文本转换为整数:

tokenizer = keras.preprocessing.text.Tokenizer(filters='', char_level=True, oov_token="|")

我使用 LSTM 编码器-解码器模型,我希望它能达到完美的精度,因为 X 和 Y 之间的依赖关系可以完美解决。

但是,我最多达到 72% 的准确率。更糟糕的是,准确度只能达到那么多,因为填充生成得很好。例如。大多数 Y 值都非常短,因此会被填充。所以 12.02.2001 变成例如||||||||||||||||||||12.02.2001。所以模型学得很好,生成了 padding token,但不是期望值。

这是我最近一次测试使用的模型结构:

from tensorflow.keras.layers import Concatenate

encoder_inputs = keras.layers.Input(batch_input_shape=[32,None], dtype=np.int32)
decoder_inputs = keras.layers.Input(batch_input_shape=[32,None], dtype=np.int32)
embeddings = keras.layers.Embedding(vocab_size, 1)
encoder_embeddings = embeddings(encoder_inputs)
decoder_embeddings = embeddings(decoder_inputs)

encoder_0 = keras.layers.Dense(128)(encoder_embeddings)
encoder_0d = keras.layers.Dropout(0.4)(encoder_0)
encoder_0_1 = keras.layers.Dense(256)(encoder_0d)
encoder_0_1d = keras.layers.Dropout(0.2)(encoder_0_1)
encoder_0_2 = keras.layers.Dense(128)(encoder_0_1d)
encoder_0_2d = keras.layers.Dropout(0.05)(encoder_0_2)
encoder_0_3 = keras.layers.Dense(64)(encoder_0_2d)

encoder_1 = keras.layers.LSTM(64, return_state=True, return_sequences=True, recurrent_dropout=0.2)
encoder_lstm_bidirectional = keras.layers.Bidirectional(encoder_1)
encoder_output, state_h1, state_c1, state_h2, state_c2 = encoder_lstm_bidirectional(encoder_0_3)
encoder_state = [Concatenate()([state_h1, state_h2]), Concatenate()([state_c1, state_c2])]

sampler = tfa.seq2seq.sampler.TrainingSampler()
decoder_cell = keras.layers.LSTMCell(64*2)

output_layer = keras.layers.Dense(vocab_size)

decoder = tfa.seq2seq.basic_decoder.BasicDecoder(decoder_cell, sampler, output_layer=output_layer)

final_outputs, final_state, final_sequence_lengths = decoder(decoder_embeddings, initial_state=encoder_state,
                                                             sequence_length=[sequence_length], training=True)
y_proba = tf.nn.softmax(final_outputs.rnn_output)

model = keras.Model(inputs=[encoder_inputs, decoder_inputs], outputs=[y_proba])

如果需要,我可以在github中部署整个笔记本,但也许有一个简单的解决方案,我只是到目前为止没有看到。 感谢您的帮助!

因此,如果这对将来的任何人有帮助: 该模型完全按照我的要求去做。

但是

您需要小心,您的数据预处理不会导致歧义。 所以你必须防止这样的事情:

a -> b and also a -> c

在改进一个方程式的同时,另一个方程式将丢失。那是我的问题。 看这个例子:

eq1: 26.04.1994 -> 26.04.1994
eq2: 26.04.1994 -> Tuesday, 26.04.1994

一方面,模型提高了 eq1 的准确性。另一方面,它减少了 eq2 的损失。所以 74% 是一种妥协,模型找到了。

为了解决这个问题,我不得不添加另一个因素,它更具体地描述了数据。所以我额外加了一个条件,描述y是写出来还是只写成date类型。所以现在我有一个像下面这样的数据结构,我的准确率增长到 98%:

eq1: 26.04.1994, dateformat -> 26.04.1994
eq2: 26.04.1994, written_out -> Tuesday, 26.04.1994