Скрещивание двух сетей

Библиотека Synaptic предоставляет удобный инструмент для создания, обучения и объединения нейронных сетей в JavaScript. Одним из продвинутых методов работы является скрещивание двух сетей, что позволяет создавать новые модели с комбинацией свойств исходных сетей.

Архитектура сетей в Synaptic

В Synaptic все нейронные сети строятся на основе нейронов (Neuron) и связей (Connection). Основные компоненты:

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

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

Скрещивание сетей: основные подходы

Скрещивание сетей — это процесс объединения двух или более сетей с целью получения новой сети, которая наследует характеристики исходных моделей. Основные методы:

  1. Прямое объединение весов (weight averaging) В этом методе создается новая сеть с той же архитектурой, что и исходные, и веса каждого нейрона вычисляются как среднее значение весов соответствующих нейронов из родительских сетей. Формула для нейрона (i) и связи (j):

    [ w_{ij}^{new} = ]

    Такой подход прост в реализации и позволяет сохранять общие свойства обеих сетей.

  2. Случайный выбор весов (random selection) Для каждого веса выбирается случайное значение из соответствующего веса одной из родительских сетей. Это создает разнообразие и иногда позволяет избежать застоя сети в локальном минимуме.

    for (let i = 0; i < neuron.connections.length; i++) {
        neuron.connections[i].weight = Math.random() < 0.5 
            ? parent1.neurons[i].connections[i].weight
            : parent2.neurons[i].connections[i].weight;
    }
  3. Частичное копирование слоев (layer swapping) Можно скрещивать сети на уровне слоев, полностью копируя один слой от одной сети и другой слой — от другой. Такой подход позволяет создавать гибридные архитектуры, где разные части сети имеют разные стратегии обучения.

Реализация скрещивания на примере

Для начала необходимо убедиться, что архитектура сетей идентична (одинаковое количество слоев и нейронов в каждом слое).

const synaptic = require('synaptic');
const { Layer, Network } = synaptic;

function crossoverNetworks(network1, network2) {
    const newNetwork = new Network();
    const neurons1 = network1.layers.input.list.concat(
        network1.layers.hidden[0].list,
        network1.layers.output.list
    );
    const neurons2 = network2.layers.input.list.concat(
        network2.layers.hidden[0].list,
        network2.layers.output.list
    );
    
    const newNeurons = neurons1.map((neuron, index) => {
        const newNeuron = new synaptic.Neuron();
        neuron.connections.projected.forEach((conn, i) => {
            const chosenWeight = Math.random() < 0.5 
                ? neurons1[index].connections.projected[i].weight
                : neurons2[index].connections.projected[i].weight;
            newNeuron.connections.projected[i].weight = chosenWeight;
        });
        return newNeuron;
    });
    
    newNetwork.layers.input = newLayerFromNeurons(newNeurons.slice(0, network1.layers.input.list.length));
    newNetwork.layers.hidden[0] = newLayerFromNeurons(newNeurons.slice(network1.layers.input.list.length, network1.layers.input.list.length + network1.layers.hidden[0].list.length));
    newNetwork.layers.output = newLayerFromNeurons(newNeurons.slice(-network1.layers.output.list.length));

    return newNetwork;
}

function newLayerFromNeurons(neurons) {
    const layer = new Layer(neurons.length);
    layer.list = neurons;
    return layer;
}

Применение скрещивания в обучении

Скрещивание сетей часто используется в генетических алгоритмах, где каждая сеть рассматривается как индивид популяции. Основные этапы процесса:

  • Создание начальной популяции сетей с случайными весами.
  • Оценка качества каждой сети по функции приспособленности.
  • Скрещивание лучших сетей для создания нового поколения.
  • Применение мутаций для сохранения разнообразия и избегания локальных минимумов.

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

Советы по эффективному скрещиванию

  • Веса и функции активации должны совпадать у скрещиваемых сетей, иначе возможны некорректные результаты.
  • Чаще всего полезно сочетать среднее весов и случайный выбор, чтобы сохранять стабильность и разнообразие.
  • После скрещивания сеть рекомендуется дополнительно дообучать, чтобы новые комбинации весов корректно адаптировались к задачам.

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