Модель Seq2Seq учится выводить токен EOS (‹\ s›) только после нескольких итераций.

Я создаю чат-бота, обученного 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), чтобы увидеть, возможно ли правильное слово где-то там, но, похоже, он предсказывает наиболее распространенные слова в словаре (например, i, you,?,. ). Даже эти 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).


person noel    schedule 28.09.2018    source источник
comment
Что составляет итерацию? Это мини-батч? Эпоха? В любом случае такое поведение меня не особо удивляет. Когда я тренирую RNN, они обычно проходят фазу на ранней стадии обучения, когда они многократно выводят один и тот же символ. Решение может заключаться просто в том, что вам нужно тренировать модель дольше. Если поведение сохраняется после тренировок в течение многих эпох, возможно, что-то не так.   -  person myrtlecat    schedule 29.09.2018
comment
Итерация в этом случае просто применяет градиентный спуск к одному случайному пакету. Я позволил ему тренироваться на несколько тысяч итераций, и прогнозируемый результат всегда будет EOS. Даже когда я проверяю 10 лучших логитов в процессе обучения (а не только максимальное значение, используемое для вывода прогнозов), кажется, что всегда самые частые (самые распространенные) слова в словаре имеют самые высокие логиты. Я не уверен, что могло вызвать эту проблему, поскольку я основывал свой код на руководстве по NMT   -  person noel    schedule 29.09.2018
comment
Обновление @myrtlecat: я позволил ему тренироваться более ста тысяч итераций, и он по-прежнему выводит только EOS (и случайные периоды). Потери в обучении также не уменьшаются после первой итерации (остаются на отметке 47).   -  person noel    schedule 30.09.2018
comment
Ноэль, вы когда-нибудь находили решение этой проблемы? Я столкнулся с той же проблемой, и я тоже последовал совету @myrtlecat. Моя модель достигает точности 98%, затем падает до 5%, а затем снова поднимается до 20%, но она по-прежнему только предсказывает конечные токены. Я понятия не имею, почему точность даже меняется, когда он выводит только argmax, который всегда является конечным токеном   -  person Tim    schedule 22.07.2021


Ответы (2)


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

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

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

(Изменить 05/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, чтобы изменить форму тензора.

person HaoChien Hung    schedule 04.10.2018
comment
У меня точно такая же проблема, кто-нибудь знает, как ее решить? Нужно ли софтмаксировать логиты потери последовательностей? - person luvwinnie; 06.06.2020

В моем случае это из-за оптимизатора, где я по ошибке установил большой lr_decay, чтобы он больше не работал нормально.

Проверьте Lr и Оптимизатор / Планировщик могут помочь.

person Shuo Zhang    schedule 13.04.2021