www.machinelearningmastery.ru

Машинное обучение, нейронные сети, искусственный интеллект
Header decor

Home

Глубокое обучение для НЛП: создание Chatbot с Keras!

Дата публикации Jul 17, 2019

В предыдущем посте мы узнали, чтоИскусственные нейронные сети и глубокое обучениеявляются. Кроме того, были представлены некоторые структуры нейронной сети для использования последовательных данных, таких как текст или аудио. Если вы не читали этот пост, вам следует сесть, выпить кофе и понемногу наслаждаться им.Можно найтиВот,

Этот новый пост будет охватыватькак использовать Kerasочень популярная библиотека для нейронных сетей для создания Chatbot. Основные понятия этой библиотеки будут объяснены, а затем мы рассмотрим пошаговое руководство о том, как использовать ее для создания да / нетотвечая бот в Python, Мы будем использовать простую природу Keras для реализации структуры RNN из статьи «Сквозные сети памятиSukbaatar и др. (Которые вы можете найтиВот).

Это интересно, поскольку определив задачу или приложение (создав чат-бота «да / нет» для ответа на конкретные вопросы), мы узнаем, какчтобы перевести идеи исследовательской работы на реальную модельчто мы можем затем использовать для достижения наших целей приложения.

Не пугайтесь, если это ваш первый разреализация модели НЛП; Я пройдусь по каждому шагу и поставлю ссылку на код в конце. Длялучший опыт обученияЯ предлагаю вам сначала прочитать пост, а затем просмотреть код, взглянув на разделы поста, которые сопровождают его.

Тогда доберемся до него!

Keras: простые нейронные сети в Python

Керас этос открытым исходным кодом, библиотека высокого уровнядля разработки моделей нейронных сетей. Он был разработан Франсуа Шоле, исследователем глубокого обучения из Google. Основной принцип состоит в том, чтобы сделать процесс построения нейронной сети, обучить ее, а затем использовать ее для прогнозирования,легко и доступно для всех, кто обладает базовыми знаниями в области программирования, в то же время позволяя разработчикам полностью настраивать параметры ANN.

По сути, Keras - это просто интерфейс, который может работать поверх различных сред глубокого обучения, таких какCNTK, Tensorflow или Theanoнапример. Он работает одинаково, независимо от того, какой сервер используется.

Многоуровневая структура API Keras. Как видно, он может беспрепятственно работать на разных платформах.

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

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

шаги для создания модели Kerasявляются следующие:

Шаг 1:Сначала мы должны определить модель сети, которая в большинстве случаев будетSтретьих, последовательноемодель:сеть будет определена как последовательность слоев, каждый со своим настраиваемым размером и функцией активации. В этих моделях первый слой будетвходной слой, что требует от нас определить размер входных данных, которые мы будем подавать в сеть. После этого можно добавлять и настраивать все больше и больше слоев, пока мы не достигнем конечного выходного слоя.

#Define Sequential Model
model = Sequential()
#Create input layer
model.add(Dense(32, input_dim=784))
#Create hidden layer
model.add(Activation('relu'))
#Create Output layer
model.add(Activation('sigmoid'))

Шаг 2:После создания структуры сети таким образом, мы должныскомпилируйте это, который преобразует простую последовательность слоев, которую мы ранее определили, в сложную группу матричных операций, которые определяют поведение сети. Здесь мы должны определить алгоритм оптимизации, который будет использоваться для обучения сети, а также выбрать функцию потерь, которая будет минимизирована.

#Compiling the model with a mean squared error loss and RMSProp #optimizer
model.compile(optimizer='rmsprop',loss='mse')

Шаг 3:Как только это будет сделано, мы можемпоездилипоместитьсясеть, которая сделана с использованием алгоритма обратного распространения, упомянутого в предыдущем посте.

# Train the model, iterating on the data in batches of 32 samples model.fit(data, labels, epochs=10, batch_size=32)

Шаг 4:Ура! Наша сеть обучена. Теперь мы можем использовать его для прогнозирования новых данных.

Как вы видете,довольно легко построить сеть, используя Keras,так что давайте перейдем к нему и используем его для создания нашего чат-бота! Блоки кода, использованные выше, не являются репрезентативными для конкретной конкретной модели нейронной сети, они являются лишь примерами каждого из шагов, чтобы помочь продемонстрировать, насколько просто построить нейронную сеть с использованием API Keras.

Вы можете найти всю документацию о Keras и как установить его в егоофициальная веб-страница,

Проект: Использование рекуррентных нейронных сетей для создания чат-бота

Теперь мы знаем, что представляют собой все эти разные типы нейронных сетей, давайте использовать их дляпостроить чат-боЭто может ответить на некоторые вопросы для нас!

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

