LSTM прокладывает через время почти линейный путь состояния. Ворота не являются маленькими разумными контролёрами: это дифференцируемые числа от нуля до единицы, которые учатся пропускать, стирать и показывать сигнал.

Пароль через длинную паузу

Последовательность начинается символом К, затем идут двести нерелевантных знаков, а в конце нужно воспроизвести первый символ. Простая RNN многократно переписывает hth_t и проводит градиент через произведение матриц. LSTM добавляет отдельное состояние памяти ctc_t с аддитивным обновлением.

Для входа xtx_t и предыдущего ht1h_{t-1} вычисляются ворота:

ft=σ(Wf[xt,ht1]+bf),it=σ(Wi[xt,ht1]+bi),ot=σ(Wo[xt,ht1]+bo),c~t=tanh(Wc[xt,ht1]+bc).\begin{aligned} f_t&=\sigma(W_f[x_t,h_{t-1}]+b_f),\\ i_t&=\sigma(W_i[x_t,h_{t-1}]+b_i),\\ o_t&=\sigma(W_o[x_t,h_{t-1}]+b_o),\\ \widetilde c_t&=\tanh(W_c[x_t,h_{t-1}]+b_c). \end{aligned}

Затем

ct=ftct1+itc~t,ht=ottanh(ct).c_t=f_t\odot c_{t-1}+i_t\odot\widetilde c_t, \qquad h_t=o_t\odot\tanh(c_t).

Forget gate ftf_t сохраняет часть старого, input gate iti_t дозирует запись, output gate oto_t решает, что показать наружу. Все операции покомпонентны.

Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Схема LSTM с forget input output gates и потоками состояния
Рис. 74.1. Путь памяти через ячейку LSTM

Горизонтальная синяя линия — ct1ctc_{t-1}\to c_t, умножение на ftf_t отмечено затвором. Зелёная ветвь добавляет itc~ti_t\widetilde c_t, нижняя ветвь формирует hth_t. Под схемой те же операции показаны для одной координаты численно.

Почему сложение помогает градиенту

Частная производная по прямому пути

ctct1ft.\frac{\partial c_t}{\partial c_{t-1}}\approx f_t.

Если на промежутке ворота близки к единице,

cTctk=t+1Tfk\frac{\partial c_T}{\partial c_t} \approx\prod_{k=t+1}^Tf_k

затухает медленно. В простой RNN к этому произведению добавлялись рекуррентные матрицы и производные tanh\tanh на каждом шаге.

«Почти» в формуле существенно: ворота зависят от ht1h_{t-1}, поэтому полный градиент имеет дополнительные пути. LSTM смягчает исчезновение, а не доказывает бесконечную память.

Если ff постоянно равен 0,990{,}99, половина сигнала остаётся после

t1/2=log0,5log0,9969t_{1/2}=\frac{\log 0{,}5}{\log0{,}99}\approx69

шагов. При f=0,9f=0{,}9 — всего около 7. Небольшое изменение ворот резко меняет временной масштаб.

Записать, не стерев

Ворота могут создавать разные режимы:

  • f1,i0f\approx1,i\approx0: хранить;
  • f0,i1f\approx0,i\approx1: заменить;
  • f1,i>0f\approx1,i>0: накопить;
  • o0o\approx0: скрыть память от выхода, не удаляя её.

Последний режим отличает внутреннее хранение от наблюдаемого состояния. Модель может помнить фазу процесса и не использовать её для текущего прогноза.

Bias forget gate часто инициализируют положительно, чтобы в начале ftf_t был ближе к единице. Это полезный prior на длительную память, но слишком большой bias мешает быстро забывать смену режима.

Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Временные ряды входа, forget input output gates, cell state и hidden state
Рис. 74.2. Ворота размечают события во времени

На шаге «ключ» input gate открывается и записывает импульс. Во время паузы ft1f_t\approx1, it0i_t\approx0. У маркера ответа output gate открывает скрытый сигнал. Вертикальные линии связывают события с изменениями ворот.

Лаборатория ворот

Forget gate, пауза и сохранённый сигнал

Загружается живая иллюстрация…

Задайте импульс и вручную управляйте f,i,of,i,o. Проверьте формулу времени полураспада. Затем разрешите модели подобрать ворота для задачи delayed copy и сравните их с вашей ручной стратегией.

Не ищите буквальное «это нейрон памяти буквы К». Представление распределено: одна координата может участвовать в нескольких функциях, а один факт храниться в нескольких координатах.

Маска, padding и неодинаковая длина

В batch последовательности дополняют padding. Маска mt{0,1}m_t\in\{0,1\} может сохранять состояние на фиктивных шагах:

ct=mtctnew+(1mt)ct1.c_t=m_t c_t^{\mathrm{new}}+(1-m_t)c_{t-1}.

Loss также умножают на маску. Иначе короткие примеры получают лишние нулевые события, а последнее состояние относится к padding, не к данным.

В медицинских рядах пропуск измерения несёт информацию: анализ могли назначить из-за ухудшения. Маска наблюдаемости и время с последнего измерения становятся входными признаками. Заполнить все пропуски нулём — значит смешать «значение равно нулю» с «не измерено».

GRU: меньше ворот

Gated Recurrent Unit объединяет память и скрытое состояние:

