Генерация текста символ за символом

Keras.js представляет собой JavaScript-библиотеку, позволяющую выполнять предобученные модели Keras непосредственно в браузере или на Node.js. Генерация текста символ за символом — одна из классических задач, где модель обучается предсказывать следующий символ на основе предыдущих, что позволяет создавать последовательности текста, имитирующие стиль исходного корпуса.

Подготовка модели для Keras.js

Для генерации текста требуется нейронная сеть, обученная на последовательностях символов. Наиболее подходящая архитектура — рекуррентная нейронная сеть (RNN), чаще всего с LSTM-ячейками:

  • LSTM (Long Short-Term Memory) обеспечивает сохранение контекста на длинных последовательностях.
  • Вход модели: последовательность символов, преобразованная в числовой вид (one-hot encoding).
  • Выход модели: вероятность появления каждого символа в алфавите на следующем шаге.

Модель создается и обучается в Python с использованием Keras, а затем экспортируется для Keras.js. Экспорт включает:

  • Сохранение структуры модели в формате JSON (model.to_json()).
  • Сохранение весов в формате HDF5 (model.save_weights()), после чего веса конвертируются в формат Keras.js (kerasjs-converter).

Загрузка модели в Keras.js

Для работы с моделью в браузере используется следующий порядок:

const model = new KerasJS.Model({
  filepath: 'model.bin', // бинарный файл с весами
  gpu: true              // использование WebGL для ускорения
});

await model.ready();

Ключевой момент: загрузка модели является асинхронной, поэтому любые вычисления можно начинать только после await model.ready().

Подготовка данных для генерации

Генерация текста начинается с подготовки входной последовательности:

  1. Словарь символов: необходимо сопоставить каждый символ уникальному индексу.
  2. One-hot encoding: входная последовательность преобразуется в массив размером [длина_последовательности, размер_алфавита], где каждый символ представлен вектором с единицей на позиции индекса символа.

Пример функции преобразования символа в one-hot:

function charToOneHot(char, charToIndex, vocabSize) {
  const vector = new Float32Array(vocabSize).fill(0);
  vector[charToIndex[char]] = 1;
  return vector;
}

Генерация текста шаг за шагом

Алгоритм генерации текста:

  1. Выбор начального текста (seed), который станет первой последовательностью.
  2. Преобразование seed в one-hot представление.
  3. Передача последовательности в модель для получения вероятностей следующего символа.
  4. Сэмплирование символа на основе распределения вероятностей (возможен контроль «температуры» генерации).
  5. Добавление нового символа к последовательности и повторение процесса.

Пример функции генерации одного символа:

async function sampleNextChar(model, inputSeq, temperature = 1.0) {
  const output = await model.predict({ input: inputSeq });
  const probs = output.data;
  // Применение температуры
  const adjustedProbs = probs.map(p => Math.pow(p, 1 / temperature));
  const sum = adjustedProbs.reduce((a, b) => a + b, 0);
  const normalizedProbs = adjustedProbs.map(p => p / sum);

  let r = Math.random();
  let cumulative = 0;
  for (let i = 0; i < normalizedProbs.length; i++) {
    cumulative += normalizedProbs[i];
    if (r < cumulative) return i;
  }
  return normalizedProbs.length - 1;
}

Температура генерации:

  • temperature < 1 делает распределение более «консервативным», символы с высокой вероятностью выбираются чаще.
  • temperature > 1 увеличивает разнообразие текста, появляется больше случайных символов.

Управление контекстом последовательности

Для генерации длинного текста важно поддерживать окно фиксированной длины:

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

Оптимизация производительности

  1. WebGL ускорение: установка gpu: true при инициализации модели позволяет использовать графический процессор для вычислений, что ускоряет генерацию.
  2. Минимизация повторного создания массивов: входные последовательности можно модифицировать на месте, чтобы уменьшить нагрузку на сборщик мусора.
  3. Сэмплинг в батчах: если генерация текста требуется в реальном времени, можно предсказать несколько символов одновременно и кэшировать результаты.

Примеры практического использования

  • Создание текстовых «ботов», имитирующих стиль автора.
  • Генерация кода на основе примеров.
  • Автозаполнение форм или редакторов текста.
  • Исследование языковых закономерностей в обученных корпусах.

Важные нюансы работы

  • Модели Keras.js только для инференса, обучение необходимо проводить на сервере или локальной машине с Python.
  • Размер модели напрямую влияет на скорость загрузки и генерации, особенно для больших RNN.
  • В браузере требуется контроль потребления памяти, особенно при больших словарях символов.

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