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

Температура без контекста

Датчик сообщает 18,118{,}1^\circ, затем 18,418{,}4^\circ, затем 18,918{,}9^\circ. Последнее число само по себе не говорит, быстро ли нагревается помещение. Нужна история. Можно подать модели окно последних kk измерений, но фиксированное окно заранее ограничивает память и дублирует параметры для разных позиций.

Простая recurrent neural network обновляет состояние:

ht=tanh(Wxxt+Whht1+b),y^t=Wyht+c.h_t=\tanh(W_xx_t+W_hh_{t-1}+b), \qquad \widehat y_t=W_yh_t+c.

hth_t — сжатое резюме префикса x1,,xtx_1,\ldots,x_t. Матрицы Wx,WhW_x,W_h одинаковы для всех tt. Это weight sharing: правило обработки не зависит от длины.

Если hth_t имеет размер 64, сеть переносит ровно 64 числа, независимо от того, прочитала 10 шагов или 10 000. Ограничение делает модель вычислимой и одновременно заставляет забывать.

Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Рекуррентная ячейка и её развёртка на пять временных шагов
Рис. 73.1. Одна ячейка, развёрнутая во времени

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

Линейная память без нелинейности

Чтобы увидеть механику, возьмём одномерную линейную систему:

ht=wxt+uht1,h0=0.h_t=wx_t+uh_{t-1},\qquad h_0=0.

Разворачивая рекурсию, получаем

ht=w(xt+uxt1+u2xt2++ut1x1).h_t=w(x_t+ux_{t-1}+u^2x_{t-2}+\cdots+u^{t-1}x_1).

При u<1|u|<1 прошлое затухает геометрически. Характерное время памяти порядка 1/(1u)1/(1-|u|). При u>1|u|>1 старые сигналы растут, и состояние становится неустойчивым. При u=1u=1 память не затухает, но любая постоянная составляющая накапливается без границы.

Нелинейность tanh\tanh ограничивает значения, однако не отменяет многократного умножения производных. Этот скалярный пример — не игрушка, а рентген сложной сети.

Обучение через развёртку

Для последовательности loss складывается по шагам:

L=t=1T(y^t,yt).\mathcal L=\sum_{t=1}^T\ell(\widehat y_t,y_t).

Backpropagation through time разворачивает вычислительный граф и проводит градиент назад. Вклад от далёкого шага содержит произведение Якобианов:

hTht=k=t+1Tdiag(1hk2)Wh.\frac{\partial h_T}{\partial h_t} =\prod_{k=t+1}^{T} \operatorname{diag}(1-h_k^2)W_h.

Если нормы множителей меньше единицы, градиент исчезает; если больше — взрывается. Gradient clipping ограничивает норму:

ggmin(1,cg).g\leftarrow g\min\left(1,\frac{c}{\|g\|}\right).

Он спасает от огромного шага оптимизатора, но не возвращает исчезнувший дальний сигнал.

Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Логарифм нормы градиента по временному лагу для трёх спектральных радиусов
Рис. 73.2. Произведение производных задаёт дальность обучения

По горизонтали лаг TtT-t, по вертикали log10hT/ht\log_{10}\|\partial h_T/\partial h_t\|. Кривые для эффективных множителей 0,80{,}8, 1,01{,}0, 1,151{,}15 показывают исчезновение, сохранение и взрыв. Горизонтальная полоса отмечает диапазон численной различимости.

Лаборатория импульса

Импульс, скрытое состояние и время забывания

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

Подайте единичный импульс x1=1x_1=1, остальные входы обнулите. Меняйте рекуррентный множитель и измеряйте время, за которое ht|h_t| уменьшится вдвое. Сопоставьте опыт с формулой ut1u^{t-1}.

Затем включите нелинейность и большой импульс. tanh\tanh насыщается: разные большие значения превращаются почти в единицу. Сеть получает устойчивость по амплитуде, но теряет различимость и производную.

Какая задача действительно требует памяти

Для проверки дальнего контекста используют synthetic-задачу adding problem. Последовательность содержит случайные числа и два маркера; нужно сложить числа в отмеченных далёких позициях. Локальное окно бесполезно, а точная цель известна.

Другой тест — delayed copy: показать символ, затем длинную паузу, затем потребовать его воспроизвести. Увеличивая задержку, строят кривую дальности памяти. Такие задачи не заменяют реальные данные, но изолируют механизм.

В естественных временных рядах сильный baseline часто проще: последнее значение, скользящее среднее, линейная авторегрессия. Если RNN не выигрывает у них, глубина не оправдана.

