Следующий этап тестирования ? рекуррентные LSTM-сети.
Как и ранее, в последних экспериментах с сетями прямого распространения, словарь создаётся инструментом Word2Vec с равномерным распределением слов в векторном пространстве. Каждое слово представляется вектором длины .
Подготовка для генерации последовательностей
Кодирование предложений
Рекуррентные сети могут генерировать последовательности, поэтому применим соответствующий способ кодирования. Попросим сеть по предложению-вопросу пословно генерировать предложение-ответ.
В текстовом виде база обучения хранится как набор предложений «Вопрос = Ответ», например:
1 ПРИВЕТ = ПРИВЕТ (2 слова) 2 ДАВНО НЕ ВИДЕЛИСЬ = ЗДРАВСТВУЙ ДРУГ (5 слов) 3 ХОРОШИЙ ДЕНЬ = ОТЛИЧНЫЙ ДЕНЬ (4 слова) 4 КАКОЙ СЕГОДНЯ ДЕНЬ = СЕГОДНЯ ОТЛИЧНЫЙ ДЕНЬ (6 слов) 5 ДАВАЙ ДРУЖИТЬ = ДАВАЙ БУДЕМ ДРУЗЬЯМИ (5 слов) 6 БУДЕШЬ МОИМ ДРУГОМ = ХОРОШО КОГДА МНОГО ДРУЗЕЙ (7 слов) 7 ДО ВСТРЕЧИ = ДО СВИДАНИЯ (4 слова)
Для управления генерацией последовательностей используются следующие служебные теги, которые закодированы с помощью Word2Vec вместе с другими словами:
- #GEN# ? конец предложения-вопроса, можно начинать генерировать ответ;
- #BOS# ? начало генерации ответа;
- #EOS# ? остановить генерацию ответа.
Для обучения нейронной сети формируются две матрицы TrainX и TrainY следующим образом. Каждая матрица имеет размер , где ? число предложений в базе ( в этом примере); ? наибольшее количество слов в предложении + 3 (для #GEN#, #BOS#, #EOS#), в данном примере ; ? длина вектора слова (50).
Все последовательности приводятся к самой длинной по числу слов. В данном примере самой длинной является последовательность №6, значит все предложения дополняются до семи слов, пустые места в конце заполняются #EOS#:
t=0 t=1 t=2 t=3 t=4 t=5 t=6 t=7 t=8 t=9 TrainX[0][t] = ПРИВЕТ #GEN# #BOS# ПРИВЕТ #EOS# #EOS# #EOS# #EOS# #EOS# #EOS# TrainY[0][t] = NULL #BOS# ПРИВЕТ #EOS# #EOS# #EOS# #EOS# #EOS# #EOS# #EOS# t=0 t=1 t=2 t=3 t=4 t=5 t=6 t=7 t=8 t=9 t=10 TrainX[1][t] = ДАВНО НЕ ВИДЕЛИСЬ #BOS# ЗДРАВСТВУЙ ДРУГ #EOS# #EOS# #EOS# #EOS# #EOS# TrainY[1][t] = NULL NULL NULL ЗДРАВСТВУЙ ДРУГ #EOS# #EOS# #EOS# #EOS# #EOS# #EOS#
NULL ? ответ сети значения не имеет, при кодировании слов заполняется нулями.
Генерирование ответа сетью
После обучения на вход нейронной сети пословно подаются все слова вопроса и тег #GEN#. После этого просим сеть предсказывать следующее слово по переданным ранее предыдущим, пока не встретится тег #EOS#. Исключая из ответа служебные теги, получаем ответ.
Тестирование архитектур
Теперь для экспериментов использую язык Python и библиотеку Keras.
Вариант 1. Одна ячейка LSTM, 65 450 параметров
В эксперименте участвуют:
- Слой 1: LSTM с D нейронами на входе и 2D на выходе;
- Слой 2: Слой прямого распространения с D нейронами.
После обучения и запоминания 109 предложений можно получить вот такие ответы.
? ПРИВЕТ ? ПРИВЕТ ? ТЕБЯ КАК ЗОВУТ? ? МЕНЯ ЗОВУТ СЕТЬ ? ПРИВЕТ СЕТЬ ? ПРИВЕТ ? ПРИВЕТ, ТЫ МЕНЯ ЗНАЕШЬ? ? Я ТОЛЬКО УЧУСЬ ? ТЕБЯ ЗОВУТ ОЛЕГ? ? ПРИЯТНО ПОЗНАКОМИТЬСЯ ? ТЕБЯ ЗОВУТ СЕТЬ? ? МЕНЯ ЗОВУТ СЕТЬ ? ТЫ ХОРОШАЯ? ? Я ДУМАЮ ТЕБЕ ? ТЕБЕ ЧТО-НИБУДЬ НРАВИТСЯ? ? МНЕ НРАВИТСЯ СЛУШАТЬ ? ХОЧЕШЬ ПОГОВОРИТЬ? ? БУДУ РАДА ИНТЕРЕСНОЙ БЕСЕДЕ ? О ЧЁМ? ? ДАВАЙ ПОГОВОРИМ О
Вариант 2. Две ячейки LSTM, 93 150 параметров
В эксперименте участвуют:
- Слой 1: LSTM с D нейронами на входе и 2D на выходе;
- Слой 2: LSTM с 2D нейронами на входе и D на выходе;
Задаём те же самые вопросы:
? ПРИВЕТ ? ПРИВЕТ ? КАК ТЕБЯ ЗОВУТ? ? МЕНЯ ЗОВУТ СЕТЬ ? ПРИВЕТ, СЕТЬ ? ЭТО ДРУГ ? ПРИВЕТ, ТЫ МЕНЯ ЗНАЕШЬ? ? Я ТОЛЬКО УЧУСЬ ? ТЕБЯ ЗОВУТ ОЛЕГ? ? МЕНЯ ЗОВУТ ? ТЕБЯ ЗОВУТ СЕТЬ? ? МЕНЯ ЗОВУТ СЕТЬ ? ТЫ ХОРОШАЯ? ? Я ДУМАЮ УЧУСЬ ? ТЕБЕ ЧТО-НИБУДЬ НРАВИТСЯ? ? МНЕ НРАВИТСЯ СЛУШАТЬ МУЗЫКУ ? ХОЧЕШЬ ПОГОВОРИТЬ? ? БУДУ РАДА ИНТЕРЕСНОЙ БЕСЕДЕ ? О ЧЁМ? ? ДАВАЙ ПОГОВОРИМ О
Вариант 3. Три ячейки LSTM, 63 150 параметров
В эксперименте участвуют:
- Слой 1: LSTM с D нейронами на входе и D на выходе;
- Слой 2: LSTM с D нейронами на входе и D на выходе;
- Слой 3: LSTM с D нейронами на входе и D на выходе.
И такой диалог:
? привет ? ПРИВЕТ ? ТЕБЯ КАК ЗОВУТ? ? МЕНЯ ЗОВУТ СЕТЬ ? ПРИВЕТ, СЕТЬ ? ЭТО ТЕБЕ ? ПРИВЕТ, ТЫ МЕНЯ ЗНАЕШЬ? ? Я ТОЛЬКО УЧУСЬ ? ТЕБЯ ЗОВУТ ОЛЕГ? ? МЕНЯ ПОЗНАКОМИТЬСЯ ? ТЕБЯ ЗОВУТ CЕТЬ? ? МЕНЯ ЗОВУТ СЕТЬ ? ТЫ ХОРОШАЯ? ? Я ДУМАЮ В ? ТЕБЕ ЧТО-НИБУДЬ НРАВИТСЯ? ? МНЕ НРАВИТСЯ СЛУШАТЬ МУЗЫКУ ? ХОЧЕШЬ ПОГОВОРИТЬ? ? БУДУ РАДА ИНТЕРЕСНОЙ БЕСЕДЕ ? О ЧЁМ? ? ДАВАЙ БУДЕМ ДРУЗЬЯМИ
Итог
Для тестирования специально выбирались вопросы, которых нет в обучающей базе (кроме первого), чтобы проверить «разумность» построенных моделей. Как мне показалось, рекуррентные сети работают гораздо лучше, на них сильно не сказывается отсутствие некоторых слов в вопросе или порядок слов в предложении (ответ на «Как тебя зовут?», «Как зовут тебя?» одинаков). Конечно, и этот результат всё ещё далёк от «хорошего».
Интересно, что первая модель из трёх наиболее адекватно отвечает на приветствие, её не сбивает собственное имя в предложении. Вместе с тем, она всё же точно не знает, как её зовут. Вторая модель, напротив, на приветствие, отличное от обучаемого, отвечает как угодно ужасно. Но, в отличие от первой модели, попыталась правильно ответить на вопрос о своём имени («Тебя зовут Олег?» ? «Меня зовут»). Хоть в данной реализации не предполагается запоминание контекста диалога и предыдущих ответов, выбор темы разговора в первых двух моделях выглядит адекватнее.
Вывод: Из всей тестовой базы первые модели отвечают адекватно на одну часть вопросов, великолепно проваливая тест на остальной. Другие модели отвечают на вторую часть вопросов и блестяще не справляются с первой. Жаль, что нельзя создать совокупность нейронных сетей, которые бы смогли ответить на все вопросы тестового набора правильно…
Поэтому дальнейшая задача ? исследование влияния типов и количества слоёв ИНС на качество её ответов при неизменных обучающем и тестовом наборах, чтобы сконструировать такую модель нейронной сети, которая пройдёт мой тест.
Комментарии (3)
napa3um
13.03.2017 19:04Для осмысленной беседы (для создания иллюзии сознательности и непрерывности мышления) бота нужно наделить theory of mind, для чего нужен генератор «ментальных моделей» с состояниями, изменяемыми сетью по результату «распознавания» текста, а ответ уже должен генерироваться по «распознаванию» состояния этой модели. При правильном дизайне обучения теоретически возможно обучить бота состояниям типа «хочу сказать об этом» и рефлексивным лингвистическим конструкциям для репрезентации этих состояний.
dmitrybelsky
13.03.2017 21:36Вот как раз статейка на предмет правильной рекуррентной сети для бота
https://arxiv.org/abs/1606.00776
jjdeluxe
Спасибо за статью. Было бы интересно посмотреть на код