GSoC 2018: Функция прямого распространения в сети LSTM - Часть III

Объяснение конструкции уровня LSTM, прямого распространения в сети LSTM и проблем, с которыми пришлось столкнуться.

В моем последнем блоге я обсуждал, как работают сети RNN и LSTM. В этом блоге я кратко объясню, как реализовано прямое распространение в TMVA-DNN. Часть обратного распространения в настоящее время находится в стадии разработки, о чем я расскажу в своем следующем рассказе.

Начнем со структуры ячейки LSTM. На рисунке ниже изображен модуль LSTM с четырьмя взаимодействующими уровнями.

Согласно исследованию Эмпирическое исследование рекуррентных сетевых архитектур: Эти четыре уровня можно разделить на четыре типа шлюзов. Ячейка LSTM имеет 2 состояния: состояние ячейки и состояние вывода. Состояние ячейки помогает бороться с проблемой исчезающего градиента, а с другой стороны, выходное состояние позволяет сети LSTM принимать сложные решения за короткий период времени. Это была одна из проблем, связанных с определением количества состояний, присутствующих в LSTM. Вторая задача заключалась в том, чтобы определить, являются ли матрицы весов и векторы смещения одинаковыми или разными. Статья, о которой я упоминал выше, оказалась весьма полезной. Сеть LSTM обычно имеет 8 различных типов матриц и 3 разных вектора смещения. Следовательно, у нас есть несколько входов, что было довольно сложно реализовать в классе TBasicLSTMLayer. Давайте поговорим о четырех воротах, о которых я упоминал выше.

Первый шаг - сохранить новую информацию в состоянии ячейки. Этот процесс можно разделить на две части. сигмовидный слой, называемый «слоем входного затвора», решает добавить новую информацию, а затем следует слой активации tanh, который создает вектор новых значений кандидатов. Уровень забвения ворот решает, какую информацию нужно выбросить из состояния ячейки. За этим процессом принятия решения следует сигмовидная функция активации, которая выводит число от 0 до 1. Значения, близкие к 0, означают «забыть», а значения, близкие к 1, означают «запомнить». Следующий шаг - обновить состояние ячейки. Значения-кандидаты дополнительно используются для масштабирования и обновления нового состояния ячейки путем вычисления поэлементного умножения матриц (также известного как произведение Адамара) со значениями входных вентилей. Полученный результат подвергается скалярному сложению с поэлементным матричным умножением значений забытых ворот и предыдущего состояния ячейки. Мы умножаем забытые значения ворот на предыдущее состояние ячейки, потому что это помогает забыть вещи, которые мы решили забыть ранее.

Затем, наконец, идет выходной вентиль, который помогает определить выходное значение сети и следующее состояние выхода. За выходным вентилем следует сигмовидная функция активации, и мы вводим новые значения состояния ячейки с помощью функции активации tanh, чтобы вернуть значения между -1 и +1.

Результат подвергается произведению Адамара со значениями выходных вентилей и вычисляет следующее выходное состояние.

Давайте обсудим, как я реализовал функцию прямого распространения внутри класса TBasicLSTMLayer TMVA.

  1. Определены 2 состояния: состояние ячейки и состояние выхода.
  2. Определены 8 весовых матриц и 4 вектора смещения.
  3. Для поддержки кода созданы такие же функции Forward () и CellForward (), аналогичные слою RNN. Работа обеих функций аналогична уровню RNN. Единственная разница в том, что здесь мы имеем дело с несколькими входами и воротами.
  4. Определенная функция для каждого гейта. Каждая вентильная функция вычисляет собственное значение и вызывается внутри функции Forward ().
  5. Следующее состояние ячейки и следующее состояние вывода вычисляются внутри функции CellForward ().
  6. Осталась часть бенчмаркинга (то есть производительности), о которой я расскажу отдельно в другом блоге.

Текущий код LSTM поддерживает архитектуру ЦП. Третья проблема, с которой я столкнулся, была во время компиляции кода. Большинство ошибок были связаны с несовпадением размеров весовых матриц и входных данных, и мне потребовалась 1 неделя, чтобы найти это в моем коде. Архитектура RNN и LSTM была разработана на основе среды Torch.

Четвертой сложной задачей было тестирование кода. Сложность задачи снизилась после прохождения тестов RNN в TMVA и Torch-LSTM. Испытания сейчас проходят успешно. В настоящее время тесты прямого прохода LSTM поддерживают только архитектуру ЦП.

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