Принципы построения нейронных сетей. Пишем простую нейросеть на JavaScript

Konstantin
Konstantin Ostrovsky
2018-12-18 09:18:43
836

Рассмотрим базовые принципы работы нейронных сетей, узнаем про Brain.js и попробуем подкрепить теорию на практике. Напишем свою первую нейронную сеть, которая будет уметь чуть больше чем ничего, но чуть меньше чем что-то. Статья не претендует на пособие по разработке нейронных сетей, я постараюсь дать Вам базовые знания и представления о работе нейросетей, которыми обладаю сам>

Введем понятие ИНС - искусственная нейронная сеть. т.e. сеть построенная при помощи компьютерной системы;

НС - нейронная сеть мозга человека.

Что такое ИНС?

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

Давайте начнем с Вашего представления о ИНС. Исходя из общепринятых знаний, многие думают что ИНС представляют собой копию человеческой НС в коре головного мозга. Некий набор алгоритмов и накопленных знаний, благодаря которым сеть принимает дальнейшие решения. Это суждение верно, но не стоит переоценивать ее возможности. Если наша ИНС умеет варить Вам кофе с утра, то вряд ли она сможет приготовить Вам завтрак, если Вы сами ее этому не научите. Из этого можно сделать вывод, что ИНС выполняет лишь те функции, которым она обучена. Самообучающиеся нейронные сети это не миф, но пока еще не удалось разработать стабильную сеть, которая самостоятельно генерировала бы алгоритмы для решения различных задач.

Для понимания устройства нейронной сети давайте немного окунемся в биологию и устройство человеческого мозга и проведем некоторые параллели с устройством ИНС. Это не так сложно, как может показаться! 

Нейронная сеть (биологическая нейронная сеть) — совокупность нейронов головного и спинного мозга центральной нервной системы (ЦНС) и ганглия периферической нервной системы (ПНС), которые связаны или функционально объединены в нервной системе, выполняют специфические физиологические функции.

Нейронная сеть состоит из группы или групп химически или функционально связанных нейронов. Один нейрон может быть связан со многими другими нейронами, а общее количество нейронов и связей в сети может быть достаточно большим. Место контакта нейронов называется синапсом, типичный синапс — аксо-дендритический химический. Передача импульсов осуществляется химическим путём с помощью медиаторов или электрическим путём посредством прохождения ионов из одной клетки в другую.

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

Давайте более подробно разберем это определение. Из него следует что нейронная сеть представляет собой некоторое количество нейронов, связанных между собой. Сколько нейронов в мозге человека? По подсчетам многих ученых, мозг человека состоит из порядка 100 миллиардов нейронов (плюс-минус пара миллиардов). Именно эта цифра долгие годы приводилась в учебниках по нейробиологии и психологии. Каждый из нейронов является вычислительной единицей, которая обрабатывает входящую информацию и передает ее дальше. Для получения информации у нейрона есть входные каналы, которые называются синапсы. Синапсы это каналы, по которым в нейрон поступает информация из других нейронов. На рисунке синапсы обозначены буквой W, а другие нейроны буквой X. Каждый синапс обладает весом, чем больше вес синапса, тем больше результат работы нейрона будет преобладать в дальнейших вычислениях. Рассмотрим работу синапсов на примере изображения:

Разноцветные круги слева - нейроны. Линиями изображены синапсы. Как видно, каждый синапс обладает весом. Этот вес проставляется случайным образом в диапазоне от 0 до 1. На изображении справа изображена работа сумматора. Сумматор - это функция, которая рассчитывает вес входных сигналов и передает их дальше в функцию активации, об этом чуть позже. Давайте попробуем рассчитать вес входных сигналов, если результаты работы нейронов были следующие:

  • 1 - 0.35
  • 2 - 0.12
  • 3 - 0.6

Важно понимать что ИНС оперирует данными в диапазоне от 0 до 1. Вычисление веса в сумматоре производится пос следующей формуле:

(L1 * W1) +  (L2 * W2) + (L3 * W3) = W

Функция совершенно линейна, из этого мы получаем следующую формулу:

