Модель Seq2Seq учится выводить токен EOS (<\ s>) только после нескольких итераций - PullRequest
0 голосов
/ 29 сентября 2018

Я создаю чат-бота, обученного на Cornell Movie Dialogs Corpus с использованием NMT .

Я частично основываю свой код с https://github.com/bshao001/ChatLearner иhttps://github.com/chiphuyen/stanford-tensorflow-tutorials/tree/master/assignments/chatbot

Во время обучения я печатаю случайный выходной ответ, поданный на декодер из пакета, и соответствующий ответ, который, по прогнозам моей модели, будет наблюдать за процессом обучения.

Моя проблема: После всего лишь 4 итераций обучения модель учится выводить токен EOS (<\s>) для каждого временного шага.Он всегда выводит это как ответ (определяемый с использованием argmax логитов), даже когда обучение продолжается.Время от времени модель редко выдает в качестве ответа серию периодов.

Я также печатаю 10 лучших логит-значений во время обучения (не только argmax), чтобы увидеть, может быть, где-то там правильное слово, но, похоже, оно предсказывает наиболее распространенные слова в словаре (например, я, вы, ?, .).Даже эти 10 лучших слов не сильно меняются во время тренировок.

Я удостоверился в правильности подсчета длины входной последовательности для кодера и декодера и добавил соответственно токены SOS (<s>) и EOS (также используются для заполнения).Я также выполняю маскирование в расчете потерь.

Вот пример вывода:

Итерация обучения 1:

Decoder Input: <s> sure . sure . <\s> <\s> <\s> <\s> <\s> <\s> <\s> 
<\s> <\s>
Predicted Answer: wildlife bakery mentality mentality administration 
administration winston winston winston magazines magazines magazines 
magazines

...

Учебная итерация 4:

Decoder Input: <s> i guess i had it coming . let us call it settled . 
<\s> <\s> <\s> <\s> <\s>
Predicted Answer: <\s> <\s> <\s> <\s> <\s> <\s> <\s> <\s> <\s> <\s> 
<\s> <\s> <\s> <\s> <\s> <\s> <\s> <\s>


После еще нескольких итераций он основывается только на прогнозировании EOS (и редко на некоторых периодах))

Я не уверен, что может быть причиной этой проблемы, и застрял на этом некоторое время.Любая помощь будет принята с благодарностью!

Обновление: Я позволил ей тренироваться более ста тысяч итераций, и она по-прежнему выводит только EOS (и случайные периоды).Потеря тренировки также не уменьшается после нескольких итераций (она остается на уровне 47 с начала)

1 Ответ

0 голосов
/ 04 октября 2018

В последнее время я также работаю над моделью seq2seq.Я сталкивался с вашей проблемой раньше, в моем случае я решаю ее, изменяя функцию потерь.

Вы сказали, что используете маску, поэтому я полагаю, что вы используете tf.contrib.seq2seq.sequence_loss, как я.

Я изменил на tf.nn.softmax_cross_entropy_with_logits, и он работает нормально (и более высокая стоимость вычислений).

(Редактировать 10/10/2018. Извините, мне нужно редактировать, поскольку я обнаружил в своем коде вопиющую ошибку)

tf.contrib.seq2seq.sequence_loss может работать очень хорошо, если форма logits, targets, mask правильная.Как определено в официальном документе: tf.contrib.seq2seq.sequence_loss

loss=tf.contrib.seq2seq.sequence_loss(logits=decoder_logits,
                                      targets=decoder_targets,
                                      weights=masks) 

#logits:  [batch_size, sequence_length, num_decoder_symbols]  
#targets: [batch_size, sequence_length] 
#weights: [batch_size, sequence_length] 

Ну, он все еще может работать, даже если форма не соответствует.Но результат может быть странным (много #EOS #PAD ... и т. Д.).

Поскольку decoder_outputs и decoder_targets могут иметь ту же форму, что и требовалось (в моем случае мой decoder_targets имеет форму [sequence_length, batch_size]).Поэтому попробуйте использовать tf.transpose, чтобы помочь вам изменить форму тензора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...