Brain.js — это библиотека для работы с нейронными сетями на JavaScript, ориентированная на простое обучение и предсказание. Одним из важных аспектов работы с нейронными сетями является понимание того, как изменяются веса и как вычисляются активации на каждом слое. Это особенно полезно при отладке или обучении сети на малых данных.
Нейронные сети в Brain.js строятся на основе слоев нейронов, каждый из которых имеет следующие ключевые элементы:
Для примера рассмотрим простую сеть с одним скрытым слоем:
const brain = require('brain.js');
const net = new brain.NeuralNetwork({
hiddenLayers: [3], // один скрытый слой с тремя нейронами
});
После обучения с помощью net.train(data) можно получить
веса и смещения сети через свойство net.toJSON().
Метод toJSON() возвращает объект, который содержит
структуру сети в формате:
{
"sizes": [2,3,1],
"layers": {
"0": {"0":{}, "1":{}, "2":{}},
"1": {"0":{}}
},
"outputLookup": true,
"inputLookup": true,
"trainOpts": {...}
}
sizes — массив, где каждый элемент соответствует
количеству нейронов в слое.layers — объект с индексами слоев и нейронов. Каждый
нейрон содержит поля bias и weights.Пример доступа к весам:
const json = net.toJSON();
const firstHiddenNeuron = json.layers[0][0];
console.log("Bias:", firstHiddenNeuron.bias);
console.log("Weights:", firstHiddenNeuron.weights);
Таким образом, можно вручную просмотреть индивидуальные веса каждого нейрона и их смещения.
Чтобы проверить, как сеть вычисляет выходные значения, можно реализовать пошаговое вычисление активации:
Для нейрона ( j ) в слое ( l ):
[ z_j = i w{ij} x_i + b_j]
где ( w_{ij} ) — вес от нейрона ( i ) предыдущего слоя к нейрону ( j ), ( x_i ) — выход нейрона предыдущего слоя, а ( b_j ) — смещение.
Brain.js по умолчанию использует sigmoid или relu, в зависимости от конфигурации сети:
function sigmoid(x) {
return 1 / (1 + Math.exp(-x));
}
Пример пошагового вычисления:
const input = [0.5, 0.8];
const neuron = json.layers[0][0]; // первый нейрон скрытого слоя
let z = neuron.bias;
for (const [key, weight] of Object.entries(neuron.weights)) {
z += input[key] * weight;
}
const output = 1 / (1 + Math.exp(-z)); // sigmoid
console.log("Активация нейрона:", output);
Этот метод позволяет сравнивать результаты ручного расчета с тем, что возвращает сеть, и выявлять возможные ошибки или неожиданные значения.
Для проверки всей сети можно пройтись по всем слоям:
function forwardPass(input, layers) {
let activations = input;
for (let l = 0; l < layers.length; l++) {
const layer = layers[l];
const nextActivations = [];
for (const key in layer) {
const neuron = layer[key];
let z = neuron.bias;
for (const [i, w] of Object.entries(neuron.weights)) {
z += activations[i] * w;
}
nextActivations.push(1 / (1 + Math.exp(-z)));
}
activations = nextActivations;
}
return activations;
}
console.log("Выход сети вручную:", forwardPass([0.5, 0.8], json.layers));
console.log("Выход сети Brain.js:", net.run([0.5, 0.8]));
Этот подход позволяет:
Этот подход является обязательным инструментом при работе с малым количеством данных или при необходимости тонкой настройки параметров сети.