Проблема моделирования последовательностей

Моделирование последовательностей является одной из ключевых задач в области машинного обучения, охватывающей такие сценарии, как прогнозирование временных рядов, обработка текста, распознавание речи и анализ сигналов. TensorFlow.js предоставляет мощный инструмент для построения и обучения моделей, работающих с последовательными данными, используя как высокоуровневые API tf.layers, так и низкоуровневые возможности tf.tensor и tf.data.

Представление последовательностей

Последовательности в TensorFlow.js обычно представляются как тензоры с размерностями [batch, timesteps, features].

  • batch — количество независимых последовательностей, обрабатываемых одновременно.
  • timesteps — длина каждой последовательности, количество временных шагов.
  • features — количество признаков на каждом временном шаге.

Например, для временного ряда с 100 последовательностями, длиной 50 шагов и одним числовым значением на шаге, тензор будет иметь форму [100, 50, 1].

Подготовка данных

Для работы с последовательностями важно правильно формировать обучающие выборки. Прямое использование исходных данных часто невозможно, поэтому применяются методы сдвига окна (sliding window):

function createSequences(data, sequenceLength) {
    const sequences = [];
    for (let i = 0; i < data.length - sequenceLength; i++) {
        sequences.push(data.slice(i, i + sequenceLength));
    }
    return tf.tensor(sequences);
}

Использование функции tf.tensor позволяет сразу создавать тензоры, готовые для подачи в модель.

Архитектуры для последовательностей

TensorFlow.js поддерживает несколько типов рекуррентных нейронных сетей (RNN), каждая из которых подходит для разных задач:

  • SimpleRNN — базовая рекуррентная сеть, эффективно справляется с короткими последовательностями.
  • LSTM (Long Short-Term Memory) — решает проблему затухающих градиентов, подходящая для длинных временных зависимостей.
  • GRU (Gated Recurrent Unit) — облегчённая версия LSTM, экономит память и ускоряет обучение.

Пример построения LSTM-модели для прогнозирования временного ряда:

const model = tf.sequential();
model.add(tf.layers.lstm({
    units: 50,
    inputShape: [timesteps, features],
    returnSequences: false
}));
model.add(tf.layers.dense({ units: 1 }));
model.compile({ optimizer: 'adam', loss: 'meanSquaredError' });

Обучение модели

Для последовательных данных оптимальным является использование батчей с правильным порядком временных шагов. В TensorFlow.js это достигается через метод model.fit с передачей тензоров входа и выхода:

await model.fit(xTrain, yTrain, {
    epochs: 100,
    batchSize: 32,
    validationSplit: 0.2,
    shuffle: false
});

Важно отключать перемешивание (shuffle: false), чтобы сохранить порядок временных шагов в последовательностях.

Прогнозирование и генерация последовательностей

После обучения модели прогнозирование выполняется через метод model.predict:

const inputSequence = tf.tensor([/* данные последовательности */]);
const prediction = model.predict(inputSequence);
prediction.print();

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

Обработка текстовых последовательностей

В задачах обработки текста последовательности представляют собой последовательности индексов слов или токенов. Используется токенизация, а затем создание тензоров:

const tokenizer = new tf.keras.preprocessing.text.Tokenizer();
tokenizer.fitOnTexts(texts);
const sequences = tokenizer.textsToSequences(texts);

Далее последовательности приводятся к единой длине с помощью padSequences, что обеспечивает совместимость с входом рекуррентной сети.

Использование tf.data для потоковой обработки

Для больших последовательностей и потоковых данных используется API tf.data, позволяющий создавать эффективные конвейеры загрузки и предварительной обработки данных:

const dataset = tf.data.array(sequences)
    .batch(32)
    .map(batch => {
        return { xs: batch.slice([0, 0], [-1, -1]), ys: batch.slice([0, -1], [-1, 1]) };
    });

Такой подход минимизирует использование памяти и ускоряет обучение на больших наборах данных.

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

TensorFlow.js позволяет запускать обучение как на CPU, так и на GPU через WebGL. При работе с последовательностями рекомендуется:

  • Использовать малые батчи для WebGL, чтобы избежать переполнения видеопамяти.
  • Применять tf.tidy для автоматического освобождения промежуточных тензоров.
  • Сохранять модели через model.save('indexeddb://my-model') для повторного использования без загрузки сервера.

Совмещение рекуррентных и свёрточных слоёв

Для задач с длинными последовательностями и многомерными признаками часто применяются гибридные архитектуры, объединяющие 1D-свёртки и LSTM. Свёрточные слои выделяют локальные паттерны, а LSTM моделирует долгосрочные зависимости:

const model = tf.sequential();
model.add(tf.layers.conv1d({ filters: 64, kernelSize: 3, activation: 'relu', inputShape: [timesteps, features] }));
model.add(tf.layers.maxPooling1d({ poolSize: 2 }));
model.add(tf.layers.lstm({ units: 50 }));
model.add(tf.layers.dense({ units: 1 }));

Такой подход улучшает качество прогнозов и ускоряет обучение.

Метрики и контроль качества

Для оценки моделей последовательностей применяются:

  • Mean Squared Error (MSE) — для регрессии временных рядов.
  • Categorical Crossentropy — для классификации последовательностей.
  • Perplexity — для языковых моделей.

Использование нескольких метрик одновременно позволяет точнее отслеживать качество и избегать переобучения.


Эта структура демонстрирует полный цикл работы с последовательностями в TensorFlow.js, начиная от подготовки данных и построения модели, до обучения и генерации предсказаний. Такой подход позволяет эффективно решать задачи временных рядов, обработки текста и сигналов в среде JavaScript.