В этом посте мы рассмотрим пример второго случая ипостроить нейронную модель из бумаги «Сквозные сети памяти»Сухбаатар и др. (которые вы можете найтиВот).

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

Модель: Вдохновение

Как упоминалось ранее, RNN, использованный в этом посте, был взят из статьи.«Сквозные сети памяти», поэтому я рекомендую вам взглянуть на это, прежде чем продолжить, хотя я объясню наиболее важные части в следующих строках.

Эта статья реализует RNN-подобную структуру, которая используетмодель вниманиячтобы компенсировать проблему долговременной памяти о RNNs, которую мы обсуждали в предыдущем посте.

Не знаете, что такое модель внимания?Не волнуйтесьЯ объясню вам в простых терминах. Модели внимания привлекли большой интерес из-за их очень хороших результатов в таких задачах, какмашинный перевод, Они решают проблемудлинные последовательностии кратковременная память RNNs, которая была упомянута ранее.

Чтобы собратьинтуицияо том, что внимание, подумайте о том, какчеловек будет переводитьдлинное предложение с одного языка на другой.Вместоприниматьwhooooooleпредложение, а затем переводя его за один раз, вы бы разбили предложение на более мелкие куски и перевели эти меньшие кусочки один за другим. Мы работаем по частям с предложением, потому чтоэто действительно трудно запомнить полностьюа затем перевести его сразу.

Как человек переведет текст сверху с английского на испанский

Механизм внимания делает именно это. На каждом временном шаге, тмодель дает больший весв выводе на те части входного предложения, которые более соответствуют задаче, которую мы пытаемся выполнить. Отсюда и название:Этоиграет вниманиек тому, что важнее, Приведенный выше пример очень хорошо иллюстрирует это; чтобы перевести первую часть предложения, не имеет смысла смотреть на все предложение или на последнюю часть предложения.

На следующем рисунке показанапроизводительность моделей RNN vs Attention при увеличении длины входного предложения, Столкнувшись с очень длинным предложением и попросив выполнить определенное задание, RNN после обработки всего предложения, вероятно, забудет о первых входных данных, которые он имел.

Производительность против длины предложения для RNN и моделей внимания.

Хорошо, теперь, когда мы знаем, что такое модель внимания, давайте побольше посмотрим на структуру модели, которую мы будем использовать. Эта модель занимаетвходXI(предложение),запросQо таком предложении и выводит да / нетответ,

Слева (а) представление одного слоя модели. Справа (б) 3 из этих слоев сложены вместе.

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

A вложениями, затем вычисляются с использованием внутреннего произведения с вложением вопросаU(это та часть, гдевнимание происходит, как вычисляявнутренний продуктмежду этими вложениями то, что мы делаем, ищетсовпадения слов из запроса и предложения, чтобы затем придать большее значение этим матчам, используяСофтмаксфункция на результирующих слагаемых точечного произведения).

Наконец, мы вычисляем выходной вектороиспользуя вложения из C(CI)и веса или вероятностичисло Пиполученный из точечного произведения. С этим выходным векторомоВесовая матрицаWи вложение вопросаU, мы можем, наконец, рассчитать предсказанный ответшляпа,

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

Не беспокойтесь, если все это произойдет слишком быстро, надеюсь, вы получите лучшее и полное понимание, когда мы пройдем различные этапыреализовать эту модель в Python,

Данные: истории, вопросы и ответы

В 2015 году Facebook придумалинабор данных bAbIи 20 заданий для проверки понимания текста и обоснования в проекте bAbI.Задачи подробно описаны в статьеВот,

Цель каждой задачи -оспаривать уникальный аспект деятельности, связанной с машинным текстом, тестирование различных возможностей моделей обучения В этом посте мы столкнемся с одной из этих задач, а именно:QA с одним подтверждающим фактом».

Блок ниже показывает пример ожидаемого поведения от этого вида бота QA:

FACT: Sandra went back to the hallway. Sandra moved to the office.  QUESTION: Is Sandra in the office?ANSWER: yes

Набор данных уже разделен наданные обучения (10 тыс. экземпляров)а такжетестовые данные (1 тыс. экземпляров)где каждый экземпляр имеетфакт,вопроси да / нетответна этот вопрос.

Теперь, когда мы увидели структуру наших данных, нам нужнопостроить словарный запасиз этого. НаОбработка естественного языкамоделировать словарный запас в основномнабор словчто модель знает и, следовательно, может понять. Если после построения словаря модель видит внутри предложения слово, которого нет в словаре, она либо присвоит ему значение 0 в своих векторах предложений, либо представит его как неизвестное.

