Я изучаю задачи tensorflow и seq2seq для машинного перевода. Для этого я дал мне следующую задачу:
Я создал Excel, содержащий случайные даты разных типов, например:
- 05.09.2192
- martes, 07 de mayo de 2329
- Пятница, 30 декабря 2129 г.
В моем наборе данных каждый тип встречается 1000 раз. Это моя стоимость поезда (X). Мои целевые (Y) значения всегда находятся в одной половине этого типа:
- 05.09.2192
- 07.03.2329
- 30.12.2129
А в другой половине этого типа:
- Samstag, 12 июня 2669
- Donnerstag, 1. апрель 2990
- Freitag, 10. ноябрь 2124
Чтобы модель могла различать эти два значения Y, другая контекстная информация (C) дается в виде текста:
- Ausgeschrieben (выписано)
- Дата (дата)
Итак, некоторые строки выглядят так:
Итак, моя цель - создать модель, которая способна «переводить» любой тип даты в немецкий тип даты, например, 05.09.2192.
Набор данных содержит 34000 пар.
Чтобы решить эту проблему, я использую токенизатор на основе символов для преобразования текста в целые числа:
tokenizer = keras.preprocessing.text.Tokenizer(filters='', char_level=True, oov_token="|")
Я использую модель кодировщика-декодера LSTM, и я ожидаю, что она достигнет идеальная точность, поскольку зависимость между X и Y может быть решена идеально.
Однако я достигаю максимальной точности 72%. Хуже того, точность достигает только этого, потому что заполнение создается хорошо. Например, большинство значений Y довольно короткие и поэтому дополнены. Таким образом, 12.02.2001
становится, например, ||||||||||||||||||||12.02.2001
. Таким образом, модель хорошо учится генерировать маркер заполнения, но не ожидаемое значение.
Это структура модели, которую я использовал в своем последнем тесте:
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, но может есть простое решение, просто пока не видел. Спасибо за помощь!