Знакомство с простейшей нейронной сетью и ее пошаговая реализация

МЕНЮ


Искусственный интеллект
Поиск
Регистрация на сайте
Помощь проекту

ТЕМЫ


Новости ИИРазработка ИИВнедрение ИИРабота разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика

Авторизация



RSS


RSS новости


Как-то раз я наткнулся на книгу под названием «Создай свою нейросеть», автор которой -Тарик Рашид и после прочтения остался доволен, в отличие от многих других методичек по нейронным сетям, которые по-своему, несомненно, хороши, в этой книге все подавалось простым языком c достаточным количеством примеров и советов

По этой же книге я и хочу пройтись пошагово, а именно по практической части — написанию кода простой нейронной сети.

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

image
Теории по машинному обучению и нейронным сетям на хабре и так достаточно. Но если кому-то это необходимо, некоторые ссылки я оставлю в конце статьи. А сейчас, приступаем непосредственно к написанию кода, причем писать мы будем на python, будет лучше, если при написании кода вы будете использовать jupyter-notebook

Шаг 1. Инициализация сети

Сначала нам, конечно же, надо инициализировать все действующие компоненты нашей сети

#импортируем numpy — это библиотека языка Python, добавляющая поддержку больших многомерных массивов и матриц import numpy # импортируем scipy.special , -scipy содержит модули для оптимизации, интегрирования, специальных функций, обработки изображений и  многих других задач, нам же здесь нужна наша функция активации, имя которой -Сигмоида import scipy.special #Вероятно, нам понадобится визуализировать наши данные import matplotlib.pyplot   # Определяем наш класс нейронной сети class neuralNetwork:          # Инициализация нашей  нейронной сети     def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate): #В параметрах мы записываем обязательный self, входные данные,  данные  скрытого слоя, выходные данные ,скорость обучения соответственно)         # устанавливаем количество узлов для входного , скрытого слоя, выходного слоя         self.inodes = inputnodes         self.hnodes = hiddennodes         self.onodes = outputnodes                  # Тут обозначены веса матрицы, wih -  вес между входным и скрытым слоем , а  так же  who- вес между скрытым и выходным  слоем         self.wih = numpy.random.rand(self.hnodes, self.inodes))         self.who = numpy.random.rand(self.onodes, self.hnodes))          # Скорость обучения -это наш гиперпараметр, то есть, параметр , который мы подбираем ручками, и в зависимости от того, как нам это удобно нам, и , конечно же, нейронной сети         self.lr = learningrate                  # Наша Сигмоида- функция активации         self.activation_function = lambda x: scipy.special.expit(x)

Немного о том, как выглядит узел в нейронной сети

image
На картинке изображен самый, что ни на есть узел, только представлен он обычно в виде круга, а не прямоугольника. Как мы видим, внутри прямоугольника(ну или круга) — это все абстрактно, находятся 2 функции: 1-я Функция занимается тем, что получает все входные, с учетом весов, данные, и иногда даже с учетом нейрона смещения(специальный нейрон, который просто позволяет графикам подвинуться, а не смешиваться в одну некрасивую кучу, вот и все) 2-я Функция принимает в качестве параметра то самое значение, которое насуммировала первая функция, и эта вторая функция называется функцией активации. В нашем случае -Сигмоида Продолжаем:

Часть 2. Тренировка Нейронной Сети

def train(self, inputs_list, targets_list):         # Конвертируем наш список в двумерный массив         inputs = numpy.array(inputs_list, ndmin=2).T # поступающие на вход данные input         targets = numpy.array(targets_list, ndmin=2).T #целевые значения targets                  # Подсчет сигнала в скрытом слое         hidden_inputs = numpy.dot(self.wih, inputs)         # Подсчет сигналов, выходящих из скрытого слоя к выходному слою. Тут в нашем узле, куда поступали все данные в переменную hidden_inputs (1я функция), эта переменная подается  как параметр в Сигмоиду - функцию активации (2я функция)         hidden_outputs = self.activation_function(hidden_inputs)                  # Подсчет сигналов в конечном(выходном) слое         final_inputs = numpy.dot(self.who, hidden_outputs)         # Подсчет  сигналов, подающихся в функцию активации         final_outputs = self.activation_function(final_inputs)                  # Значение ошибки (Ожидание - Реальность)         output_errors = targets - final_outputs         # Ошибка скрытого слоя становится ошибкой ,которую мы получили для <b>ошибки выходного слоя</b>, но уже <b>распределенные по весам между скрытым и выходным слоями</b>(иначе говоря с учетом умножения соответствующих весов)          hidden_errors = numpy.dot(self.who.T, output_errors)                   # Обновление весов между скрытым слоем и выходным (Явление того, что люди зовут ошибкой обратного распространения)         self.who += self.lr * numpy.dot((output_errors * final_outputs * (1.0 - final_outputs)), numpy.transpose(hidden_outputs))                  # Обновление весов между скрытым слоем и входным(Та же ошибка ошибка обратного распространения в действии)         self.wih += self.lr * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), numpy.transpose(inputs))                  pass 

И вот мы приближаемся к концу

Часть 3. Опрос нейронной сети

#Создаем функцию , которая будет принимать входные данные  def query(self, inputs_list):         # Конвертируем поданный список входных данных в двумерный массив         inputs = numpy.array(inputs_list, ndmin=2).T         # Подсчет сигналов в скрытом слое         hidden_inputs = numpy.dot(self.wih, inputs)         # Подсчет сигналов, поданных в функцию активации         hidden_outputs = self.activation_function(hidden_inputs)                  #Подсчет сигналов в конечном выходном слое         final_inputs = numpy.dot(self.who, hidden_outputs)         #Подсчет сигналов в конечном выходном слое, переданных в функцию активации         final_outputs = self.activation_function(final_inputs)                  return final_outputs

Доводим дело до конца

  #Подаем конкретное значение для входного , скрытого ,выходного слоев соответственно(указываем количество <b>нод</b>- узлов в ряду входного, скрытого, выходного соответственно input_nodes = 3 hidden_nodes = 3 output_nodes = 3  # Возьмем коэффициент обучения - скорость обучения равной, например... 0.3! learning_rate = 0.3  # Создаем нейронную сеть(n это объект класса neuralNetwork , при его создании запустится конструктор __init__  , и дальше все будет включаться по цепочке n = neuralNetwork(input_nodes,hidden_nodes,output_nodes, learning_rate)

P.S

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

При желании, можно продолжить этот код, добавив в него возможность распознавания рукописного текста MNIST, для этого вы можете полностью разобраться(или просто позабавиться), имея этот jupyter-файл , моя же задача была продемонстировать код и по возможности разжевать для что и для чего. Ссылки на теорию, как и обещал, прикреплю в конце, ну а так же вы найдете Github и книгу Тарика Рашида, их я тоже оставлю 1.Github 2.Книга «Создай свою нейронную сеть» 3.Теория по машинному обучению 1 4.Теория по машинному обучению 2 5.Теория по машинному обучению 3 6.Теория по машинному обучению 4 Также можно ознакомиться с этим курсом.


Источник: habr.com

Комментарии: