tl; доктор: Переводить последовательности произвольной длины вперед и назад проще, чем вы думаете

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

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

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

Давайте начнем с рассмотрения одной из проблем, которые привели к seq2seq, - автоматического перевода. Предположим, вы хотите перевести слова с одного языка (скажем, английского) на другой язык (скажем, немецкий). Очевидно, вы не можете просто сопоставить токен слова с токеном слова; некоторые токены исчезают при переводе, другие появляются из ниоткуда, некоторые сильно зависят от контекста токенов вокруг них, а некоторые токены сходятся или расходятся, как мой личный фаворит: « Rechtsschutzversicherungsgesellschaften » (или, по-английски, страховые компании, обеспечивающие правовую защиту). Такие простые примеры, как этот, демонстрируют, что перевод - это не функция на уровне токена.

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

Теперь, когда мы определились с переводом на уровне предложений в качестве задачи, мы должны спросить себя - как мы можем возможно смоделировать это с помощью глубокого обучения? Какую бы архитектуру вы ни выбрали (прямая или повторяющаяся, глубокая или мелкая и т. Д.), Вам все равно нужно выбрать размер входного слоя, размер выходного слоя и всего оборудования внутри. Но предложения бывают разной длины! Вы строите разные сети для каждой длины (скажем, одну сеть, которая переводит все предложения из 12 слов на английском языке в предложения из 8 слов на немецком языке и т. д. на)? Это кажется абсурдным, и это так. Не делай этого.

Seq2Seq решает эту проблему аналогично тому, как обратное распространение во времени решает задачу обучения циклических сетей. С помощью BPTT мы взяли временную самореферентную сеть и изменили ее на пространственную несамореферентную сеть. Здесь с помощью seq2seq мы переосмысливаем пространственную проблему (последовательность токенов переменной длины) как временную (токены, генерируемые с течением времени). По сути, мы запихиваем некоторое количество клоунов в машину (input переменной длины), затем вытаскиваем другую последовательность клоунов обратно, пока не получим маркер, указывающий, что мы закончили (переменная длина вывод).

Давайте посмотрим на схему всего процесса слева направо (адаптировано из Суцкевер, 2014 и Чо, 2014):

По сути, у нас есть две разные рекуррентные нейронные сети, связанные здесь: кодировщик RNN (нижние левые поля) слушает входные токены, пока не получит специальный токен ‹DONE›, а затем декодер RNN (верхние правые поля) вступает во владение и начинает генерировать токены, также заканчивая собственным токеном ‹DONE›.

RNN кодировщика развивает свое внутреннее состояние (отображаемое изменением светло-голубого на темно-синий, когда появляются английские токены предложений), а затем, когда поступает токен ‹DONE›, мы принимаем окончательное состояние кодировщика ( темно-синее поле) и передать его без изменений и многократно в декодер RNN вместе с каждым сгенерированным немецким токеном. RNN декодера также имеет собственное динамическое внутреннее состояние, изменяющееся от светло-красного до темно-красного.

Вуаля! Вход переменной длины, выход переменной длины, из архитектуры фиксированного размера.

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

и возможность генерировать последовательность токенов, например «человек, едущий на мотоцикле по грунтовой дороге»?

Все, что нам нужно сделать, это заменить кодировочную часть пары кодер / декодер на тип сверточной нейронной сети (CNN), который обычно используется при обработке изображений в качестве альтернативного кодировщика, а затем выполнить то же декодирование на основе токенов, которое мы сделали. выше. CNN кодирует изображение в некоторый тензор скрытого состояния, а затем декодер использует это состояние в качестве внутреннего представления для описания.

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

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