(0.35 * 0.1) + (0.12 * 0.3) + (0.6 * 0.2) = 0.191

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

Функция активации — это способ нормализации входных данных. То есть, если на входе у вас будет большое число, пропустив его через функцию активации, вы получите выход в нужном вам диапазоне.

Функций активации достаточно много поэтому мы рассмотрим самые основные: Линейная, Сигмоид (Логистическая) и Гиперболический тангенс. Главные их отличия — это диапазон значений.

Линейная функция


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

Сигмоид


Это самая распространенная функция активации, ее диапазон значений [0,1]. Именно на ней показано большинство примеров в сети, также ее иногда называют логистической функцией. Соответственно, если в вашем случае присутствуют отрицательные значения (например, акции могут идти не только вверх, но и вниз), то вам понадобиться функция которая захватывает и отрицательные значения.

Гиперболический тангенс

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


Подведем итоги. Что мы узнали про ИНС?

У нейрона есть входы. На них подаются сигналы в виде чисел. Каждый вход имеет свой вес (тоже число). Сигналы на входе умножаются на соответствующие веса. Получаем набор «взвешенных» входных сигналов.

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

Затем взвешенная сумма преобразуется функцией активации и мы получаем выход нейрона.

Виды ИНС

Мы разобрались со структурой искусственного нейрона. Искусственные нейронные сети состоят из совокупности искусственных нейронов. Возникает логичный вопрос – а как располагать/соединять друг с другом эти самые искусственные нейроны?

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

На этом схожесть заканчивается и начинаются различия...

Однослойные нейронные сети

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

Выглядит однослойная нейронная сеть следующим образом:

На этой картинке входной слой обозначен кружками (он не считается за слой нейронной сети), а справа расположен слой обычных нейронов.

Нейроны соединены друг с другом стрелками. Над стрелками расположены веса соответствующих связей (весовые коэффициенты).

Однослойная нейронная сеть (Single-layer neural network) — сеть, в которой сигналы от входного слоя сразу подаются на выходной слой, который и преобразует сигнал и сразу же выдает ответ.

Многослойные нейронные сети

Такие сети, помимо входного и выходного слоев нейронов, характеризуются еще и скрытым слоем (слоями). Понять их расположение просто – эти слои находятся между входным и выходным слоями.

Такая структура нейронных сетей копирует многослойную структуру определенных отделов мозга.

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

Многослойные нейронные сети обладают гораздо большими возможностями, чем однослойные.

Работу скрытых слоев нейронов можно сравнить с работой большого завода. Продукт (выходной сигнал) на заводе собирается по стадиям. После каждого станка получается какой-то промежуточный результат. Скрытые слои тоже преобразуют входные сигналы в некоторые промежуточные результаты.

Сети прямого распространения

Можно заметить одну очень интересную деталь на картинках нейросетей в примерах выше.

Во всех примерах стрелки строго идут слева направо, то есть сигнал в таких сетях идет строго от входного слоя к выходному.

Сети прямого распространения (Feedforward neural network) (feedforward сети) — искусственные нейронные сети, в которых сигнал распространяется строго от входного слоя к выходному. В обратном направлении сигнал не распространяется.

Такие сети широко используются и вполне успешно решают определенный класс задач: прогнозирование, кластеризация и распознавание.

Однако никто не запрещает сигналу идти и в обратную сторону.

Сети с обратными связями

В сетях такого типа сигнал может идти и в обратную сторону. В чем преимущество?

Дело в том, что в сетях прямого распространения выход сети определяется входным сигналом и весовыми коэффициентами при искусственных нейронах.

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

Возможность сигналов циркулировать в сети открывает новые, удивительные возможности нейронных сетей. С помощью таких сетей можно создавать нейросети, восстанавливающие или дополняющие сигналы. Другими словами такие нейросети имеют свойства кратковременной памяти (как у человека).

Классификация ИНС

Как уже стало известно, невозможно написать ИНС для всех нужд и потребностей, поэтому перед учеными появилась задача: классифицировать ИНС по назначению. Из наиболее распространенных назначений ИНС можно выделить следующие:

