Слой Embedding

Слой Embedding является фундаментальным компонентом при работе с моделями обработки текстов и последовательностей. Он используется для преобразования категориальных данных, таких как слова или токены, в плотные векторные представления фиксированной размерности. Это позволяет нейронной сети работать с семантическими свойствами данных, а не с их исходными дискретными идентификаторами.

Основные принципы работы

Слой Embedding принимает на вход последовательность целых чисел — индексов слов или токенов из словаря. Каждый индекс отображается на соответствующий вектор фиксированной длины, называемый эмбеддингом. Математически это можно представить как матрицу W размером (vocab_size, embedding_dim), где:

  • vocab_size — размер словаря, то есть количество уникальных токенов.
  • embedding_dim — размерность векторов эмбеддинга.

Если входная последовательность имеет форму (batch_size, sequence_length), выход слоя будет иметь форму (batch_size, sequence_length, embedding_dim).

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

Создание слоя Embedding в TensorFlow.js

В TensorFlow.js слой Embedding создается с использованием функции tf.layers.embedding. Основные параметры:

const embeddingLayer = tf.layers.embedding({
  inputDim: vocabSize,       // размер словаря
  outputDim: embeddingDim,   // размерность вектора эмбеддинга
  inputLength: sequenceLength, // длина входной последовательности
  embeddingsInitializer: 'randomUniform', // способ инициализации весов
  maskZero: false            // игнорирование нулевых индексов
});
  • inputDim — обязательный параметр, задает размер словаря. Индексы вне диапазона [0, inputDim-1] приведут к ошибке.
  • outputDim — размерность векторов эмбеддинга.
  • inputLength — фиксированная длина последовательности, часто необходима для последующих слоев, например, LSTM.
  • embeddingsInitializer — задает метод инициализации весов матрицы эмбеддинга (например, randomUniform, glorotUniform).
  • maskZero — если true, нули во входных данных будут игнорироваться при обучении рекуррентных слоев.

Пример интеграции Embedding в модель

Слой Embedding чаще всего используется в сочетании с рекуррентными сетями (LSTM, GRU) или свёрточными слоями для обработки текста. Пример последовательной модели:

const model = tf.sequential();

model.add(tf.layers.embedding({
  inputDim: 10000,     // словарь из 10 000 токенов
  outputDim: 128,      // вектор эмбеддинга размерностью 128
  inputLength: 50      // каждая последовательность длиной 50
}));

model.add(tf.layers.lstm({
  units: 64,
  returnSequences: false
}));

model.add(tf.layers.dense({
  units: 1,
  activation: 'sigmoid'
}));

model.compile({
  optimizer: 'adam',
  loss: 'binaryCrossentropy',
  metrics: ['accuracy']
});

В этом примере слой Embedding преобразует последовательность из 50 индексов в матрицу размером (50, 128) для каждой последовательности в батче. Далее LSTM обрабатывает эту матрицу для извлечения признаков.

Использование предобученных эмбеддингов

В TensorFlow.js можно загружать и использовать предобученные эмбеддинги, например GloVe или Word2Vec. Для этого веса слоя Embedding устанавливаются вручную:

embeddingLayer.setWeights([pretrainedWeights]);
embeddingLayer.trainable = false; // замораживание предобученных весов

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

Особенности работы

  • Память: Слой Embedding может занимать значительное количество памяти при большом словаре. В TensorFlow.js рекомендуется использовать подходящие методы инициализации и ограничивать размер словаря.
  • Маскирование: Если последовательности имеют разную длину, часто используется maskZero: true, чтобы рекуррентные слои игнорировали паддинги.
  • Обратное распространение: Весовая матрица обучается вместе с моделью. Каждое обновление влияет только на строки, соответствующие индексам, встречающимся во входных данных.

Практические советы

  • При небольших наборах данных размер эмбеддинга лучше ограничивать, чтобы избежать переобучения.
  • Если данные сильно различаются по частоте слов, полезно использовать словарь с ограничением по частоте или применять токенизацию с редкими токенами.
  • Слой Embedding может быть начальной точкой для сложных архитектур, включая Transformer и BERT-подобные модели в TensorFlow.js.

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