Truncated BPTT

Для длинной последовательности хранить весь граф дорого. Truncated BPTT обрабатывает отрезки длины LL: состояние переносится между ними, но градиент через границу обрывается. Модель может использовать информацию в forward pass, хотя обучающий сигнал не проходит дальше LL шагов напрямую.

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

При разбиении нескольких временных рядов нельзя переносить состояние от одного устройства к другому. В batch элементы имеют разную длину; padding маскируют в loss, иначе сеть учится на искусственных нулях.

Реальные данные: датчики турбины

NASA C-MAPSS содержит синтетически сгенерированные, но физически мотивированные траектории деградации авиационных двигателей: режимы работы, показания сенсоров и момент отказа. Задача — оценить remaining useful life.

Разделять данные нужно по двигателям, а не по строкам времени. Если ранние моменты одного двигателя попадут в train, а поздние — в test, модель узнает индивидуальную траекторию и оценка станет завышенной. Признаки нормируют с учётом режима работы; константные сенсоры удаляют.

RNN получает последовательность до текущего момента и предсказывает остаток. Но target часто обрезают сверху: на ранней стадии точный срок почти неразличим, разумнее предсказывать «не меньше порога».

Рисунок шире экрана — проведите по немуОткрыть целиком ↗
Два сенсорных ряда двигателей и прогноз remaining useful life
Рис. 73.3. Деградация видна в траектории, не в одной точке

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

RNN, свёртка и внимание

Одномерная свёртка обрабатывает локальные окна параллельно; её receptive field растёт с глубиной и dilation. RNN естественно работает online, обновляя одно состояние. Attention даёт прямой доступ ко всем прошлым позициям, но хранит их и обычно стоит квадратично по длине.

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

Мини-исследование: какая история действительно используется

Возьмите обученную модель прогноза нагрузки и проведите temporal occlusion. Для каждого лага \ell замените xtx_{t-\ell} локальным средним, оставив остальные входы. Измерьте рост ошибки

I()=MAEoccluded()MAEbase.I(\ell)= \operatorname{MAE}_{\mathrm{occluded}(\ell)} -\operatorname{MAE}_{\mathrm{base}}.

Если модель использует суточный и недельный ритм, пики I()I(\ell) ожидаются около 24 и 168 часов. Но замена одной точки может создавать неестественный скачок. Второй контроль — перемешать целый блок вокруг лага или заменить его фрагментом другого дня с тем же часом.

Сопоставьте occlusion profile с gradient y^t/xt\|\partial\widehat y_t/\partial x_{t-\ell}\|. Gradient показывает локальную чувствительность, вмешательство — фактическое изменение output. Их расхождение содержательно: насыщенная RNN может иметь малый gradient, хотя крупное вмешательство меняет состояние.

Добавьте seasonal baseline и тот же occlusion к нему. Если RNN-пик на лаге 168 повторяет явное правило baseline, модель не обязательно открыла новую закономерность. Главный вопрос — уменьшила ли она ошибку в режимах, где недельный повтор не работает: праздники, аномальная погода, пропуски.

Мини-исследование: скрытый state как ограниченный канал

Обучите одинаковые RNN с dh{4,16,64,256}d_h\in\{4,16,64,256\} на delayed-copy с несколькими одновременно запоминаемыми символами. Для каждого размера измерьте accuracy против числа символов и задержки, а также время и параметры. Малый state исчерпывает ёмкость, большой труднее оптимизируется. Получится empirical frontier, а не лозунг «больше памяти лучше».

С помощью linear probe попробуйте декодировать каждый сохранённый символ из hth_t на разных шагах. Probe не доказывает использование информации, но показывает, когда она становится недоступна простому чтению. Сравните с фактическим output модели.

Добавьте shuffle-control: перемешайте временной порядок внутри окна, сохранив набор значений. Если качество почти не изменилось, модель использует агрегат, а не последовательность. Тогда более простой табличный baseline со средним и трендом может быть достаточен.

В реальном ряду перемешивание разрушает сезонность, поэтому делайте его внутри сопоставимых часов или synthetic-задачи. Контроль должен удалять исследуемую структуру и сохранять остальные, иначе причина падения неясна.

Память измеряется задачей

RNN — повторяемое правило обновления состояния. Развёртка показывает и экономию параметров, и проблему произведения производных. Простые импульсные тесты объясняют память лучше случайной метрики на одном датасете. А на реальных рядах честное разделение по объектам важнее архитектурного названия.

Задачи