Классификация образов. Задача состоит в указании принадлежности входного образа (например, речевого сигнала или рукописного символа), представленного вектором признаков, одному или нескольким предварительно определенным классам. К известным приложениям относятся распознавание букв, распознавание речи, классификация сигнала электрокардио-граммы, классификация клеток крови, обеспечение деятельности биометрических сканеров и т. п.

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

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

Предсказание/прогноз. Пусть заданы n дискретных отсчетов {y (t1), y (t2)..., y (tn)} в последовательные моменты времени t1, t2,..., tn. Задача состоит в предсказании значения y (tn+1) в некоторый будущий момент времени tn+1. Предсказание/прогноз имеют значительное влияние на принятие решений в бизнесе, науке и технике. Предсказание цен на фондовой бирже и прогноз погоды являются типичными приложениями техники предсказания/прогноза.

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

Память, адресуемая по содержанию (ассоциативная память). В модели вычислений фон Неймана обращение к памяти доступно только посредством адреса, который не зависит от содержания памяти. Более того, если допущена ошибка в вычислении адреса, то может быть найдена совершенно иная информация. Ассоциативная память доступна по указанию заданного содержания. Содержимое памяти может быть вызвано даже по частичному входу или искаженному содержанию. Ассоциативная память может прекрасно найти применение при создании мультимедийных информационных баз данных.

Управление. Рассмотрим динамическую систему, заданную совокупностью векторов входного управляющего воздействия, текущего состояния, выходного вектора системы. Классической постановкой задачи является расчет
управляющего воздействия, чтобы в конкретный момент времени система находилась в определенной желаемой точке. Примером является оптимальное управление двигателем, рулевое управление на кораблях, самолетах.

Отлично! Но как научить сеть делать то, что я от нее хочу? Может нужно помочь ей? Или она сама себя обучит? 

Искусственная нейронная сеть – это совокупность искусственных нейронов. Теперь давайте возьмем, например, 100 нейронов и соединим их друг с другом. Ясно, что при подаче сигнала на вход, мы получим что-то бессмысленное на выходе.

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

Что мы можем менять в нейронной сети?

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

Сумматор изменить не получится, так как он выполняет одну жестко заданную функцию – складывать. Если мы его заменим на что-то или вообще уберем, то это вообще уже не будет искусственным нейроном.

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

Остается только один вариант – менять веса связей.

Обучение нейронной сети (Training) — поиск такого набора весовых коэффициентов, при котором входной сигнал после прохода по сети преобразуется в нужный нам выходной.

Такой подход к термину «обучение нейронной сети» соответствует и биологическим нейросетям. Наш мозг состоит из огромного количества связанных друг с другом нейросетей. Каждая из них в отдельности состоит из нейронов одного типа (функция активации одинаковая). Мы обучаемся благодаря изменению синапсов – элементов, которые усиливают/ослабляют входной сигнал.

Однако есть еще один важный момент. Если обучать сеть, используя только один входной сигнал, то сеть просто «запомнит правильный ответ». Со стороны будет казаться, что она очень быстро «обучилась». И как только вы подадите немного измененный сигнал, ожидая увидеть правильный ответ, то сеть выдаст бессмыслицу.

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

Именно с этой целью и создаются обучающие выборки.

Обучающая выборка (Training set) — конечный набор входных сигналов (иногда вместе с правильными выходными сигналами), по которым происходит обучение сети.

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

Однако прежде чем пускать свежеиспеченную нейросеть в бой, часто производят оценку качества ее работы на так называемой тестовой выборке.

Тестовая выборка (Testing set) — конечный набор входных сигналов (иногда вместе с правильными выходными сигналами), по которым происходит оценка качества работы сети.

Мы поняли, что такое «обучение сети» – подбор правильного набора весов. Теперь возникает вопрос – а как можно обучать сеть? В самом общем случае есть два подхода, приводящие к разным результатам: обучение с учителем и обучение без учителя.

Обучение с учителем

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

Важный момент. Не путайте правильные ответы и известный алгоритм решения! Вы можете обвести пальцем лицо на фото (правильный ответ), но не сможете сказать, как это сделали (известный алгоритм). Тут такая же ситуация.

Затем, с помощью специальных алгоритмов, вы меняете веса связей нейронной сети и снова даете ей входной сигнал. Сравниваете ее ответ с правильным и повторяете этот процесс до тех пор, пока сеть не начнет отвечать с приемлемой точностью (как я говорил в 1 главе, однозначно точных ответов сеть давать не может).

Обучение без учителя

Обучение без учителя применяют тогда, когда у нас нет правильных ответов на входные сигналы. В этом случае вся обучающая выборка состоит из набора входных сигналов.

Что же происходит при таком обучении сети? Оказывается, что при таком «обучении» сеть начинает выделять классы подаваемых на вход сигналов. Короче говоря – сеть начинает кластеризацию.

Например, вы демонстрируете сети конфеты, пирожные и торты. Вы никак не регулируете работу сети. Вы просто подаете на ее входы данные о данном объекте. Со временем сеть начнет выдавать сигналы трех разных типов, которые и отвечают за объекты на входе.

Обучение без учителя (Unsupervised learning) — вид обучения сети, при котором сеть самостоятельно классифицирует входные сигналы. Правильные (эталонные) выходные сигналы не демонстрируются.

Выводы

В этой главе вы узнали все о структуре искусственного нейрона, а также получили полное представление о том, как он работает (и о его математической модели).

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

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

Вы уже знаете необходимую теорию.  Давайте попробуем подкрепить наши знания на практике.


Практика

Наиболее распространенным решением является использование Python для построения ИНС. Существует огромное множество готовых решений и библиотек для построения ИНС. Но так как мы лучше знакомы с веб языками программирования, то мы будем использовать JavaScript. При работе с ИНС Вам вряд ли придется их самостоятельно писать, но понимать принцип работы ИНС необходимо понимать при работе с ними.
Мы будем использовать популярную JavaScript библиотеку brain.js

В библиотеке уже реализованы все необходимые инструменты для работы с ИНС и нам лишь необходимо передать необходимые параметры для создания нужного нам экземпляра brain.js. Первый релиз библиотеки состоялся 1 января 2018г. Правильнее будет сказать, что первый релиз после упадка библиотеки состоялся 1 января 2018г. Библиотека brain.js является работой энтузиастов, которые не стали равнодушны к закрытию проекта brain и создали собственный форк, который по сей день очень активно развивается. Начать работать с brain.js очень просто, для этого Вам необходимо пройти несколько шагов:

  • Установить NodeJS и NPM, либо использовать версию для браузера (ее можно подключить прямо в документ с CDN);
  • Если Вы решили использовать NodeJS, то Вам необходимо установить пакет brain.js, выполнив команду npm install brain.js и подключить ее в файл командой const brain = require('brain.js');
  • Создать экземпляр объекта ИНС, передав необходимые параметры конструктору: const net = new brain.NeuralNetwork({...});
  • Тренировать сеть при помощи команды train и набора тренировочных данных;
  • Использовать ИНС при помощи команды run;

Библиотека имеет отличный пример работы в котором на первом этапе Вам необходимо создать тренировочные данные для ИНС выбирая цвет текста на разноцветных плитках, который лучше видно. На втором этапе после обучения, ИНС сама будет определять какой цвет текста будет лучше видно на разноцветных плитках. Пример находится по этому адресу. Так же существует отличный интерактивный урок по работе с brain.js на scrimba. Еще больше примеров и уроков можно найти в WIKI на GitHub.

Вот некоторая техническая информация которая может понадобиться Вам при работе с brain.js. Я не нашел русского перевода, поэтому перевел самостоятельно, поправьте если я где-то допустил ошибку.

Использование brain.js в браузере требует вычислительных затрат, поэтому вы должны попытаться обучить сеть в автономном режиме (или на рабочем месте) и использовать опции toFunction()или toJSON(), чтобы подключить предварительно обученную сеть к своему веб-сайту.

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

Тренировка с NeuralNetwork

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

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

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

Для обучения с RNNTimeStep, LSTMTimeStepиGRUTimeStep
Каждый шаблон тренировки может:

- Быть массивом чисел
- Быть массивом массивов чисел

Пример использования массива чисел:

const net = new brain.recurrent.LSTMTimeStep();

