В библиотеке TensorFlow.js при построении рекуррентных нейронных сетей (RNN), LSTM или GRU слоев, ключевую роль играют параметры returnSequences и returnState. Они определяют формат выходных данных слоя и способ взаимодействия между слоями сети. Понимание этих параметров критично для построения сложных архитектур, где требуется передавать скрытое состояние или формировать последовательности выходов.
returnSequencesСлой RNN по умолчанию возвращает только последнее состояние скрытого слоя. Это удобно для задач, где требуется агрегированная информация о всей последовательности, например, классификация текста. Однако часто необходимо получать выход на каждом временном шаге.
Синтаксис:
const lstmLayer = tf.layers.lstm({
units: 128,
returnSequences: true
});
Ключевые моменты:
returnSequences: false (по умолчанию):
возвращается тензор формы [batchSize, units], где
units — количество нейронов слоя. В этом случае
используется только последнее скрытое состояние.returnSequences: true: возвращается
тензор формы [batchSize, timeSteps, units], где
timeSteps — длина входной последовательности. Каждый
временной шаг имеет собственный выходной вектор.Пример:
const input = tf.input({shape: [10, 50]}); // последовательность длиной 10, размерность признака 50
const lstm = tf.layers.lstm({units: 64, returnSequences: true});
const output = lstm.apply(input);
console.log(output.shape); // [null, 10, 64]
Использование returnSequences: true необходимо, когда
один LSTM-слой передаёт последовательность другому рекуррентному слою
или когда требуется сформировать выходную последовательность для задач
предсказания временных рядов.
returnStateИногда требуется не только выходные значения, но и скрытые
состояния слоя. Параметр returnState позволяет
получить состояния LSTM или GRU для передачи их в последующие
вычисления, восстановления состояния или инициализации другого слоя.
Синтаксис:
const lstmLayer = tf.layers.lstm({
units: 128,
returnState: true
});
Особенности для LSTM:
LSTM имеет два состояния: h (hidden state) и c (cell state).
Если returnState: true, метод apply
возвращает массив:
[output, h, c]
где output зависит от returnSequences:
returnSequences: false, output имеет
форму [batchSize, units].returnSequences: true, output имеет
форму [batchSize, timeSteps, units].Пример:
const lstm = tf.layers.lstm({units: 64, returnState: true});
const [output, h, c] = lstm.apply(input);
console.log(output.shape); // [null, 64] если returnSequences: false
console.log(h.shape); // [null, 64]
console.log(c.shape); // [null, 64]
Для GRU слой возвращает только одно скрытое состояние h,
так как в GRU нет отдельного cell state:
const gru = tf.layers.gru({units: 64, returnState: true});
const [output, h] = gru.apply(input);
returnSequences и returnStateЭти два параметра можно использовать одновременно для гибкой конфигурации:
returnSequences: true,
returnState: true Позволяет получить полный
выходной тензор по всем временным шагам и скрытые состояния для
инициализации следующего слоя.
returnSequences: false,
returnState: true Возвращается только последнее
значение последовательности вместе с состояниями слоя.
Пример LSTM с обоими параметрами:
const lstm = tf.layers.lstm({
units: 64,
returnSequences: true,
returnState: true
});
const [outputSeq, h, c] = lstm.apply(input);
console.log(outputSeq.shape); // [null, 10, 64]
console.log(h.shape); // [null, 64]
console.log(c.shape); // [null, 64]
Использование такого подхода важно для построения encoder-decoder архитектур или многоступенчатых RNN, где требуется передавать скрытое состояние на следующий слой или шаг генерации.
const encoderInput = tf.input({shape: [20, 128]});
const encoderLSTM = tf.layers.lstm({units: 256, returnState: true});
const [_, stateH, stateC] = encoderLSTM.apply(encoderInput);
const decoderInput = tf.input({shape: [30, 128]});
const decoderLSTM = tf.layers.lstm({
units: 256,
returnSequences: true,
returnState: true
});
const [decoderOutput, _, __] = decoderLSTM.apply(decoderInput, {initialState: [stateH, stateC]});
const lstm1 = tf.layers.lstm({units: 128, returnSequences: true, returnState: true});
const [out1, h1, c1] = lstm1.apply(input);
const lstm2 = tf.layers.lstm({units: 64, returnSequences: false});
const out2 = lstm2.apply(out1, {initialState: [h1, c1]});
returnSequences управляет формой выхода слоя: полный
выход по всем временным шагам или только последний вектор.returnState позволяет получить внутренние состояния RNN
для дальнейшего использования.Эффективное применение этих параметров является ключевым при проектировании рекуррентных сетей для задач обработки последовательностей, предсказания временных рядов и генерации текста.