VOCABULARY:
'.', '?', 'Daniel', 'Is', 'John', 'Mary', 'Sandra', 'apple','back','bathroom', 'bedroom', 'discarded', 'down','dropped','football', 'garden', 'got', 'grabbed', 'hallway','in', 'journeyed', 'kitchen', 'left', 'milk', 'moved','no', 'office', 'picked', 'put', 'the', 'there', 'to','took', 'travelled', 'up', 'went', 'yes'

Как наштренировочные данные не очень разнообразны(большинство вопросов используют одни и те же глаголы и существительные, но с разными комбинациями), наш словарный запас не очень большой, но впроекты НЛП среднего размерасловарный запас может быть очень большим.

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

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

Есть много способов векторизации наших предложений, таких какМешок словмодели илиTf-Idfоднако для простоты мы будем просто использовать технику векторизации индексирования, в которой каждому слову в словаре присваивается уникальный индекс от 1 до длины словаря.

VECTORIZATION INDEX:
'the': 1, 'bedroom': 2, 'bathroom': 3, 'took': 4, 'no': 5, 'hallway': 6, '.': 7, 'went': 8, 'is': 9, 'picked': 10, 'yes': 11, 'journeyed': 12, 'back': 13, 'down': 14, 'discarded': 15, 'office': 16, 'football': 17, 'daniel': 18, 'travelled': 19, 'mary': 20, 'sandra': 21, 'up': 22, 'dropped': 23, 'to': 24, '?': 25, 'milk': 26, 'got': 27, 'in': 28, 'there': 29, 'moved': 30, 'garden': 31, 'apple': 32, 'grabbed': 33, 'kitchen': 34, 'put': 35, 'left': 36, 'john': 37}

Примите во внимание, что эта векторизация выполняется с использованием случайного начального числа, поэтому даже если вы используете те же данные, что и я,вы можете получить разные индексы для каждого слова, Не волнуйся; это не повлияет на результаты проекта. Кроме того, слова в нашем словаре были в верхнем и нижнем регистре; при выполнении этой векторизации все слова получаютстрочнымидля единообразия.

После этого,из-за того, как работает Керасмынужно дополнитьпредложения. Что это значит? Это означает, что нам нужно найти длину самого длинного предложения, преобразовать каждое предложение в вектор этой длины и заполнить разрыв между количеством слов в каждом предложении и количеством слов в самых длинных предложениях с нулями.

После этого случайное предложение набора данных должно выглядеть следующим образом:

FIRST TRAINING SENTENCE VECTORIZED AND PADDED:
array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 20, 30, 24, 1, 3, 7, 21, 12, 24, 1, 2, 7])

Как мы видим, он имеет нули везде, кроме конца (это предложение было намного короче самого длинного предложения), где у него есть несколько цифр. Что это за цифры? Ну, это индексы, представляющие разные слова предложения: 20 - индекс, представляющий словоМэри,30являетсяпереехал,24 этов1 является3 представляетваннаяи так далее. Фактическое предложение:

FIRST TRAINING SENTENCE: 
"Mary moved to the bathroom . Sandra journeyed to the bedroom ."

Хорошо, теперь, когда мы подготовили данные, мы готовы построить нашу нейронную сеть!

Нейронная сеть: построение модели

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

#Example of a Placeholder
question = Input((max_question_len,batch_size))

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

Теперь мы должны создатьвложенияупоминается в статье,А, С и Б.Вложение превращает целое число (в данном случае индекс слова) вdмерный вектор, гдеконтекст принимается во внимание, Слова вложенияшироко используется в НЛПи является одним из методов, которые сделали так много прогресса в последние годы.

#Create input encoder A:
input_encoder_m = Sequential()
input_encoder_m.add(Embedding(input_dim=vocab_len,output_dim = 64))
input_encoder_m.add(Dropout(0.3))#Outputs: (Samples, story_maxlen,embedding_dim) -- Gives a list of #the lenght of the samples where each item has the
#lenght of the max story lenght and every word is embedded in the embbeding dimension

Приведенный выше код является примером одного из вложений, выполненных в статье (A embedding). Как всегда вKerasСначала мы определяем модель (Sequential), а затем добавляем слой внедрения и выпадающий слой, что снижает вероятность перестройки модели, вызывая отключение узлов сети.

После того как мы создали два вложения для входных предложений и вложения для вопросов, мы можем приступить к определению операций, которые происходят в нашей модели. Как упоминалось ранее, мы рассчитываем внимание, выполняяскалярное произведениемежду встраиванием вопросов и одним из встраиваний в истории, а затем делать софтмакс. Следующий блок показывает, как это делается:

match = dot([input_encoded_m,question_encoded], axes = (2,2))
match = Activation('softmax')(match)

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

response = add([match,input_encoded_c])
response = Permute((2,1))(response)
answer = concatenate([response, question_encoded])

Наконец, как только это будет сделано, мы добавим остальные слои модели, добавивLSTMслой (вместо RNN, как в статье), выпадающий слой и окончательный softmax для вычисления результата.

answer = LSTM(32)(answer)
answer = Dropout(0.5)(answer)
#Output layer:
answer = Dense(vocab_len)(answer)
#Output shape: (Samples, Vocab_size) #Yes or no and all 0s
answer = Activation('softmax')(answer)

Обратите внимание, что здесь выводится вектор размера словаря (то есть длины числа слов, известных модели), где все позиции должны быть нулевыми, кроме позиций в индексах'да и нет'.

Изучение данных: обучение модели

Теперь мы готовы скомпилировать модель и обучить ее!

model = Model([input_sequence,question], answer)
model.compile(optimizer='rmsprop', loss = 'categorical_crossentropy', metrics = ['accuracy'])

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

Теперь этовремя тренировать модельздесь мы должны определитьвклад в обучение(входные истории, вопросы и ответы),размер партиичто мы будем кормить модель (то есть, сколько входов одновременно), иколичество эпохдля чего мы будем тренировать модель (то есть, сколько раз модель будет проходить через обучающие данные для обновления весов). Я использовал 1000 эпох и получил точность 98%, но даже при 100–200 эпохах вы должны получить довольно неплохие результаты.

Обратите внимание, что в зависимости от вашего оборудования, это обучение может занять некоторое время. Просто расслабься, откинься назад,продолжайте читать среднийи ждать, пока это не будет сделано.

После того, как он закончил тренировку, вас могут удивить«Мне придется ждать так долго каждый раз, когда я хочу использовать модель?»очевидный ответ, мой друг,НЕТ, Keras позволяет разработчикамсохранить определенную модельон обучен, с весами и всеми конфигурациями. Следующий блок кода показывает, как это делается.

filename = 'medium_chatbot_1000_epochs.h5'
model.save(filename)

Теперь, когда мы хотим использовать модель так же просто, какпогрузкаэто так

model.load_weights('medium_chatbot_1000_epochs.h5')

Классно классно. Теперь, когда мы обучили нашу модель, давайте посмотрим, как она работает с новыми данными, ииграть немного с этим!

Видя результаты: Тестирование и игра

Давайте посмотрим, как наша модель работает на тестовых данных!

pred_results = model.predict(([inputs_test,questions_test]))

Эти результатымассивКак упоминалось ранее, в каждой позиции содержатся вероятности того, что каждое из слов в словаре является ответом на вопрос. Если мы посмотрим на первый элемент этого массива, мы увидим вектор размеромсловарьгде все времена близки к 0, кроме тех, которые соответствуютДа или нет,

Из них, если мы выбереминдекс наибольшего значения массиваа затем посмотреть, какому слову это соответствует, мы должнывыяснить, если ответутвердительно или отрицательно.

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

my_story = 'Sandra picked up the milk . Mary travelled left . '
my_story.split()
my_question = 'Sandra got the milk ?'
my_question.split()

Я создал историю и вопрос как-топохоже на то, что наш маленький бот видел раньшеи после адаптации его к формату, который нейронная сеть хочет, чтобы бот ответил ‘ДА»(В нижнем регистре он не такой восторженный, как я).

Давайте попробуем что-то другое:

my_story = 'Medium is cool . Jaime really likes it. '
my_story.split()
my_question = 'Does Jaime like Medium ?'
my_question.split()

Ответ на этот раз был: ‘Конечно, кто нет?»

Шучу, я не пробовал эту комбинацию история / вопрос, так как многие слова включеныне в словаренашего маленького автоответчика. Кроме того, он знает только, как сказать «да» и «нет», и обычно не дает никаких других ответов.Однако при наличии большего количества обучающих данных и некоторых обходных путей это может быть легко достигнуто.

Вот и все на сегодня! Я надеюсь, что вы, ребята, любили читать пост так же, как мне понравилось его писать Хорошего дня, берегите себя и наслаждайтесь искусственным интеллектом!

Вы можете найти код и данные на моемGithubстр.

Другие источники:

Если вы хотите углубиться в модели внимания или понять некоторые методы векторизации слов, которые я упомянул, ознакомьтесь с этими дополнительными ресурсами, которые я собрал для вас. Наслаждайтесь!

Руководство для начинающих по механизмам внимания и сетям памяти

Эндрю Нг видео с интуицией к вниманию моделей.

Руководство для начинающих по Tf-Idf и Bag of Words,

Keras руководство по созданию этой же модели.

Не стесняйтесь связаться со мной наLinkedInили следуйте за мной в Твиттере на @jaimezorno. Кроме того, вы можете взглянуть на мои другие посты по науке о данных и машинного обученияВот,Приятного чтения!

Оригинальная статья

Footer decor

© www.machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map