Як створити нейронну мережу в 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 {Шар, Мережа} = window.synaptic;

var inputLayer = новий шар (2);

var hiddenLayer = новий шар (3);

var outputLayer = новий шар (1);

Далі ми з’єднаємо ці шари разом і створимо інстанцію нової мережі, наприклад:

inputLayer.project (hiddenLayer);

hiddenLayer.project (outputLayer);

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

input: 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 для себе і продовжувати вчитися самостійно. Їхня вікі містить багато хороших підручників.

Нарешті, обов’язково поділіться своїми знаннями, створивши скринкаст Scrimba або написавши статтю, коли дізнаєтесь щось нове! :)

PS: У нас є більше безкоштовних курсів для вас!

Якщо ви шукаєте свій наступний виклик, у нас є кілька інших безкоштовних курсів, які ви можете переглянути на Scrimba.com. Ось три, які можуть бути для вас актуальними:

  • Нейронні мережі в JavaScript
  • Вступ до ES6 +
  • Дізнайтеся D3 JS

Щасливого кодування!