Вступление
Прочитав множество теоретических статей о повторяющихся слоях, я просто хотел построить свою первую модель LSTM и обучить ее на некоторых текстах! Но огромный список выставленных параметров для слоя и тонкости слоистых структур были для меня слишком сложными. Это означало, что мне пришлось потратить много времени на изучение определений StackOverflow и API, чтобы получить более четкую картину. Эта статья представляет собой попытку обобщить все заметки, которые могут ускорить процесс перехода от теории к практике. Цель этого руководства - развить практическое понимание использования повторяющихся слоев, таких как RNN и LSTM, а не дать теоретическое понимание. Для более глубокого понимания я предлагаю это и это, которые я рекомендую пройти перед чтением этой статьи. Если вы готовы, приступим!
Рекуррентная нейронная сеть
Полный уровень RNN представлен в Keras как SimpleRNN
класс. В отличие от архитектуры, предложенной во многих статьях, реализация Keras отличается, но проста. Каждая ячейка RNN принимает один ввод данных и одно скрытое состояние, которое передается от одноразового шага к следующему. Ячейка РНС выглядит следующим образом:
Полная формулировка ячейки RNN:
здесь h {t} и h {t-1} - это скрытые состояния с момента времени t и t-1. x {t} - это вход во время t, а y {t} - это выход во время t. Важно отметить, что есть две весовые матрицы W {hh} и W {hx} и один член смещения b {h}. Каждую из этих матриц можно рассматривать как внутреннюю однослойную нейронную сеть с размером вывода, как определено в параметре units
, также смещение имеет такой же размер. y {t} является необработанным h {t}, и мы не применяем здесь другую весовую матрицу, как это предлагается во многих статьях. Это представляет одну отдельную ячейку RNN, и последовательная комбинация ячеек (количество, равное временным шагам в данных) создает полный уровень RNN. Помните, что одни и те же матрицы весов и смещения используются для всех ячеек RNN. Наконец, мы можем вычислить количество параметров, необходимых для обучения слоя RNN, следующим образом:
Обратите внимание, что входные данные представляют собой кортеж в формате (временные шаги, функции) и что параметры зависят только от функций, поскольку мы разделяем одни и те же веса для каждого временного шага. Это можно проверить, отобразив сводку образца модели с RNN в Keras.
Мы также можем получить точные матрицы и напечатать их имя и форму с помощью,
Следует отметить, что Keras называет входной вес как kernel, скрытую матрицу как recurrent_kernel и смещение как bias. Теперь давайте пройдемся по параметрам, выставленным Керасом. Хотя полный список представлен, мы кратко рассмотрим некоторые из них.
- Первый и самый главный - это
units
, который равен размеру вывода как kernel, так и recurrent_kernel. Это также размер члена bias и размер скрытого термина. - Затем у нас есть
activation
, который определил функцию g () в нашей формулировке. По умолчанию - tanh. - Затем у нас есть параметры
{*}_initializer
,{*}_regularizer
и{*}_constraint
для ядра, recurrent_kernel и bias. Их можно игнорировать, если вы не уверены в них, поскольку значения по умолчанию достаточно хороши. use_bias
- это логический параметр, который включает или выключает член смещения.dropout
иrecurrent_dropout
используются для применения вероятности выпадения к ядру и recurrent_kernel соответственно.return_sequence
- логический параметр. Когда он имеет значение «Истина», выходной формой слоя RNN является (временная метка, функция), а когда его значение «Ложь», выходными данными являются только (функции). Это означает, что если он включен, на выходе мы возвращаем y {t} для всех временных шагов, а если он выключен, мы возвращаем только 1 y {t} (здесь с последнего временного шага). Дополнительное предупреждение: не забудьте добавить слойTimeDistributed
илиFlatten
после RNN с включеннымreturn_sequence
перед добавлением слояDense
.go_backwards
имеет логический тип, и когда он имеет значение «Истина», RNN обрабатывает данные в обратном порядке. По умолчанию - "Ложь".return_state
имеет логический тип, и когда «Истина», он возвращает последнее состояние в дополнение к выходным данным. По умолчанию - «Ложь».stateful
- важный параметр. Когда установлено значение «True», Keras использует одно и то же скрытое состояние в пакетах для одного и того же индекса выборки. Поймите это так: мы обучаем нашу модель для нескольких эпох, что похоже на итерацию по полным данным. 1 эпоха - это 1 проход по полным данным. Теперь каждая эпоха содержит несколько пакетов, которые, в свою очередь, содержат несколько выборок, то есть отдельные данные. Обычно после обработки каждого образца в пакете состояние ячейки RNN сбрасывается. Но если мы подготовили данные в таком формате, что для нескольких пакетов выборки по определенному индексу являются просто расширением одного и того же предложения, мы можем изменить состояние как «Истина», и это будет эквивалентно обучению всех предложений сразу (как один образец). Мы можем сделать это из-за нехватки памяти и, следовательно, если мы не можем загрузить полные данные за один раз. По умолчанию - «Ложь».
Поняв основы RNN, давайте рассмотрим одну архитектуру, которая часто создается с помощью RNN.
Глубокие вертикальные РНС
Было высказано предположение, что наложение нескольких повторяющихся слоев друг на друга лучше для нескольких приложений. Это приводит к структуре, подобной сетке, где горизонтальная глубина (визуализация развернутой RNN) обусловлена шагами по времени, а вертикальные копии (наложение) обусловлены новыми слоями RNN. Это называется моделированием Seq2Seq и в основном используется для - языкового перевода, маркировки сущностей, распознавания речи - типа приложений, где у нас есть последовательность в качестве ввода и вывода. Тем не менее, мы также можем складывать несколько RNN, прежде чем, наконец, применить полностью связанный плотный слой, это пример последовательности в качестве ввода, но сглаженного вывода. Пример кода:
Это довольно просто, поскольку мы только что добавили два новых слоя RNN к предыдущему коду. Но обратите внимание, что мы устанавливаем return_sequence
как «Истина» для уровня RNN, если мы хотим наложить на него еще одну RNN. Это связано с тем, что следующая RNN ожидает ввода, распределенного по времени, и выход каждого временного шага предыдущей RNN становится входом в верхнюю RNN для тех же временных шагов. Здесь, в то время как обучаемые параметры для 1-го RNN остаются такими же, как предлагалось ранее, 2-й и 3-й RNN имеют разные параметры, потому что размер входных данных для этих RNN равен 128. Это делает параметр обучения для каждого из следующих двух RNN равным,
LSTM
Переходя к LSTM, есть куча очень хороших статей, таких как это и это. Я бы посоветовал взглянуть на них, прежде чем двигаться дальше. Как и в случае с RNN, реализация LSTM немного отличается от того, что предлагается в большинстве статей. Основное различие заключается в том, что вместо объединения ввода и предыдущего скрытого состояния у нас есть разные весовые матрицы, которые применяются к обоим перед передачей их в 4 внутренние нейронные сети в ячейке LSTM. Это означает, что мы удвоили количество требуемых матриц (на самом деле это удваивает размеры, но об этом позже). 4 матрицы, которые умножаются на ввод, называются kernel, а 4, которые умножаются на предыдущее скрытое состояние, называются recurrent_kernel. Чтобы лучше понять это, давайте посмотрим на формулировку:
Здесь, если вы заметили, у нас всего 8 весовых матриц, и, предполагая, что каждая из них имеет одинаковый размер, мы можем сказать, что в одном случае мы выполняем те же операции, что и в RNN, но теперь в 4 раза больше. Следовательно, количество обучаемых параметров теперь можно рассчитать следующим образом:
А переключиться с RNN на LSTM так же просто, как заменить вызов соответствующей функции, это можно увидеть в следующем коде,
Мы снова можем извлечь все веса из модели с помощью
Здесь обратите внимание, что все 4 матрицы kernel и 4 матрицы recurrent_kernel хранятся в каждой единственной монолитной матрице (объединенной на оси столбца), поэтому размерность составляет 128 * 4 = 512. То же самое и с термином смещения. Кроме того, здесь применимы почти все параметры, используемые в RNN. Одно предупреждение о дополнительных параметрах - это recurrent_activation
, который имеет значение по умолчанию сигмоид и применяется к входному, забытому и выходному вентилю, как предложено выше в формуле. При этом остается фактический activation
, который применяется к состоянию ячейки и скрытому состоянию (со значением по умолчанию tanh), как предложено выше, а также в формуле.
Заключение
Мы попытались охватить некоторые из основных тем, необходимых для соединения теории и практики для повторяющихся слоев в Керасе. Поскольку полного руководства со всеми внутренними деталями будет слишком много для одной статьи, я думаю, что существует множество материалов, которые очень хорошо объясняют эту тему. Что мне действительно не хватало, так это несколько примечаний, которые связывают формулы, которые я видел в статьях, с тем, что действительно реализовано в Keras, с некоторыми дополнительными практическими деталями. Надеюсь, это помогло!
Ваше здоровье.
Весь код из статьи загружен сюда.
Чтобы увидеть больше подобных статей, посетите мой сайт и свяжитесь со мной @ linkedin.