Глубокие рекуррентные нейронные сети (RNN) часто сталкиваются с проблемой затухающих и взрывающихся градиентов, что ограничивает их способность запоминать долгосрочные зависимости. Для решения этой задачи были разработаны специализированные механизмы памяти, среди которых GRU (Gated Recurrent Unit) занимает одно из ведущих мест благодаря простоте и эффективности.
GRU — это модифицированная RNN-ячейка, в которой используется два типа гейтов (врат): обновляющий и сброса. Эти гейты управляют потоком информации через временные шаги сети:
Гейт сброса (reset gate, r_t) Контролирует, какая часть предыдущего состояния ( h_{t-1} ) будет использована для вычисления нового кандидата состояния. Формула:
[ r_t = (W_r x_t + U_r h_{t-1} + b_r)]
Когда ( r_t ) близок к 0, предыдущее состояние почти не влияет на новое кандидата состояние, что позволяет сети “забывать” ненужную информацию.
Гейт обновления (update gate, z_t) Определяет, насколько текущее состояние должно включать информацию из предыдущего состояния:
[ z_t = (W_z x_t + U_z h_{t-1} + b_z)]
Гейт обновления управляет балансом между сохранением старой информации и внедрением нового кандидата состояния ( _t ).
**Кандидатное скрытое состояние ((_t))** Вычисляется с использованием гейта сброса, который фильтрует предыдущие значения состояния:
[ t = (W x_t + U (r_t h{t-1}) + b)]
Здесь ( ) обозначает поэлементное умножение. Гейт сброса позволяет контролировать, какие элементы старого состояния участвуют в создании кандидата.
Новое скрытое состояние (h_t) Обновляется как взвешенная комбинация предыдущего состояния и кандидата:
[ h_t = (1 - z_t) h_{t-1} + z_t _t]
В библиотеке Brain.js GRU реализован через класс
recurrent.GRU, который предоставляет интерфейс для создания
сети с поддержкой последовательных данных.
Пример инициализации:
const brain = require('brain.js');
const net = new brain.recurrent.GRU({
inputSize: 10,
hiddenLayers: [20, 20],
outputSize: 5
});
inputSize — размерность входного вектораhiddenLayers — массив, определяющий количество нейронов
в скрытых слоях GRUoutputSize — размерность выходного вектораПроцесс обучения:
net.train([
{ input: [0,1,0,1,0], output: [1] },
{ input: [1,0,1,0,1], output: [0] }
], {
iterations: 2000,
learningRate: 0.01
});
GRU особенно эффективна для задач:
Управление гейтами позволяет сети динамически адаптироваться к долгосрочным и краткосрочным зависимостям, что делает GRU предпочтительным выбором для многих приложений в Brain.js.