Создание сети из слоёв вручную

В библиотеке Synaptic нейронная сеть строится из трёх базовых компонентов: нейрон, слой и сеть. Каждый слой представляет собой набор нейронов, объединённых для выполнения определённой функции. В отличие от автоматических конструкторов сети, ручное создание слоёв позволяет полностью контролировать архитектуру и параметры сети.

Слои создаются с помощью класса Layer. Основной синтаксис:

const Layer = require('synaptic').Layer;
let слой = new Layer(количество_нейронов);

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

Соединение слоёв

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

let входной = new Layer(3);
let скрытый = new Layer(4);
let выходной = new Layer(2);

входной.project(скрытый);
скрытый.project(выходной);

По умолчанию создаются полносвязные соединения: каждый нейрон предыдущего слоя соединяется с каждым нейроном следующего. Для более сложной настройки можно использовать объекты Layer.connectionType, включая односторонние соединения, рециркуляцию и произвольные маски соединений.

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

Каждый нейрон слоя по умолчанию использует сигмоидную функцию активации. Для изменения функции активации можно модифицировать нейроны после создания слоя или применять собственные методы активации. Пример:

const Neuron = require('synaptic').Neuron;
let нейрон = new Neuron();
нейрон.squash = Neuron.squash.TANH;

Для слоя это можно сделать через обход нейронов:

скрытый.neurons().forEach(n => n.squash = Neuron.squash.TANH);

Создание сети из слоёв

После определения слоёв и соединений их объединяют в сеть с помощью класса Network. Основной подход — передать объект с массивами слоёв и связями:

const Network = require('synaptic').Network;

let сеть = new Network({
    input: входной,
    hidden: [скрытый],
    output: выходной
});

Сеть можно запускать на входных данных методом activate, который возвращает массив значений на выходном слое:

let результат = сеть.activate([0.5, 0.2, 0.1]);

Обратное распространение ошибки осуществляется методом propagate:

сеть.propagate(0.3, [0.1, 0.9]);

Многослойные и рекуррентные соединения

Библиотека позволяет строить сложные сети с несколькими скрытыми слоями и рекуррентными связями. Для многослойной сети создаются несколько слоёв и соединяются последовательно:

let скрытый2 = new Layer(5);
скрытый.project(скрытый2);
скрытый2.project(выходной);

Для рекуррентных соединений используется метод project с аргументом Layer.connectionType.ALL_TO_ALL и установкой свойства recurrent = true. Это позволяет строить сети с памятью, где выход одного слоя возвращается на вход того же слоя или предыдущего.

Масштабирование и инициализация весов

Вес каждого синапса инициализируется случайным образом в диапазоне [-1, 1]. Для контроля можно использовать метод set на соединениях слоя:

let соединения = входной.project(скрытый);
соединения.connections.forEach(c => c.weight = Math.random() * 0.2 - 0.1);

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

Активация и обратное распространение на уровне слоёв

Методы activate и propagate могут применяться не только к сети целиком, но и к отдельным слоям. Это даёт возможность строить частично обучаемые сети и экспериментировать с гибридными архитектурами:

скрытый.activate([0.3, 0.7, 0.1, 0.5]);
скрытый.propagate(0.5, [0.1, 0.9, 0.2, 0.3]);

Управление связями между нейронами

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

входной.neurons()[0].project(скрытый.neurons()[2], { weight: 0.5 });

Подобные операции дают полный контроль над структурой сети на микроуровне.

Использование пользовательских функций для обучения

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

сеть.propagate(скорость_обучения, целевые_значения);

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

Выводы о подходе ручного создания

Ручное создание слоёв в Synaptic даёт:

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

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