Нейронный машинный перевод с применением GPU. Вводный курс. Часть 2

Автор оригинальной публикации: Киунхьюн Чо (Kyunghyun Cho)

В предыдущей статье мы рассмотрели статистический машинный перевод и выяснили, что он может и должен рассматриваться, как машинное обучение с учителем, при котором вход и выход являются последовательностями переменной длины. Чтобы познакомить вас с парадигмой нейронного машинного перевода (НМП, neural machine translation, NMT), половину предыдущей статьи я посвятил рекуррентным нейронным сетям (РНС, recurrent neural network, RNN). В частности, мы рассмотрели две ключевые возможности РНС: (1) обобщение последовательностей и (2) вероятностное моделирование последовательностей. На основе двух этих возможностей в данной статье я подробно объясню вам модель кодер-декодер (encoder-decoder model) для статистического машинного перевода.

Архитектура кодер-декодер

Рисунок 1. Схема модели кодер-декодер

Рисунок 1. Схема модели кодер-декодер

Я не являюсь специалистом в области нейробиологии или когнитивистики, поэтому не могу компетентно говорить о том, как работает мозг. Но если представить себе работу мозга в тот момент, когда я пытаюсь перевести предложение с английского на корейский, можно сказать, что происходит следующее: мой мозг кодирует предложение на английском языке в набор нейронных активаций, а затем из этих активаций декодирует соответствующее предложение на корейском. Другими словами, в процессе (человеческого) перевода участвует кодер, преобразующий последовательность слов в набор нейронных активаций (или импульсов, или каких-либо других явлений, происходящих в мозге), и декодер, генерирующий на основе набора активаций последовательность слов на другом языке (см. рис. 1).

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

Со времени публикации работы Калчбреннера (Kalchbrenner) и Блансома (Blunsom) (Оксфордский университет) в 2013 году, архитектура кодер-декодер была предложена многими научными группами, включая лабораторию машинного обучения Монреальского университета (где я работаю) и компанию Google, как новый подход к статистическому машинному переводу [Kalchbrenner and Blunsom, 2013; Sutskever et al., 2014; Cho et al., 2014; Bahdanau et al., 2015]. (По данной теме также существует более ранняя работа, опубликованная Микелем Форкада (Mikel Forcada) из Университета Аликанте в 1997 году [Forcada and Neco, 1997].) Несмотря на то, что и кодер, и декодер могут быть реализованы на основе любых типов нейронных сетей, мы будем использовать РНС в обоих случаях.

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

Рисунок 2. Наша первая система нейронного машинного перевода

Рисунок 2. Наша первая система нейронного машинного перевода

Кодер

Начнем с кодера, который является прямым приложением рекуррентной нейронной сети, основанным на ее способности обобщать последовательности. Если вы вспомните предыдущую статью, это покажется вам вполне естественным. Вкратце напомню: мы рекурсивно применяем рекуррентную функцию активации к входной последовательности (то есть к входному предложению), пока не получим итоговое внутреннее состояние РНС hT, являющееся обобщением всего входного предложения.

Вначале, каждое слово исходного предложения представляется в виде вектора в прямом унитарном коде (one-hot vector или 1-of-K coded vector), как показано на рисунке 3. Это самое нехитрое представление, которое только можно придумать. Все слова равноудалены друг от друга. То есть никакие взаимосвязи между словами не сохраняются.

Рисунок 3. Шаг 1. Представление слова в виде вектора в прямом унитарном коде.

Рисунок 3. Шаг 1. Представление слова в виде вектора в прямом унитарном коде.

Чтобы получить представление предложения, то есть вектор, обобщающий входное предложение, мы применяем иерархический подход. В этой иерархии первым шагом является получение содержательного представления каждого слова. Но что мы подразумеваем под «содержательным» представлением? Ответ состоит в том, что мы позволяем модели учиться на данных! Этим все сказано.

Кодер линейно проецирует вектор в прямом унитарном коде wi (см. рис. 3) с помощью матрицы E, количество столбцов в которой равно количеству слов в исходном словаре, а количество строк – произвольно (обычно от 100 до 500). Эта проекция si = Ewi, представленная на рисунке 4, дает в результате непрерывный вектор (continuous vector) для каждого исходного слова. Потом каждый элемент вектора обновляется, чтобы максимизировать эффективность перевода. Мы еще вернемся к объяснению этого момента.

