Создание нейросети для начинающих (на Python, с кодом)

Нейросеть просто! Как понять и обуздать персептрон

Итак, вы хотите создать свою первую искусственную нейронную сеть или просто открыть для себя эту тему, но не знаете, с чего начать? Следуйте этому руководству, чтобы понять все шаги!

Что такое нейронная сеть (нейросеть)?

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

Работа нейронной сети проста: в качестве входных данных вводятся переменные (например, изображение, если предполагается, что нейронная сеть сообщает, что находится в обработке изображения), и после некоторых вычислений возвращается результат (изображение пса должно возвращать слово «собака»).

Искусственные нейронные сети обычно визуализируются в столбцах, так что нейрон столбца n может быть соединен только с нейронами из столбцов n-1 и n+1. Существует несколько типов сетей, использующих различную архитектуру, но мы сосредоточимся на самых простых.

Итак, мы можем представить искусственную нейронную сеть следующим образом:

Рисунок 1 — Представление нейронной сети

Нейронные сети обычно нужно читать слева направо. Здесь первый слой — это слой, в который поступают входные данные. Есть 2 внутренних слоя (называемых скрытыми слоями), которые выполняют некоторые математические операции. И последний слой, содержащий все возможные выходные данные. Посмотрите на «+1» внизу каждого столбца. Это то, что называется «предвзятостью», и мы поговорим об этом позже.

Реклама. ЧОУ ЧАСТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ДОПОЛНИТЕЛЬНОГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ ОБРАЗОВАТЕЛЬНЫЕ ТЕХНОЛОГИИ СКИЛБОКС (КОРОБКА НАВЫКОВ), ИНН 9704088880, erid: LdtCJzD4K

Что делает нейрон?

Операции, выполняемые каждым нейроном, очень просты:

Рисунок 2 — Операции, выполняемые нейроном

Во-первых, он суммирует значение каждого нейрона из предыдущего столбца, к которому он подключен. На рисунке 2 к нейрону поступает 3 входа (x1, x2, x3), поэтому к нашему нейрону подключены 3 нейрона из предыдущего столбца.

Это значение перед добавлением умножается на другую переменную, называемую «весом» (w1, w2, w3), которая определяет связь между двумя нейронами. Каждое соединение нейронов имеет свой вес, и это единственные значения, которые будут изменены в процессе обучения.

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

После всех этих сумм нейрон, наконец, применяет функцию, называемую «функцией активации», к полученному значению.

Рисунок 3 — Сигмовидная функция

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

Это все, что делает нейрон! 

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

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

Как обучается нейронная сеть?

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

Давайте посмотрим, как работает процесс обучения:

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

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

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

Персептрон. Для чего он нужен?

Теперь, когда мы знаем основы, давайте проверим нейронную сеть, которую мы создадим. Описанный здесь называется перцептроном и он является первой когда-либо созданной нейронной сетью. Персептрон состоит из 2 нейронов во входном столбце и 1 нейрона в выходном столбце. Эта конфигурация позволяет создать простой классификатор для того чтобы различать 2 группы данных:

Допустим, мы хотим, чтобы нейронная сеть могла возвращать выходные данные по правилам «или»:

 

Правила “или”
  • если А истинно и В истинно, то А или В истинно
  • если А истинно, а В ложно, то А или В истинно
  • если А ложно, а В истинно, то А или В истинно
  • если А ложно и В ложно, то А или В ложно.

Если вы замените «истину» на 1, а «ложь» на 0 и поместите 4 вариации в виде точек с координатами на графике, то поймете, что две последние группы «ложные» и «истинные» будут разделены одной линией. Это то, что делает персептрон.

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

Таким образом, персептрон действительно не очень эффективная нейронная сеть, но ее легко создать, и она все еще может быть полезна в качестве классификатора.

Создание собственной простой нейронной сети на Python

Давайте создадим нейронную сеть с нуля с помощью Python (3.x в примере ниже).

import numpy, random, os
lr = 1 #скорость обучения 
bias = 1 #значение весов смещения
weights = [random.random(),random.random(),random.random()] #веса, сгенерированные в списке (3 веса для 2 нейронов и смещения))

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

def Perceptron(input1, input2, output) :
 outputP = input1*weights[0]+input2*weights[1]+bias*weights[2]
 if outputP > 0 : #функция активации
 outputP = 1
 else :
 outputP = 0
 error = output – outputP
 weights[0] += error * input1 * lr
 weights[1] += error * input2 * lr
 weights[2] += error * bias * lr

В этом коде мы создаем функцию, которая определяет работу выходного нейрона. Она принимает 3 параметра (2 значения нейронов и ожидаемый результат). «outputP» — это переменная, соответствующая выходным данным персептрона. Затем мы вычисляем ошибку, используемую для изменения веса каждого соединения с выходным нейроном.

for i in range(50) :
 Perceptron(1,1,1) #True or true
 Perceptron(1,0,1) #True or false
 Perceptron(0,1,1) #False or true
 Perceptron(0,0,0) #False or false

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

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

x = int(input()) 
y = int(input()) 
outputP = x*weights[0] + y*weights[1] +bias*weights[2] 
if outputP > 0 : #функция активации, ступенчатая функция Хевисайта
 outputP = 1 
else : 
 outputP = 0 
print (x, "or", y, "is:", outputP)

Наконец, на этапе тестирования, мы можем попробовать вводить разные значения, чтобы проверить, работает ли персептрон.

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

outputP = 1/(1+numpy.exp(-outputP)) #сигмовидная функция

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

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