Библиотека Synaptic предоставляет низкоуровневые
возможности для работы с нейронными сетями, позволяя создавать обучающие
циклы вручную, без использования встроенного класса
Trainer. Такой подход необходим для тонкой настройки
процесса обучения, реализации нестандартных функций потерь или
специфических алгоритмов оптимизации.
Основой является объект Network или заранее созданные
компоненты Layer, Neuron. Для простейшей сети
достаточно связать слои через Layer.project():
const { Layer, Network } = require('synaptic');
const inputLayer = new Layer(2);
const hiddenLayer = new Layer(3);
const outputLayer = new Layer(1);
inputLayer.project(hiddenLayer);
hiddenLayer.project(outputLayer);
const myNetwork = new Network({
input: inputLayer,
hidden: [hiddenLayer],
output: outputLayer
});
Ключевые моменты:
Layer.project() устанавливает полное соединение между
слоями.Network можно создать вручную, указав входной,
скрытый и выходной слои, что позволяет гибко манипулировать
архитектурой.Для получения выходных данных сети используется метод
activate. Он принимает массив значений входного слоя и
возвращает массив выходов:
const input = [0.5, 0.8];
const output = myNetwork.activate(input);
console.log(output); // [0.73] — примерное значение после инициализации
Особенности прямого прохода:
sigmoid, tanh, relu).Метод propagate выполняет шаг обратного распространения
ошибки:
const learningRate = 0.1;
const target = [1];
myNetwork.propagate(learningRate, target);
Принципы работы:
target и фактическим output.learningRate регулирует размер шага изменения весов.
Мелкие значения дают стабильное обучение, большие ускоряют сходимость,
но могут вызвать раскачку сети.Основной цикл состоит из нескольких шагов:
activate).propagate).Пример реализации простого цикла:
const trainingSet = [
{ input: [0, 0], output: [0] },
{ input: [0, 1], output: [1] },
{ input: [1, 0], output: [1] },
{ input: [1, 1], output: [0] }
];
const epochs = 10000;
const learningRate = 0.3;
for (let epoch = 0; epoch < epochs; epoch++) {
let totalError = 0;
for (const data of trainingSet) {
const output = myNetwork.activate(data.input);
myNetwork.propagate(learningRate, data.output);
totalError += output.reduce((sum, val, i) => sum + Math.pow(data.output[i] - val, 2), 0);
}
if (epoch % 1000 === 0) {
console.log(`Epoch ${epoch}, Error: ${totalError.toFixed(4)}`);
}
}
Выделенные моменты цикла:
propagate вызывается после каждого примера — это
вариант online learning. Для batch
learning ошибки можно аккумулировать и применять после полного
прохода по набору данных.Synaptic позволяет изменять отдельные веса, смещения и функции активации:
hiddenLayer.list.forEach(neuron => {
neuron.bias = Math.random() - 0.5;
});
hiddenLayer.set({
squash: require('synaptic').Neuron.squash.TANH
});
neuron.bias регулирует смещение нейрона.squash задаёт функцию активации: LOGISTIC,
TANH, RELU.Для оценки прогресса обучения полезно:
learningRate.hiddenLayer.list.forEach(neuron => {
neuron.connections.projected.forEach(conn => {
console.log(`Weight: ${conn.weight.toFixed(4)}`);
});
});
Вручную можно реализовать:
learningRate динамически в зависимости от ошибки.Пример простой адаптации коэффициента обучения:
let lr = 0.5;
for (let epoch = 0; epoch < epochs; epoch++) {
trainingSet.forEach(data => {
myNetwork.activate(data.input);
myNetwork.propagate(lr, data.output);
});
lr *= 0.999; // постепенное уменьшение
}
Такой подход открывает полный контроль над процессом обучения,
позволяет интегрировать сложные алгоритмы оптимизации, кастомные функции
потерь и экспериментировать с архитектурой сети без ограничений,
накладываемых встроенным Trainer.