Рисунок 4. Шаг 2. Преобразование вектора из прямого унитарного кода в новое представление в непрерывном пространстве

Рисунок 4. Шаг 2. Преобразование вектора из прямого унитарного кода в новое представление в непрерывном пространстве

На данный момент мы уже преобразовали последовательность слов в последовательность непрерывных векторов si. Теперь в игру вступает РНС. В конце предыдущей статьи я сказал, что одной из двух ключевых возможностей РНС является обобщение последовательностей. В данном случае мы будем использовать РНС, чтобы обобщить последовательность непрерывных векторов, соответствующих словам исходного предложения. На рисунке 5 показано, как РНС выполняет эту задачу.

Математически процесс обобщения можно выразить следующим образом:

latex

где h0 – нулевой вектор. То есть после того, как последний непрерывный вектор sT, соответствующий последнему слову, будет прочитан, внутреннее состояние РНС hT будет представлять собой обобщение всего исходного предложения.

Рисунок 5. Шаг 3. Обобщение последовательности с помощью РНС

Рисунок 5. Шаг 3. Обобщение последовательности с помощью РНС

Что собой представляет обобщенный вектор?

Теперь, когда у нас есть обобщенный вектор (summary vector), возникает естественный вопрос: «Как выглядит этот вектор?» Я мог бы долго рассуждать о том, каким должен быть обобщенный вектор, что он означает, и как он, вероятно, связан с обучением представлений (representation learning) и глубоким обучением (deep learning), но, я думаю, одна иллюстрация из публикации [Sutskever et al., 2014] расскажет обо всем в намного более компактной форме (см. рис. 6).

Чтобы визуализировать точки на рисунке 6, авторы публикации обучили систему нейронного машинного перевода на большом параллельном корпусе английского и французского языков. После того, как модель была обучена, на вход кодера было подано несколько предложений на английском, чтобы получить их соответствующие представления, то есть обобщенные векторы hT. (Я думаю, это было сделано, чтобы продемонстрировать удивительные качества их модели!)

К сожалению, люди – трехмерные создания, а наши экраны и бумага могут отображать только двумерные проекции. Поэтому нелегко визуализировать вектор большой размерности, особенно на бумаге. Существует множество методов, позволяющих визуализировать векторы большой размерности в пространстве малой размерности. В данном случае был использован метод главных компонент (principal component analysis, PCA), чтобы спроецировать каждый вектор на двумерное пространство, образованное двумя первыми главными компонентами (ось x и ось y на рис. 6). Благодаря этому мы можем получить общее представление о взаимном положении обобщенных векторов в исходном пространстве. На рисунке 6 мы видим, что обобщенные векторы сохраняют структуру, в том числе семантику и синтаксис (если синтаксис вообще существует). Другими словами, похожие предложения расположены близко друг к другу.

Рисунок 6. Двумерная визуализация представлений предложений из публикации [Sutskever et al., 2014]. Похожие предложения расположены близко друг к другу

Рисунок 6. Двумерная визуализация представлений предложений из публикации [Sutskever et al., 2014]. Похожие предложения расположены близко друг к другу

Декодер

У нас уже есть хорошее представление исходного предложения. Теперь давайте создадим декодер опять же на основе РНС (верхняя половина рисунка 2). Далее мы пошагово рассмотрим этот процесс. Полезно помнить, что декодер – это, по сути, перевернутый кодер.

Рисунок 7. Декодер. Шаг 1. Вычисление скрытого внутреннего состояния декодера

Рисунок 7. Декодер. Шаг 1. Вычисление скрытого внутреннего состояния декодера

Давайте начнем с вычисления внутреннего состояния РНС zi на основе обобщенного вектора исходного предложения hT, предыдущего слова ui-1 и предыдущего внутреннего состояния zi-1. Не волнуйтесь, я расскажу вам, как получить слово. Новое внутренне состояние zi вычисляется по следующей формуле:

latex (1)

Мы подробно рассмотрели φθ’ в предыдущей статье. На рисунке 7 показан процесс вычисления. Получив скрытое внутреннее состояние декодера zi, мы можем оценить каждое целевое слово, на основе того, насколько вероятно его появление после всех предыдущих переведенных слов при данном исходном предложении. Для этого необходимо присвоить вероятность pi каждому слову (рис. 8). Обратите внимание, вероятность отличается от оценки тем, что сумма вероятностей всех возможных слов равна единице, а сумма оценок – нет.

