Библиотека Synaptic предоставляет возможность создавать нейронные
сети произвольной структуры, выходя за рамки стандартных полносвязных
слоёв. Основной элемент в этом подходе — нейрон, а сеть
формируется как граф из нейронов, связанных синапсами. Каждый нейрон
обладает свойствами activation, bias и набором
входящих и исходящих соединений.
const synaptic = require('synaptic');
const { Neuron, Layer, Network } = synaptic;
Нейроны можно связывать вручную через метод project:
let inputNeuron = new Neuron();
let hiddenNeuron = new Neuron();
inputNeuron.project(hiddenNeuron);
При этом создаётся синапс, который соединяет выход
inputNeuron с входом hiddenNeuron. Можно
задавать вес синапса вручную:
let connection = inputNeuron.project(hiddenNeuron);
connection.weight = 0.5;
Слой в Synaptic — это коллекция нейронов с набором удобных методов для массовых операций. Создание нестандартного слоя:
let customLayer = new Layer(3); // три нейрона в слое
Можно напрямую добавлять нейроны:
customLayer.add(new Neuron());
Все нейроны слоя можно соединять с другим слоем через
project:
customLayer.project(anotherLayer);
Для полного контроля над структурой можно соединять отдельные нейроны между слоями или внутри слоя.
Метод project поддерживает несколько вариантов:
Пример создания асимметричной топологии:
let inputLayer = new Layer(2);
let hiddenLayer = new Layer(3);
let outputNeuron = new Neuron();
// соединяем только первый нейрон inputLayer с outputNeuron
inputLayer.neurons()[0].project(outputNeuron);
// соединяем все нейроны hiddenLayer с outputNeuron
hiddenLayer.project(outputNeuron);
Это позволяет создавать сложные конфигурации с разной степенью связанности и пропускной способности сигналов.
Каждый нейрон по умолчанию использует сигмоидальную функцию
активации, но её можно изменять через переопределение метода
activate:
let neuron = new Neuron();
neuron.squash = Neuron.squash.TANH; // гиперболический тангенс
Вес синапса можно динамически изменять во время работы сети для реализации адаптивного поведения:
connection.weight += 0.1; // корректировка веса
Рекуррентные нейронные сети в Synaptic строятся путем соединения нейронов слоя с самим собой или с предыдущими слоями:
hiddenLayer.neurons().forEach(neuron => {
neuron.project(hiddenLayer); // самосвязь
});
Такая структура позволяет хранить состояние и учитывать прошлые значения при вычислениях.
Можно объединять несколько отдельных сетей в одну более крупную,
создавая сложные архитектуры. Для этого используется метод
Network:
let inputLayer = new Layer(2);
let hiddenLayer = new Layer(3);
let outputLayer = new Layer(1);
inputLayer.project(hiddenLayer);
hiddenLayer.project(outputLayer);
let network = new Network({
input: inputLayer,
hidden: [hiddenLayer],
output: outputLayer
});
В нестандартных топологиях можно включать несколько скрытых слоёв с перекрестными соединениями, создавать петли обратной связи и частично связные слои.
Для нестандартных сетей важно правильно формировать маски
входов и выходов. Активация сети выполняется через метод
activate:
let output = network.activate([0.5, 0.2]);
Обратное распространение ошибки (propagate) работает на
уровне сети независимо от топологии, если корректно указаны входы и
выходы:
network.propagate(0.3, [1]); // обучение с целевым выходом
Для рекуррентных или частично соединённых структур стоит вручную контролировать последовательность активаций нейронов.
Такой подход позволяет полностью контролировать архитектуру сети, создавать гибкие решения для специфических задач и экспериментировать с уникальными схемами обработки сигналов.