zt=σ(Wz[xt,ht1]),rt=σ(Wr[xt,ht1]),h~t=tanh(Wh[xt,rtht1]),ht=(1zt)ht1+zth~t.\begin{aligned} z_t&=\sigma(W_z[x_t,h_{t-1}]),\\ r_t&=\sigma(W_r[x_t,h_{t-1}]),\\ \widetilde h_t&=\tanh(W_h[x_t,r_t\odot h_{t-1}]),\\ h_t&=(1-z_t)\odot h_{t-1}+z_t\odot\widetilde h_t. \end{aligned}

Update gate ztz_t интерполирует между старым и новым. Параметров меньше, вычисление быстрее. Нельзя заранее утверждать, что LSTM «лучше помнит»: сравнение зависит от данных, размера и бюджета.

Одинаковое число скрытых координат не означает одинаковое число параметров. При честном сравнении выравнивают хотя бы размер модели или время обучения.

Электропотребление дома

Набор UCI Individual Household Electric Power Consumption содержит поминутные измерения нескольких лет. Реальная задача: по последним суткам предсказать нагрузку на следующий час или сутки. Периодичность дня и недели создаёт длинный контекст, а пропуски требуют явной обработки.

Хороший эксперимент:

  1. разбить время на train, validation и будущий test;
  2. построить seasonal naive baseline: значение неделю назад;
  3. использовать доступные календарные признаки;
  4. сравнить GRU, LSTM и 1D-convolution при близком бюджете;
  5. оценить MAE отдельно в пиковые часы.

Если нормировать по среднему всего датасета, test влияет на train. Статистики вычисляют только по обучающему периоду.

Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Почасовая нагрузка дома, прогнозы seasonal baseline и LSTM, ошибки на пиках
Рис. 74.3. Память о недельном ритме

Верхняя панель показывает две недели нагрузки и границу прогноза. Внизу — абсолютная ошибка seasonal baseline и LSTM; красным отмечены вечерние пики. Рядом приведён профиль среднего forget gate, но он интерпретируется как диагностический сигнал, не причинное объяснение.

Что ворота не решают

LSTM всё ещё обрабатывает шаги последовательно, что ограничивает параллельность. Состояние остаётся фиксированного размера. Дальняя информация может затухнуть или быть перезаписана, а интерпретация ворот неоднозначна.

Для задач с прямыми связями между далёкими токенами attention создаст короткий путь. Для потоковой обработки на устройстве LSTM может быть дешевле. Архитектура выбирается по ограничениям, а не по хронологии моды.

Связь с остаточными соединениями трансформера содержательная: и аддитивный путь ctc_t, и residual дают сигналу возможность пройти без полного нелинейного переписывания.

Мини-исследование: ворота на смене режима

Сгенерируйте ряд, где скрытый уровень btb_t постоянен 50–150 шагов, затем маркер mt=1m_t=1 сообщает, что уровень заново выбран. Наблюдение

xt=bt+εt,εtN(0,0,22).x_t=b_t+\varepsilon_t,\qquad \varepsilon_t\sim\mathcal N(0,0{,}2^2).

LSTM должна усреднять шум внутри сегмента и быстро забывать старое после маркера. Постройте средние ft,itf_t,i_t в окне от 10-10 до +20+20 вокруг переключения. Ожидается падение forget gate и рост input gate, но проверяйте одновременно ошибку: красивый профиль без улучшения прогноза ничего не доказывает.

Проведите counterfactual: удалите маркер из входа, сохранив сами значения. Время адаптации должно увеличиться. Затем вставьте ложный маркер без смены уровня. Если сеть полностью стирает память, возникнет краткий всплеск ошибки. Так выясняется, как она объединяет явное событие и статистическое свидетельство.

Сравните с change-point detection, где переключение ищется по вероятностному критерию. LSTM обучает внутренний detector вместе с прогнозом, но не выдаёт калиброванную вероятность смены.

Практическая проверка масок

Создайте batch из одной короткой и одной длинной последовательности. Один раз правильно замаскируйте padding, второй — оставьте нули как обычный вход. Убедитесь, что prediction короткого объекта зависит от количества добавленных нулей только во втором режиме. Этот unit test стоит держать рядом с кодом: ошибка padding способна тихо пережить обучение и проявиться лишь на другой длине.

При irregular sampling добавьте Δt\Delta t как признак. Два одинаковых значения, разделённые минутой и сутками, означают разную скорость процесса. Здесь LSTM встречается с работой над временными данными: индекс времени является частью наблюдения, а не подписью на графике.

Проверьте state reset. Отсортируйте объекты в batch двумя разными порядками и убедитесь, что прогноз каждого не меняется. Если hidden state случайно перетекает между объектами, результат зависит от технического порядка строк. Такой баг способен дать особенно высокий validation score, когда соседние записи относятся к одному устройству.

Для streaming inference явно задайте событие сброса: новый двигатель, длинный разрыв или смена пользователя. Сохраните этот контракт рядом с моделью, иначе offline и production будут вычислять разные состояния.

Отдельно протестируйте длинное накопление в mixed precision. Ограниченный hth_t способен скрывать рост внутреннего ctc_t; позднее открытие output gate насыщает tanh\tanh и стирает различия.

Тестируйте state contract на отдельном наборе коротких, длинных и прерванных последовательностей.

Ворота задают временной масштаб

LSTM делает память управляемой: отдельный аддитивный канал, запись, забывание и чтение. Формула постоянного forget gate связывает значение ворот с временным масштабом. На практике качество определяется масками, разделением данных, baseline и честным бюджетом не меньше самой ячейки.

Задачи