net.train([
  [1, 2, 3]
]);

const output = net.run([1, 2]);  // 3

Пример использования массива чисел:

const net = new brain.recurrent.LSTMTimeStep({
  inputSize: 2,
  hiddenLayers: [10],
  outputSize: 2
});

net.train([
  [1, 3],
  [2, 2],
  [3, 1],
]);

const output = net.run([[1, 3], [2, 2]]);  // [3, 1]

Для обучения с RNN, LSTMиGRU
Каждый шаблон тренировки может:

- Быть массивом значений
 - Будь строкой
- Есть input и output
Любой из которых может массив значений или строка

Пример использования прямых строк:

const net = new brain.recurrent.LSTM();

net.train([
  'doe, a deer, a female deer',
  'ray, a drop of golden sun',
  'me, a name I call myself',
]);

const output = net.run('doe');  // ', a deer, a female deer'

Пример использования строк с входами и выходами:

const net = new brain.recurrent.LSTM();

net.train([
  { input: 'I feel great about the world!', output: 'happy' },
  { input: 'The world is a terrible place!', output: 'sad' },
]);

const output = net.run('I feel great about the world!');  // 'happy'

Варианты обучения

train() принимает хэш опций в качестве второго аргумента:

net.train(data, {
                            // Defaults values --> expected validation
      iterations: 20000,    // максимальное количество итераций обучающих данных -> число больше 0 
      errorThresh: 0.005,   // допустимый процент ошибок из обучающих данных - > число от 0 до 1 
      log: false,           // true для использования console.log, когда функция предоставляется, она используется -> либо true, либо функция 
      logPeriod: 10,        // итерации между выходом из системы -> число больше 0 
      learningRate: 0.3,    // масштабирование дельтой для повышения скорости тренировки -> число от 0 до 1 
      momentum: 0.1,        // масштабирование с значением изменения следующего слоя -> число между 0 и 1 
      callback: null,       // периодический обратный вызов, который может быть запущен во время обучения -> null или функция 
      callbackPeriod: 10,   // количество итераций данных обучения между вызовами обратного вызова -> число больше 0 
      timeout: Infinity     // максимальное количество миллисекунд, для которых нужно тренироваться -> число больше 0 
});

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

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

Скорость обучения - это параметр, который влияет на скорость обучения в сети. Это число от 0до 1. Если скорость обучения близка 0, обучение займет больше времени. Если скорость обучения ближе 1, она будет тренироваться быстрее, но результаты обучения могут быть ограничены локальным минимумом и плохо работать с новыми данными. ( Переоснащение ) Скорость обучения по умолчанию - 0.3.

JSON
Сериализация или загрузка в состоянии обученной сети с помощью JSON:

const json = net.toJSON();
net.fromJSON(json);

Автономная функция
Вы также можете получить настраиваемую автономную функцию из обученной сети, которая действует так же, как run():

const run = net.toFunction();
const output = run({ r: 1, g: 0.4, b: 0 });
console.log(run.toString()); // copy and paste! no need to import brain.js

Активация
Этот параметр позволяет указать, какую функцию активации должна использовать ваша нейронная сеть. Есть в настоящее время четыре поддерживаемых функций активации, сигмовидные по - умолчанию:

sigmoid
- relu
- leaky-relu (с этой опцией доступен параметр «leakyReluAlpha», по умолчанию 0,01)
- tanh


Вот таблица (спасибо, Википедия!), Обобщающая множество функций активации - Функция активации

Скрытые слои
Вы можете использовать это, чтобы указать количество скрытых слоев в сети и размер каждого слоя. Например, если вы хотите два скрытых слоя - первый с 3 узлами, а второй с 4 узлами, вы должны дать:

hiddenLayers: [3, 4]
По умолчанию brain.js используется один скрытый слой с размером, пропорциональным размеру входного массива.

Типы нейронных сетей

Теперь когда мы знаем что представляют из себя ИНС и обладаем технической информацией по работе с brain.js можно приступить к написанию своей первой ИНС. Я буду использовать repl.it для публикации кода и NodeJS для вычислительных процессов что бы не нагружать Ваши браузеры. 

