Хабрахабр

[Перевод] Как создать нейросеть всего из 30 строк JavaScript-кода

Перевод How to create a Neural Network in JavaScript in only 30 lines of code.

Давайте создадим простейшую нейросеть, решающую XOR-уравнение. В этой статье мы рассмотрим, как можно создать и обучить нейросеть с помощью библиотеки Synaptic.js, позволяющей проводить глубокое обучение в связке Node.js с браузером. Также можете изучить специально написанный интерактивный туториал.

Но прежде чем переходить к коду, давайте поговорим об основах нейросетей.

Нейроны и синапсы

Основной «строительный» элемент нейросети, конечно же, нейрон. Как и функция, он берёт несколько входных значений и выдаёт какой-то результат. Есть разные виды нейронов. Наша сеть будет использовать сигмоиды, берущие любые числа и сводящие их к значениям в диапазоне от 0 до 1. Ниже проиллюстрирован принцип действия такого нейрона. На входе у него число 5, а на выходе 1. Стрелки обозначают синапсы, соединяющие нейрон с другими уровнями нейросети.

Это сумма трёх синапсов, «входящих» в нейрон. Но почему на входе у нас число 5? Давайте разберёмся.

Сначала первые два значения умножаются на их веса, которые равны 7 и 3, полученные результаты складываются и к ним прибавляется байесово значение, получаем 5. Слева мы видим значения 1 и 0, а также байесово значение -2. Это и будет входным значением для нашего искусственного нейрона.

Если такие нейроны соединить друг с другом с помощью синапсов, то получится нейросеть, по которой значения проходят от входа к выходу и трансформируются. А поскольку это сигмоида, которая любое значение сводит к диапазону от 0 до 1, то выходным значением будет 1. Примерно так:

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

После каждой итерации вычисляется точность прогнозирования и корректируются веса и байесовы значения, чтобы в следующий раз ответ нейросети оказался чуть точнее. Для обучения вы просто даёте набор образцов и заставляете нейросеть обрабатывать их раз за разом, пока она не станет давать правильный ответ. Если провести тысячи итераций, то ваша нейросеть научится хорошо обобщать. Такой процесс обучения называется методом обратного распространения ошибки (backpropagation).

Но если вас интересуют подробности, то можете почитать эти статьи: Работу метода обратного распространения ошибки мы рассматривать не будем, это выходит за рамки нашего руководства.

Код

Первым делом создадим уровни, и сделаем это в синаптическом режиме с помощью функции new Layer(). Передаваемое ей число означает количество нейронов в свежем уровне. Если вы не знаете, что такое уровень, то посмотрите вышеупомянутый туториал.

const = window.synaptic;
var inputLayer = new Layer(2);
var hiddenLayer = new Layer(3);
var outputLayer = new Layer(1);

Теперь соединим уровни друг с другом и инстанцируем новую сеть.

inputLayer.project(hiddenLayer);
hiddenLayer.project(outputLayer);
var myNetwork = new Network({ input: inputLayer, hidden: [hiddenLayer], output: outputLayer
});

У нас получилась сеть по схеме 2–3–1, которая выглядит так:

Давайте её обучим:

// train the network - learn XOR
var learningRate = .3;
for (var i = 0; i < 20000; i++) { // 0,0 => 0 myNetwork.activate([0,0]); myNetwork.propagate(learningRate, [0]); // 0,1 => 1 myNetwork.activate([0,1]); myNetwork.propagate(learningRate, [1]); // 1,0 => 1 myNetwork.activate([1,0]); myNetwork.propagate(learningRate, [1]); // 1,1 => 0 myNetwork.activate([1,1]); myNetwork.propagate(learningRate, [0]);
}

Мы прогнали 20 000 итераций обучения. В каждой итерации данные четыре раза прогоняются вперёд-назад, то есть на вход подаются четыре возможные комбинации значений: [0,0] [0,1] [1,0] [1,1].

Это называется прямым распространением (forward propagation), или активацией нейросети. Начнём с выполнения myNetwork.activate([0,0]), где [0,0] — входные данные. После каждого прямого распространения нужно сделать обратное, при котором нейросеть обновляет свои веса и байесовы значения.

Второй параметр 0 представляет собой правильное выходное значение при входном [0,0]. Обратное распространение выполняется с помощью myNetwork.propagate(learningRate, [0]), где learningRate — константа, означающая, насколько нужно каждый раз корректировать веса.

Тем самым она определяет точность собственной работы. Далее нейросеть сравнивает получившееся выходное значение с правильным.

После 20 000 таких циклов можно проверить, насколько хорошо обучилась наша нейросеть, активировав её с помощью всех четырёх возможных входных значений: По результатам сравнения нейросеть корректирует веса и байесовы значения, чтобы в следующий раз ответить немного точнее.

console.log(myNetwork.activate([0,0])); -> [0.015020775950893527]
console.log(myNetwork.activate([0,1]));
->[0.9815816381088985]
console.log(myNetwork.activate([1,0]));
-> [0.9871822457132193]
console.log(myNetwork.activate([1,1]));
-> [0.012950087641929467]

Если округлить результаты до ближайших целочисленных значений, то получим точные ответы для XOR-уравнения. Работает!

Хотя мы лишь самую малость копнули тему нейросетей, вы уже можете самостоятельно поэкспериментировать с Synaptic и продолжить самообучение. На этом всё. В wiki авторов библиотеки есть ещё много хороших руководств.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть