Простой генератор текста посимвольно

Библиотека Synaptic представляет собой чисто JavaScript-фреймворк для создания и обучения нейронных сетей. Для использования в Node.js необходимо выполнить установку через npm:

npm install synaptic

После установки подключение производится стандартным способом:

const synaptic = require('synaptic');

Для работы в браузере библиотека доступна через CDN:

<script src="https://cdn.jsdelivr.net/npm/synaptic@1.1.4/dist/synaptic.js"></script>

Основные компоненты Synaptic

Synaptic строится вокруг трёх ключевых объектов:

  • Neuron — отдельный нейрон, реализующий активацию и передачу сигналов.
  • Layer — слой нейронов, способный принимать входные данные и выдавать выходные.
  • Network — сеть, объединяющая несколько слоев в полноценную архитектуру.

Для генератора текста посимвольно удобно использовать Feedforward Network, состоящую из входного слоя, скрытых слоёв и выходного слоя.

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

Для посимвольной генерации необходимо:

  1. Составить словарь символов текста.
  2. Преобразовать каждый символ в one-hot-вектор.
  3. Создать последовательности фиксированной длины, которые будут использоваться как входные данные сети.

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

const text = "hello world";
const chars = Array.from(new Set(text));
const charToIndex = {};
const indexToChar = {};

chars.forEach((char, index) => {
    charToIndex[char] = index;
    indexToChar[index] = char;
});

function charToVector(char) {
    const vector = Array(chars.length).fill(0);
    vector[charToIndex[char]] = 1;
    return vector;
}

function vectorToChar(vector) {
    return indexToChar[vector.indexOf(Math.max(...vector))];
}

Создание архитектуры сети

Для генератора текста оптимальна следующая структура:

  • Входной слой — размер равен количеству символов в словаре.
  • Один или два скрытых слоя — размер выбирается экспериментально (обычно 50–100 нейронов).
  • Выходной слой — размер равен количеству символов, с функцией активации softmax.

Пример создания сети:

const { Layer, Network } = synaptic;

const inputLayer = new Layer(chars.length);
const hiddenLayer = new Layer(100);
const outputLayer = new Layer(chars.length);

inputLayer.project(hiddenLayer);
hiddenLayer.project(outputLayer);

const myNetwork = new Network({
    input: inputLayer,
    hidden: [hiddenLayer],
    output: outputLayer
});

Настройка и обучение сети

Для обучения можно использовать стандартный Trainer, который поддерживает различные методы оптимизации. В случае посимвольного генератора удобен метод backpropagation.

Подготовка обучающих примеров:

const trainingData = [];
const seqLength = 3;

for (let i = 0; i < text.length - seqLength; i++) {
    const inputSeq = text.slice(i, i + seqLength).split('').map(charToVector);
    const outputChar = charToVector(text[i + seqLength]);
    
    // Сглаживаем входной массив в один вектор
    const inputFlat = [].concat(...inputSeq);
    
    trainingData.push({
        input: inputFlat,
        output: outputChar
    });
}

Обучение сети:

const Trainer = synaptic.Trainer;
const trainer = new Trainer(myNetwork);

trainer.train(trainingData, {
    rate: 0.1,
    iterations: 2000,
    error: 0.005,
    shuffle: true,
    log: 100
});

Генерация текста

Для генерации текста необходимо:

  1. Задать начальную последовательность символов.
  2. Прогонять её через сеть, получать вероятностное распределение следующего символа.
  3. Выбирать символ с наибольшей вероятностью или с вероятностной выборкой.
  4. Добавлять выбранный символ к последовательности и повторять процесс.

Пример генерации:

function generateText(seed, length = 50) {
    let result = seed;
    let inputSeq = seed.split('').map(charToVector);

    for (let i = 0; i < length; i++) {
        const inputFlat = [].concat(...inputSeq);
        const output = myNetwork.activate(inputFlat);
        
        // Выбираем наиболее вероятный символ
        const nextChar = vectorToChar(output);
        result += nextChar;
        
        inputSeq.push(charToVector(nextChar));
        inputSeq.shift(); // поддерживаем длину последовательности
    }

    return result;
}

console.log(generateText("hel"));

Настройка параметров генерации

  • Длина последовательности (seqLength) — влияет на способность сети учитывать контекст.
  • Размер скрытых слоёв — больше нейронов увеличивает способность сети к запоминанию, но замедляет обучение.
  • Скорость обучения (rate) — слишком высокая скорость может привести к расходимости, слишком низкая — к медленному обучению.
  • Итерации — количество циклов обучения; оптимально подбирать экспериментально.

Оптимизация работы

Для улучшения генерации текста полезно:

  • Использовать dropout или случайное шумовое смещение, чтобы уменьшить переобучение.
  • Пробовать разные функции активации для скрытых слоёв (sigmoid, tanh).
  • Экспериментировать с методами выбора следующего символа, например, случайная выборка на основе вероятности вместо жёсткого выбора максимума.

Гибкая настройка этих параметров позволяет создавать генераторы текста с разнообразным стилем и степенью предсказуемости.