Инструменты: Jest, Mocha в связке с Brain.js

Brain.js — это JavaScript-библиотека для создания нейронных сетей, работающая как в Node.js, так и в браузере. Основным элементом является объект NeuralNetwork или NeuralNetworkGPU, предоставляющий методы для обучения, прогнозирования и настройки структуры сети. Подключение производится через пакетный менеджер npm:

const brain = require('brain.js');
const net = new brain.NeuralNetwork();

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

const net = new brain.NeuralNetwork({
  hiddenLayers: [10, 20],
  activation: 'relu', // или 'sigmoid', 'tanh'
  learningRate: 0.01
});

Формат данных для обучения

Обучение сети происходит на массиве объектов с полями input и output. input представляет собой входные данные в виде массива или объекта чисел, а output — желаемый результат. Пример для распознавания чисел:

const trainingData = [
  { input: [0, 0], output: [0] },
  { input: [0, 1], output: [1] },
  { input: [1, 0], output: [1] },
  { input: [1, 1], output: [0] }
];

net.train(trainingData, { iterations: 20000, errorThresh: 0.005 });

Метод train возвращает объект с информацией о процессе обучения, включая окончательную ошибку и количество итераций. Для прогнозирования используется метод run:

const output = net.run([1, 0]); // Вернёт приблизительное значение 1

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

Для проверки корректности работы сети используют Jest. Основной подход — сравнивать фактический результат сети с ожидаемым. Создаётся отдельный файл тестов, например network.test.js:

const brain = require('brain.js');

test('Искусственная нейронная сеть корректно обучается XOR', () => {
  const net = new brain.NeuralNetwork();
  net.train([
    { input: [0, 0], output: [0] },
    { input: [0, 1], output: [1] },
    { input: [1, 0], output: [1] },
    { input: [1, 1], output: [0] }
  ], { iterations: 5000 });

  const result = net.run([1, 0]);
  expect(result[0]).toBeCloseTo(1, 1); // округление до 1 знака после запятой
});

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

Тестирование с Mocha и Chai

Mocha в сочетании с Chai даёт более гибкую структуру для комплексных тестов. Пример использования:

const { expect } = require('chai');
const brain = require('brain.js');

describe('Тестирование нейронной сети XOR', function() {
  let net;

  before(function() {
    net = new brain.NeuralNetwork();
    net.train([
      { input: [0, 0], output: [0] },
      { input: [0, 1], output: [1] },
      { input: [1, 0], output: [1] },
      { input: [1, 1], output: [0] }
    ], { iterations: 5000 });
  });

  it('возвращает близкий к 1 результат для [1, 0]', function() {
    const output = net.run([1, 0]);
    expect(output[0]).to.be.closeTo(1, 0.1);
  });

  it('возвращает близкий к 0 результат для [0, 0]', function() {
    const output = net.run([0, 0]);
    expect(output[0]).to.be.closeTo(0, 0.1);
  });
});

Использование before позволяет настроить сеть один раз для нескольких тестов, экономя время на обучение. Chai обеспечивает удобные методы для проверки приближённых значений (closeTo), логических условий (true, false) и диапазонов чисел.

Параметры обучения и их влияние на тесты

  • iterations — количество циклов обучения. Чем выше, тем точнее сеть, но дольше время выполнения.
  • learningRate — скорость изменения весов. Слишком большая скорость может приводить к нестабильному обучению, слишком маленькая — к медленному.
  • errorThresh — порог ошибки для завершения обучения. Позволяет автоматически остановить обучение при достижении нужной точности.

Тесты должны учитывать приближённость результатов, так как значения сети никогда не будут строго 0 или 1.

Интеграция тестов в CI/CD

Jest и Mocha легко интегрируются с системами непрерывной интеграции. Для этого достаточно добавить скрипт в package.json:

"scripts": {
  "test": "jest",
  "test:mocha": "mocha"
}

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

Практические рекомендации

  • Всегда нормализовать данные: Brain.js лучше работает с числами в диапазоне 0–1.
  • Разделять обучение и тестирование на разные наборы данных для предотвращения переобучения.
  • Для сложных задач использовать NeuralNetworkGPU для ускоренного обучения на видеокарте.
  • Тесты должны проверять как отдельные входы, так и набор типичных сценариев, чтобы выявить слабые места сети.

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