Сохранение нейронной сети в JSON и другое: обучаем нейронную сеть на JavaScript

Когда речь идет о задачах, отличных от обработки больших массивов информации, человеческий мозг обладает большим преимуществом по сравнению с компьютером. Человек может распознавать лица, даже если в помещении будет много посторонних объектов и плохое освещение. Мы легко понимаем незнакомцев, даже когда находимся в шумном помещении. Но, несмотря на годы исследований, компьютеры все еще далеки от выполнения подобных задач на высоком уровне.

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

Сегодня нейронные сети популярны как никогда. Свои решения в этой области представляют такие компании, как Google, Microsoft и многие другие. Но существуют и библиотеки с открытым кодом, написанные энтузиастами на самых разных языках. Сегодня tproger расскажет вам об одной из них — это библиотека brain, написанная на JavaScript.

Использование

Самый простой пример применения — обучение на функции XOR:

var 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]}]);

var output = net.run([1, 0]); // 1

А еще есть очень классная визуализация того, как нейронная сеть обучается XOR, OR и другим логическим функциям.

Чтобы установить библиотеку, можно использовать, например, npm:

npm install brain

Можно также скачать последнюю версию brain.js. Тренировать сеть можно даже оффлайн, а затем уже натренированную загрузить на сайт.

Чтобы начать обучать сеть, нужно использовать функцию train(), в которую передаются данные для обучения в виде массива. Сеть будет обучаться всеми данными сразу в одном вызове train(). Чем больше моделей обучения — тем дольше сеть будет обучаться, но и справляться со своей задачей она после этого будет лучше.

Каждая модель для обучения должна иметь параметры input и output, каждый из которых составляет массив или хэш чисел от 0 до 1. Например, для демо с распознаванием контрастности цветов это выглядело так:

var net = new brain.NeuralNetwork();

net.train([{input: { r: 0.03, g: 0.7, b: 0.5 }, output: { black: 1 }},
           {input: { r: 0.16, g: 0.09, b: 0.2 }, output: { white: 1 }},
           {input: { r: 0.5, g: 0.5, b: 1.0 }, output: { white: 1 }}]);

var output = net.run({ r: 1, g: 0.4, b: 0 }); // { white: 0.99, black: 0.002 }

Функция train() умеет принимать в качестве второго аргумента массив нескольких параметров:

net.train(data, {
    errorThresh: 0.005, // порог ошибок, которого нужно достичь
    iterations: 20000, // максимальное число итераций обучения
    log: true, // нужен ли периодический console.log()
    logPeriod: 10, // число итераций между логированиями
    learningRate: 0.3 // степень обучения
})

Обучаться сеть будет до тех пор, пока не будет достигнут заданный порог ошибок (по умолчанию задается 0.005) или не будет совершено заданное число итераций (20000).

По умолчанию вы никак не можете определить, как много времени осталось до конца обучения, но зато можно поставить на true параметр log, чтобы отслеживать ход обучения. Если передать в качестве этого параметра функцию, то она будет вызываться каждый раз через каждое заданное число итераций.

learningRate — параметр, определяющий, как быстро натренируется нейронная сеть. Задается он числом от 0 до 1. Чем меньше параметр, тем дольше сеть будет обучаться. С увеличением числа скорость будет расти, но вместе с этим растет вероятность более плохого качества обучения. По умолчанию это число составляет 0.3.

Результатом обучения будет массив output с информацией о том, как прошло обучение.

{
    error: 0.0039139985510105032, // ошибки
    iterations: 406 // число итераций
}

Если обучение закончилось ошибкой, то параметр error будет близок к порогу ошибки. Причиной этому может стать излишняя «зашумленность» данных, недостаток нейронов или недостаточное число итераций. Если даже после 20000 итераций ошибка составила около 0.4, это может означать, что сеть плохо воспринимает предоставляемые вами данные.

Обученную сеть можно хранить в формате JSON:

var json = net.toJSON();

net.fromJSON(json);

Также можно данных сохранить в функцию:

var run = net.toFunction();

var output = run({ r: 1, g: 0.4, b: 0 });

console.log(run.toString()); // это нужно скопировать и вставить в нужное место. Подключать brain.js не требуется

NeuralNetwork() принимает ассоциативный массив параметров:

var net = new brain.NeuralNetwork({
    hiddenLayers: [4],
    learningRate: 0.6 // общая степень обученности, полезна при обучении в несколько потоков
});

Первый параметр — общее количество скрытых слоев и размер каждого слоя. Например, если нужно два скрытых слоя — один с 3 нодами и второй с 4, то параметр будет таким:

hiddenLayers: [3, 4]

По умолчанию brain использует один слой, пропорциональный размеру входного массива.

Кстати, сеть может использовать WriteStream. Ее можно тренировать, используя pipe(), чтобы отправлять данные в сеть.

Чтобы тренировать сеть в потоке, сначала нужно поток создать вызовом метода net.createTrainStream(), принимающего следующие параметры:

  • floodCallback() — функция, которая будет вызываться на каждой итерации обучения;
  • doneTrainingCallback(info) — функция, которая выполнится после завершения обучения. Параметр info будет содержать ассоциативный массив информации о том, как прошло обучение:
{
    error: 0.0039139985510105032, // ошибки
    iterations: 406 // число итераций
}

Также можно использовать Transform, чтобы привести данные к корректному формату или чтобы на лету нормализовывать данные.

  1. 987

Источник: GitHub