Как да създадете невронна мрежа в JavaScript само в 30 реда код

В тази статия ще ви покажа как да създадете и обучите невронна мрежа с помощта на Synaptic.js, което ви позволява да правите задълбочено обучение в Node.js и браузъра.

Ще създадем възможно най-простата невронна мрежа: такава, която успява да реши XOR уравнението.

Създал съм и интерактивен урок за Scrimba на този пример, така че проверете и това:

В урока за Scrimba ще можете да си играете с кода, когато пожелаете.

Или ако се интересувате от пълен курс по невронни мрежи в JavaScript, моля, разгледайте нашия безплатен курс по Brain.js в Scrimba.

Щракнете върху изображението, за да стигнете до курса

Но преди да разгледаме кода, нека разгледаме самите основи на невронните мрежи.

Неврони и синапси

Първият градивен елемент на невронната мрежа са невроните.

Невронът е като функция, отнема няколко входа и връща изход.

Има много различни видове неврони. Нашата мрежа ще използва сигмоидни неврони, които вземат дадено число и го смачкат до стойност между 0и 1.

Кръгът по-долу илюстрира сигмоиден неврон. Неговият вход е 5и изходът му е 1. Стрелките се наричат ​​синапси, които свързват неврона с други слоеве в мрежата.

И така, защо е червеното число 5? Защото това е сумата от трите синапса, които се свързват с неврона, както е показано от трите стрелки вляво. Нека разопаковаме това.

Най-вляво виждаме две стойности плюс така наречената пристрастна стойност. Стойностите са 1и 0кои са зелените числа. Стойността на отклонението е -2кое е кафявото число.

Първо, двата входа се умножават с техните тегла , които са 7и 3както е показано със сините числа.

Накрая го събираме с пристрастието и завършваме с 5или червеното число. Това е входът за нашия изкуствен неврон.

Тъй като това е сигмоиден неврон, който смачква всяка стойност между 0 и 1, изходът се свива до 1.

Ако свържете мрежа от тези неврони заедно, имате невронна мрежа. Това се разпространява напред от входа към изхода, чрез неврони, които са свързани помежду си чрез синапси. Подобно на изображението по-долу:

Целта на невронната мрежа е да я обучи да прави обобщения, като разпознаване на ръчно написани цифри или нежелана поща по имейл. И да бъдеш добър в обобщаването е въпрос на наличието на правилните тегла и стойности на пристрастия в мрежата. Както при сините и кафявите числа в нашия пример по-горе.

Когато обучавате мрежата, просто й показвате купища примери като ръкописни цифри и получавате мрежата да предскаже правилния отговор.

След всяка прогноза ще изчислите колко грешна е  била прогнозата и ще коригирате теглата и стойностите на пристрастия, така че мрежата да отгатне малко по-правилно следващия път. Този процес на обучение се нарича обратно размножаване. Правете това хиляди пъти и вашата мрежа скоро ще стане добра в обобщаването.

Начинът, по който обратното размножаване работи технически, е извън обхвата на този урок, но ето трите най-добри източника, които намерих за разбирането му:

  • Пример за размножаване стъпка по стъпка - от Мат Мазур
  • Ръководство за хакери за невронни мрежи - от Андрей Карпати
  • NeuralNetworksAndDeepLarning - от Майкъл Нилсен

Кодът

Сега, след като сте получили основно въведение, нека преминем към кода. Първото нещо, което трябва да направим, е да създадем слоевете. Правим това с new Layer()функцията в synaptic. Броят, предаден на функцията, диктува колко неврони трябва да има всеки слой.

Ако сте объркани относно слоя , проверете скринкаста по-горе.

const {Layer, Network} = window.synaptic;

var inputLayer = нов слой (2);

var hiddenLayer = нов слой (3);

var outputLayer = нов слой (1);

След това ще свържем тези слоеве заедно и ще създадем нова мрежа, като тази:

inputLayer.project (hiddenLayer);

hiddenLayer.project (outputLayer);

var myNetwork = нова мрежа ({

вход: inputLayer,

скрито: [hiddenLayer],

изход: outputLayer

});

Това е 2–3–1 мрежа, която може да се визуализира по следния начин:

Сега нека обучим мрежата:

// train the network - learn XOR var learningRate = .3; for (var i = 0; i  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].

Започваме с това myNetwork.activate([0,0]), къде [0,0]е точката с данни, която изпращаме в мрежата. Това е разпространението напред, наричано още активиране  на мрежата. След всяко разпространение напред трябва да направим обратното разпространение, където мрежата актуализира собствените си тегла и пристрастия.

The backpropagation is done with this line of code: myNetwork.propagate(learningRate, [0]), where the learningRate is a constant that tells the network how much it should adjust its weights each time. The second parameter 0 represents the correct output given the input [0,0].

The network then compares its own prediction to the correct label. This tells it how right or wrong it was.

It uses the comparison as a basis for correcting its own weights and bias values so that it will guess a little bit more correct the next time.

After it has done this process 20,000 times, we can check how well our network has learned by activating the network with all four possible inputs:

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] 

If we round these values to the closest integer, we’ll get the correct answers for the XOR equation. Hurray!

И това е всичко. Въпреки че току-що надраскахме повърхността на невронните мрежи, това трябва да ви даде достатъчно, за да започнете да играете със Synaptic за себе си и да продължите да учите сами. Техният wiki съдържа много добри уроци.

И накрая, не забравяйте да споделите знанията си, като създадете скрийнскаст на Scrimba или напишете статия, когато научите нещо ново! :)

PS: Имаме още безплатни курсове за вас!

Ако търсите следващото си предизвикателство, имаме няколко други безплатни курса, които можете да проверите на Scrimba.com. Ето три може да са от значение за вас:

  • Невронни мрежи в JavaScript
  • Въведение в ES6 +
  • Научете D3 JS

Приятно кодиране!