К научным трудам

Источник: Cборник материалов X научной конференции молодых ученых «Presenting academic achievements to the world». — 2020. — Т. 9. — С. 124-132.


УДК 004.8

ИСПОЛЬЗОВАНИЕ РЕКУРРЕНТНЫХ НЕЙРОННЫХ СЕТЕЙ ДЛЯ АНАЛИЗА ТЕКСТОВ

Д. П. Суровягин

Саратовский национальный исследовательский государственный университет имени Н. Г. Чернышевского

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

Аннотация

В докладе рассматривается использование нейронных сетей при работе с текстами. Текст – это один из самых распространенных способов представления данных. Он может пониматься как последовательность символов или как последовательность слов. Глубокое обучение для обработки естественного языка – это распознавание образов применительно к словам и предложениям, во многом так же, как компьютерное зрение – это распознавание образов применительно к пикселям. Рекуррентная нейронная сеть (RNN) обрабатывает последовательности, перебирая её элементы и поддерживая состояние, содержащее информацию относительно того, что она видела до сих пор. Другими словами, RNN – это тип нейронной сети, которая имеет внутренний цикл. Когда у вас есть данные, в которых временной или семантический порядок имеет значение, рекуррентные сети отлично подходят для их обработки и легко превосходят другие модели глубокого обучения.

Введение

Текст - это одна из наиболее распространенных форм последовательных данных. Его можно понимать как последовательность символов или слов. Модели обработки последовательностей для глубокого обучения могут использовать текст для создания базовой формы понимания на естественном языке (Jurafsky et al., 2018, с. 102-121). Конечно, ни одна из этих моделей глубокого обучения на самом деле не понимает текст в человеческом понимании; скорее, эти модели могут отображать статистическую структуру письменного языка, чего достаточно для решения многих простых текстовых задач. Глубокое обучение для обработки данных на естественном языке - это распознавание образов, применяемое к словам, предложениям и абзацам, во многом аналогично тому, как компьютерное зрение распознает образы, применяемые к пикселям.

Применение алгоритмов глубокого обучения включает в себя следующее:

Модели глубокого обучения не используют исходные тексты в качестве входных данных — они работают только с числовыми тензорами. Тензор — это контейнер для данных (почти всегда числовых). Тензор, содержащий только одно число, называется скаляром. Массив чисел называется вектором, или одномерным тензором. Массив векторов — это матрица, или двумерный тензор. Если вы соберете такие матрицы в новый массив, то получите трехмерный тензор, который вы можете визуально интерпретировать как куб чисел [4].

Векторизация текста - это процесс преобразования текста в числовые тензоры. Это можно сделать несколькими способами:

N-граммы — это перекрывающиеся группы из нескольких последовательных слов или символов. В совокупности различные единицы, на которые вы можете разбить текст (например, слова, символы или n-граммы), называются токенами, а разбиение текста на такие токены называется токенизацией [6]. Все процессы векторизации текста состоят из применения некоторой схемы токенизации и последующего сопоставления числовых векторов с сгенерированными токенами. Эти векторы, упакованные в тензоры последовательностей, передаются в глубокие нейронные сети.

Основной характеристикой таких нейронных сетей, как сети с плотной связью и сверточные сети, является то, что они не имеют памяти. Каждый вводимый сигнал обрабатывается независимо, без сохранения состояния между входами. В таких сетях, чтобы обработать последовательность или временной ряд точек данных, вы должны показать сети всю последовательность сразу: превратить её в единую точку данных [4].

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

Рекуррентная нейронная сеть (RNN) использует тот же принцип: она обрабатывает последовательности, перебирая элементы последовательности и поддерживая состояние, содержащее информацию относительно того, что она видела до сих пор. По сути, RNN — это тип нейронной сети с внутренним циклом (см. рис. 1). Состояние RNN сбрасывается между обработками двух разных независимых последовательностей, поэтому вы по-прежнему рассматриваете одну последовательность как единую точку данных. Что изменилось, так это то, что эта точка данных больше не обрабатывается за один шаг; скорее, сеть имеет внутреннюю петлю над сетью: сеть с элементами циклической последовательности [1].

Рекуррентная сеть
Рисунок 1 – Рекуррентная сеть

Чтобы прояснить эти понятия цикла и состояния, давайте реализуем прямой проход игрушечного RNN. Этот RNN принимает последовательность векторов в качестве входных данных, которые вы будете кодировать как двумерный тензор размера (временные интервалы, input_features). Он выполняет цикл по временным интервалам, и на каждом временном интервале он рассматривает свое текущее состояние в момент t и входные данные в момент t и объединяет их для получения выходных данных в момент t. Затем вы зададите состояние для следующего шага, которое будет соответствовать предыдущему выходу. Для первого временного шага предыдущий выходной сигнал не определен; следовательно, текущее состояние отсутствует. Итак, вы будете инициализировать состояние в виде нулевого вектора, называемого начальным состоянием сети. В псевдокоде это RNN (см. рис. 2).

Псевдокод РНН
Рисунок 2 – Псевдокод РНН

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

Каким бы простым ни был RNN, у него есть серьезная проблема – хотя теоретически он должен быть способен сохранять информацию о входных данных, которые были замечены за много временных шагов до момента времени t, на практике такие долгосрочные зависимости невозможно изучить. Это связано с проблемой исчезающего градиента, эффектом, который аналогичен тому, что наблюдается в неповторяющихся сетях (сетях с прямой связью), которые находятся на много уровней глубже: по мере того, как вы продолжаете добавлять слои к сети, сеть в конечном итоге становится необучаемой. Теоретические причины этого эффекта были изучены Хохрайтером, Шмидхубером и Бенгио в начале 1990-х годов [2].

Слои LSTM и GRU предназначены для решения этой проблемы. Давайте рассмотрим слой LSTM. Лежащий в основе алгоритма долговременной кратковременной памяти (LSTM) был разработан Хохрайтером и Шмидхубером в 1997 году; это стало кульминацией их исследований проблемы исчезающего градиента [5].

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

К простому слою RNN будет добавлен дополнительный поток данных, который переносит информацию по временным интервалам. Назовите его значения на разных временных интервалах Ct, где C означает «перенос». Эта информация окажет следующее влияние на ячейку: она будет объединена с входным соединением и рекуррентным соединением и повлияет на состояние, передаваемое на следующий временной шаг. Концептуально, перенос потока данных - это способ модулировать следующий вывод и следующее состояние (см. рис. 3).

Структура LSTM
Рисунок 3 – Структура LSTM

Если вы хотите пофилософствовать, вы можете интерпретировать, для чего предназначена каждая из этих операций. Например, вы можете сказать, что умножение c_t и f_t - это способ намеренно забыть ненужную информацию в потоке передаваемых данных. Тем временем i_t и k_t предоставляют информацию о настоящем, обновляя дорожку переноса новой информацией.

Но, в конечном счете, эти интерпретации мало что значат, потому что то, что на самом деле делают эти операции, определяется содержимым параметрирующих их весов. Спецификация ячейки RNN определяет ваше пространство гипотез – пространство, в котором вы ищете хорошую конфигурацию модели во время обучения. Но это не определяет, что делает ячейка, это зависит от веса ячейки [1].

Одна и та же ячейка с разными весами может выполнять совершенно разные действия. Таким образом, комбинацию операций, составляющих ячейку RNN, лучше интерпретировать как набор ограничений для вашего поиска, а не как проект в инженерном смысле. Исследователю кажется, что выбор таких ограничений – вопрос о том, как реализовать ячейки RNN, – лучше оставить алгоритмам оптимизации (таким как генетические алгоритмы или процессы обучения с подкреплением), чем инженерам-людям. И в будущем именно так мы будем строить сети [7].

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

Увеличение пропускной способности сети обычно достигается за счет увеличения количества блоков в слоях или добавления большего количества слоев. Как правило, рекомендуется увеличивать пропускную способность вашей сети до тех пор, пока перегрузка не станет основным препятствием (при условии, что вы уже предпринимаете основные шаги по снижению перегрузки, например, используете dropout). Объединение рекуррентных слоев - классический способ создания более мощных рекуррентных сетей: например, в настоящее время алгоритм Google Translate использует набор из семи больших слоев LSTM.

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

RNN, в частности, зависят от порядка или времени: они обрабатывают временные интервалы своих входных последовательностей по порядку, и перетасовка или изменение временных интервалов может полностью изменить представления, которые RNN извлекает из последовательности. Именно по этой причине они хорошо справляются с задачами, в которых важен порядок, такими как задача прогнозирования температуры. Двунаправленная RNN использует чувствительность RNN к порядку: она заключается в использовании двух обычных RNN, таких как слои LSTM, каждый из которых обрабатывает входную последовательность в одном направлении (хронологическом и антихронологическом), а затем объединяет их представления. Обрабатывая последовательность в обоих направлениях, двунаправленный RNN может улавливать закономерности, которые могут быть пропущены однонаправленным RNN [4].

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

В машинном обучении всегда стоит использовать различные, но полезные представления, и чем больше они отличаются, тем лучше: они позволяют по-новому взглянуть на ваши данные, фиксируя аспекты, которые были упущены при других подходах, и, таким образом, могут помочь повысить производительность при выполнении задачи. Двунаправленный RNN использует эту идею для улучшения производительности RNN в хронологическом порядке. Он рассматривает входную последовательность в обоих направлениях (см. рис. 4), получая потенциально более богатые представления и фиксируя закономерности, которые могли быть упущены только в версии с хронологическим порядком.

Двунаправленная RNN
Рисунок 4 – Схема двунаправленного слоя РНН

Выводы

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

Многослойные сети RNN обеспечивают большую репрезентативность, чем один слой RNN. Они также намного дороже и, следовательно, не всегда стоят того. Если глобальное упорядочение не имеет фундаментального значения, то одномерная сверточная сеть будет работать, по крайней мере, не хуже и дешевле. Это часто относится к текстовым данным, где ключевое слово, найденное в начале предложения, имеет такой же смысл, как и ключевое слово, найденное в конце.

Двунаправленные RNN, которые рассматривают последовательность в обоих направлениях, полезны при обработке данных на естественном языке. Но они не очень эффективны при обработке данных последовательности, где недавнее прошлое гораздо более информативно, чем начало последовательности.

Список литературы

  1. Николенко С., Кадурин А., Архангельская Е. Глубокое обучение: Погружение в мир нейронных сетей. Спб.: Питер, 2019. 480 с.
  2. Bengio, Yoshua et al. «Learning Long-Term Dependencies with Gradient Descent Is Difficult». In: IEEE Transactions on Neural Networks 5, no. 2, 1994. pp. 1–35.
  3. Brink, Henrik & Richards, Joseph W. Real-World Machine Learning. Manning Publications Co., 2017. 242 pp.
  4. Chollet, François. Deep Learning with Python. Manning Publications Co., 2018. 362 pp.
  5. Hochreiter, Sepp & Schmidhuber, Jürgen. «Long Short-Term Memory». In: Neural Computation, Vol. 9, no. 8, 1997. pp. 1735–80.
  6. Jurafsky, Daniel & Martin, James H. Speech and Language Processing. 3rd ed. draft. 2018. URL: https://web.stanford.edu/~jurafsky/slp3/ (дата обращения: 03.04.2020).
  7. Schmidhüber, Jürgen. «Deep learning in neural networks: An overview». In: Neural Networks, no. 61, 2015. pp. 85–117.