Рисунок 8. Декодер. Шаг 2. Вероятность следующего слова

Рисунок 8. Декодер. Шаг 2. Вероятность следующего слова

Вначале мы вычисляем оценку для каждого слова k на основе скрытого состоянии zi следующим образом:

latex (2)

где wk – вектор целевого слова, а bk – смещение.

Давайте пока забудем про смещение bk и подумаем о первом слагаемом – скалярном произведении двух векторов. Скалярное произведение больше, когда вектор целевого слова wk и внутреннее состояние декодера zi подобны друг другу, и меньше – в обратном случае. Напомню, что результатом скалярного произведения является длина проекции одного вектора на другой. Если векторы подобны (почти параллельны) – проекция длиннее, если не подобны (почти перпендикулярны) – проекция короче. Таким образом, этот механизм присваивает слову высокую оценку, если оно «достаточно параллельно» внутреннему состоянию декодера.

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

latex (3)

Этот тип нормализации называется софтмакс (softmax) [Bridle, 1990].

Теперь у нас есть распределение вероятностей для целевых слов, которое мы можем использовать, чтобы выбрать слово путем семплирования (sampling) распределения (см. здесь), как показано на рисунке 9. Выбрав i-е слово, мы возвращаемся к первому шагу и вычисляем скрытое внутренне состояние декодера (рис. 7), оцениваем и нормализуем целевые слова (рис. 8) и выбираем следующее (i+1)-е слово (рис. 9). Процесс повторяется, пока не будет достигнут конец предложения (<eos>).

Рисунок 9. Декодер. Шаг 3. Отбор следующего слова

Рисунок 9. Декодер. Шаг 3. Отбор следующего слова

Обучение. Метод максимального правдоподобия

Система нейронного машинного перевода готова. Как нам обучить эту систему, чтобы она могла выполнять перевод? Как и в случае с любой другой моделью, нам доступно множество способов обучения. В данном случае мы будем обучать нашу модель посредством максимизации логарифмической функции правдоподобия (log-likelihood). Этот популярный статистический метод называется методом максимального правдоподобия (ММП, maximum likelihood estimation, MLE).

Сначала необходимо подготовить так называемый параллельный корпус D. Каждый элемент корпуса представляет собой пару (Xn, Yn), состоящую из исходного и целевого предложения. Каждое предложение – это последовательность целочисленных индексов, соответствующих словам, которая эквивалентна последовательности векторов в прямом унитарном коде. (Вектор в прямом унитарном коде – это двоичный вектор, один элемент которого равен единице, а все остальные равны нулю. Умножение вектора в прямом унитарном коде на матрицу (слева) эквивалентно выделению i-го столбца матрицы, если i-й элемент вектора равен единице.) Для любой пары из корпуса НМП-модель может вычислить условную лог-вероятность (log-probability) для Yn при данном Xn следующим образом: log P(Yn|Xn, θ). Тогда логарифмическая функция правдоподобия для всего обучающего корпуса будет иметь вид:

latex (4)

где N – количество обучающих пар.

Теперь необходимо максимизировать логарифмическую функцию правдоподобия. Это можно сделать с помощью стохастического градиентного спуска (stochastic gradient descent, SGD).

Градиент логарифмической функции правдоподобия L по всем параметрам может быть вычислен посредством метода обратного распространения ошибки (backpropagation). Для этого необходимо создать обратный граф, начиная с итоговой лог-вероятности на входе, и вычислить производные каждого оператора в прямом вычислительном графе. Не знаю, как вам, но мне этот процесс кажется очень сложным и трудоемким. Вместо того чтобы делать это вручную, мы можем воспользоваться процедурой автоматического дифференцирования из библиотеки Theano, выполнив следующий вызов: theano.tensor.grad(-loglikelihood, parameters). Здесь находится пример, а здесь  – подробная документация.

Когда производная логарифмической функции правдоподобия по каждому параметру будет автоматически вычислена, мы обновляем параметр, чтобы двигаться по этой производной медленно. Нередко эта часть расстраивает многих людей и служит одной из причин, по которым глубокое обучение ошибочно считают черной магией. Я согласен, что поиск хороших параметров обучения (таких как начальный коэффициент скорости обучения (initial learning rate), планирование коэффициента скорости обучения (learning rate scheduling), коэффициент инерции (momentum coefficient), планирование коэффициента инерции (momentum coefficient scheduling) и т.д.) – сложная задача.

Поэтому часто я просто использую один из недавно предложенных алгоритмов с адаптивным коэффициентом скорости обучения (adaptive learning rate). Из многих подобных алгоритмов моими любимыми являются Adadelta [Zeiler, 2012] и Adam [Kingma and Ba, 2015]. Они могут быть легко реализованы с помощью Theano. Если вы не очень хотите читать публикации и заниматься реализацией, тогда вы можете обратиться к документации Theano. Возможно, вам также будет интересно посмотреть на следующие визуализации алгоритмов оптимизации (также на рис. 10). Однако должен вас предупредить, что поведение в пространстве малой размерности не обязательно соответствует поведению в пространстве большей размерности.

Рисунок 10. Поведение алгоритмов с адаптивным коэффициентом скорости обучения в седловой точке. Источник: http://imgur.com/a/Hqolp.

Рисунок 10. Поведение алгоритмов с адаптивным коэффициентом скорости обучения в седловой точке. Источник: http://imgur.com/a/Hqolp.

Почему так важны графические процессоры? Вычислительная сложность НМП-обучения

Можем ли мы обучить НМП-модель на большом параллельном корпусе с помощью ноутбука? К сожалению, нет. Как вы уже могли догадаться, для каждого обновления необходимо большое количество вычислений, а для полного обучения модели, в свою очередь, требуется большое количество SGD-обновлений. Давайте посчитаем, какие вычисления необходимы для одного прохода в прямом направлении:

  1. Векторные представления исходных слов: T × |V| (T исходных слов, |V| уникальных слов).
  2. Исходные векторные представления – кодер: T × ne × (3 × nr) (ne-мерное векторное представление, nr рекуррентных нейронов; два гейта (gate) и один управляемый рекуррентный нейрон (gated recurrent unit, GRU)).
  3. ht-1ht: T × nr × (3 × nr).
  4. Контекстный вектор – декодер: T × nr × (3 × nr).
  5. zt-1zt: T × nr × (3 × nr).
  6. Декодер – векторные представления целевых слов: T‘ × nr × ne (T целевых слов, ne-мерное целевое векторное представление).
  7. Целевые векторные представления – выход: T‘ × ne × |V‘| (|V‘| целевых слов).
  8. Софтмакс-нормализация выхода: T‘ × |V‘|.

Учитывая то, что |V| и |V‘| обычно имеют порядок десятков или сотен тысяч, а ne, ne и nr – порядок сотен или тысяч, общая вычислительная нагрузка является очень существенной. Кроме того, почти такой же объем вычислений требуется для работы алгоритма обратного распространения ошибки, то есть для вычисления градиента логарифмической функции правдоподобия.

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

Таблица 1 дает представление о том, какое количество времени можно сэкономить благодаря GPU. В таблице представлено только время, затрачиваемое на перевод. Когда же речь идет об обучении модели, преимущество от использования GPU становится еще более значительным, согласно приведенной выше оценке вычислительной сложности.

CPU (Intel i7-4820K) GPU (GTX TITAN Black)
РНС-поиск [Bahadanau et al,, 2015] 0.09s 0.02s
Таблица 1. Среднее время декодирования/перевода одного слова. Источник: [Jean et al., 2015]

Могу вас заверить, что этот раздел я написал не в угоду NVIDIA. Для обучения любых реалистичных НМП-моделей нам действительно необходимы хорошие графические процессоры, как минимум, пока не появятся масштабируемые и доступные универсальные квантовые компьютеры!

Что пройдено, и что дальше

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

На основе этой базовой модели в следующей статье я расскажу, как можно значительно повысить эффективность нейронного машинного перевода за счет внедрения в модель механизма внимания (attention mechanism). Более того, я покажу вам, как с помощью НМП можно «переводить» изображения и даже видеоматериалы в их описания!

По материалам: Nvidia

Перевод Станислава Петренко

Добавить комментарий

Ваш e-mail не будет опубликован.

закрыть

Поделиться

Отправить на почту
закрыть

Вход

закрыть

Регистрация

+ =