Уважаемый читатель!

Эта статья была переиздана на Эдукаора и также была с открытым исходным кодом. К сожалению, TensorFlow 2.0 изменил API, поэтому он не работает для более поздних версий. Мы приветствуем любую помощь в обновлении учебников. Я также рекомендую вам изучить PyTorch.

В предыдущем посте мы изменили наш код, чтобы использовать собственный RNN API TensorFlow. Теперь мы приступим к созданию модификации RNN, которая называется Рекуррентная нейронная сеть с долговременной краткосрочной памятью или RNN-LSTM. Пионером в этой архитектуре был, в частности, Юрген Шмидхубер. Одна проблема с RNN при использовании длительных зависимостей от времени (truncated_backprop_length большой) - это проблема исчезающего градиента. Один из способов противостоять этому - использовать состояние, которое является защищенным и избирательным. RNN-LSTM запоминает, забывает и выбирает, что передавать и выводить в зависимости от текущего состояния и ввода.

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

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

Другое состояние

LSTM имеет «состояние ячейки» и «скрытое состояние», чтобы учесть это, вам нужно удалить _current_state в строке 79 в предыдущем скрипте и заменить его следующим:

TensorFlow использует внутреннюю структуру данных LSTMStateTuple для своего LSTM: s, где первый элемент в кортеже - это состояние ячейки, а второй - скрытое состояние. Таким образом, вам нужно изменить строку 28, где заполнители init_state объявлены для этих строк:

Изменить прямой проход теперь просто, вы просто меняете вызов функции, чтобы создать LSTM и указать исходный кортеж состояний в строках 38–39.

states_series будет списком скрытых состояний в виде тензоров, а current_state будет LSTMStateTuple, который показывает как скрытое, так и состояние ячейки на последний временной шаг, как показано ниже:

Таким образом, current_state возвращает ячейки и скрытое состояние в кортеже. После расчета они должны быть разделены и предоставлены заполнителям в функции выполнения в строке 90.

Вся программа

Это полный код для создания RNN с долговременной краткосрочной памятью.

Следующий шаг

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