В качестве первого примера предлагаю написать нейронную сеть по расчету XOR. XOR - это операция, которая принимает значение «истина» только если всего один из аргументов имеет значение «истина».

Более подробно изучить работу XOR Вы можете в отличной статье fealsoft на habr.com.

Пример 1

В реальной жизни эта ИНС конечно же является абсолютно бесполезной, но отлично подходит для простого промера. В качестве тренировочных данных на вход мы будем передавать два аргумента, а на выход результат XOR. К примеру [input: [0,0];output: 0,input:[0,1];output:1, ....]. Таким образом наша ИНС найдет закономерность и будет самостоятельно выявлять XOR. Важно понимать фактически она не будет высчитывать XOR, она будет делать предсказания каким может быть XOR для введенных аргументов. Весь код имеет комментарии и не вижу необходимости более детально углубляться в подробности реализации, Вы можете попробовать поменять значения передаваемые в функцию run и проверить корректность работы ИНС. Пример ИНС для расчета XOR:

Разрабатывать бесполезную ИНС для выполнения элементарных вычислений безумно "увлекательное " занятие, не так ли? Вы наверняка хотели бы создавать нейросети, которые будут уметь отвечать пользователю, проявлять признаки интеллекта или хотя бы будут как-то полезны обществу. Не вопрос!

Пример 2

Предположим что у Вы являетесь психологом в учебном заведении и перед Вами поставили цель: выявить эмоциональное состояние учащихся. Казалось бы спросить "Какое у тебя сегодня настроение?" дело совершенно плёвое, но когда это необходимо сделать 30 000 раз каждый день(именно столько учащихся Вам необходимо опросить) - это уже становится проблемой.

Предположим что в учебном заведении есть закрытая социальная сеть, в которой учащиеся ежедневно оставляют более 500 000 сообщений. Эта информация строго конфиденциальная, но Вы имеете к ней доступ, так как подписали договор о не разглашении. Отлично! Теперь у нас есть несколько миллионов сообщений вместо 30 000 учеников! 

Эмм... Звучит не особо оптимистично, но помимо психологии Вы увлекаетесь построением ИНС. Действительно. Зачем заниматься классификацией сообщений самому, если это может сделать машина и дать Вам отчет.

Перед нами стоит следующая задача:  Построить ИИС которая будет определять эмоциональное состояние человека по сообщению.

Входными данными является сообщение пользователя.

Выходными данными является строка: "хорошее" - если эмоциональный окрас сообщения позитивный, "плохое" - если эмоциональный окрас сообщения агрессивный или депрессивный.

Пример работы:

Сообщение "Завтра будет просто ужасный день!"

Результат "плохое"

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

Советую сохранять результаты обучения и не заставлять сеть учиться каждый раз когда Вы ее запускаете. Сохранить результаты обучения сети можно при помощи функции toJSON. Далее полученную строку сохраните в файл и при последующем запуске при помощи команды fromJSON выгрузите результаты вычислений обратно в сеть.

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


В заключение хочу сказать что JavaScript безусловно не является языком наиболее подходящим для построения ИНС. Вы наверно уже заметили как медленно проходит процесс обучения. Это вызвано тем что NodeJS, как и JavaScript является однопоточным и не раскрывает все вычислительные возможности процессора. Разработчики brain.js обещают улучшить производительность с выходом 2-й версии. Хотя и сейчас есть возможность использовать мощность видеопроцессора при помощи WebGL, но работу через GPU в brain.js поддерживают только neural networks. Для дальнейшего изучения рекомендую посмотреть в сторону Python.

 

Источники:

  1. https://neuralnet.info/chapter/основы-инс/
  2. https://habr.com/company/epam_systems/blog/317050/
  3. https://habr.com/post/312450/
  4. https://habr.com/post/40137/
  5. https://habr.com/post/398645/
  6. https://tproger.ru/translations/javascript-brain-neural-framework/
  7. https://itnan.ru/post.php?c=1&p=304414
  8. https://habr.com/post/183462/
  9. https://medium.com/openmindonline/emotion-detection-with-javascript-neural-networks-5a408f84eb75