Привет ребята,

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

Покажите свою поддержку, подписавшись на нашу рассылку!

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

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

Самое приятное в этом то, что мы не будем использовать какие-либо библиотеки для создания нашей нейронной сети (кроме numpy, очевидно). Это поможет нам понять основную структуру нейронной сети и то, как она на самом деле работает.

Чтобы не усложнять вам жизнь, давайте начнем с кода. Мы начнем с установки необходимой библиотеки, в данном случае numpy.

Затем мы импортируем необходимые библиотеки. Нам понадобится exp для экспоненты (почему вы узнаете позже), array (очевидно, для массива), random для генерации случайных чисел и dot для скалярного произведения (прямо физическое!) Все из numpy.

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

Вам должно быть интересно, как, черт возьми, он получил такой результат? Не волнуйтесь, здесь нет ракетостроения, я просто скопировал всю Input 2 строку таблицы!

Итак, мы будем использовать этот набор данных. Теперь, двигаясь дальше, давайте объявим входные и выходные переменные для нашей программы, которые будут массивами, представляющими эту таблицу.

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

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

Мы использовали здесь функцию seed(), чтобы сгенерированные случайные веса оставались неизменными каждый раз при выполнении программы, пока она не будет закрыта.

Вот концепция, которую стоит понять. Что ж, это скорее приложение, чем концепция. Нам нужно сгенерировать случайные числа для нейрона с 3 входными подключениями и 1 выходным подключением, поэтому наша функция становится random(3,1).

Также нам нужно сгенерировать случайные числа в диапазоне от -1 до 1 (так как наш результат - либо 0, либо 1). При использовании функции random для диапазона a to b, функция random определяется как: (b — a) * random_sample() + a, поэтому здесь a = -1 и b = 1, и функция становится примерно такой, где synaptic_weights = 2 * random.random((3, 1)) — 1.

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

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

Голова

Первая часть функции train() - это голова. Он принимает 3 аргумента, а именно train_inputs (входные данные для обучения), train_outputs (выходные данные для обучения) и iterations (количество раз, в течение которого цикл будет выполняться для обучения нейрона, чтобы его веса можно было регулировать).

Также существует цикл for, который выполняется в течение заданного количества итераций. Здесь xrange используется для указания количества раз, в течение которого цикл должен выполняться. Остальные 3 части функции train() находятся внутри этого цикла.

Предиктор вывода

Эта часть train() используется для прогнозирования вывода для данного train_inputs с использованием текущего synaptic_weights. Это делается с помощью функции getoutput(), которую можно определить следующим образом:

Здесь мы будем использовать сигмоидальные значения inputs и synaptic_weights. Для их объединения мы использовали dot() функцию для выполнения скалярного произведения inputs и synaptic_weights и отправки их в sigmoid() функцию.

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

Выглядит это примерно так:

Давайте запишем эту концепцию в код:

Калькулятор ошибок

Следующая часть вычисляет ошибку. Это простой шаг, который вычитает output, полученный в части Output Predictor, из фактического ожидаемого результата, хранящегося в переменной train_outputs.

Регулятор веса

Последняя и самая важная часть функции train(). Здесь synaptic_weights настраиваются с использованием error, полученного в Калькуляторе ошибок.

Сигмовидная кривая выглядит примерно так -

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

Sigmoid Gradient = output * (1-output)

Здесь сначала мы передали output из Предиктора вывода в sig_grad() функцию. Что он делает, так это вычисляет сигмовидный градиент выходного сигнала, используя приведенную выше формулу, чтобы мы могли двигаться к краям сигмовидной кривой и получать более точные результаты.

Затем мы умножим наше значение error на сигмоидный градиент output, чтобы соответствующим образом изменить наши выходные данные, и, наконец, мы возьмем скалярное произведение этих значений и транспонирование (.T) train_inputs, чтобы получить нашу корректировку.

Последним шагом каждого запуска и функции train() является обновление synaptic_weights путем добавления к нему adjustment. Мы объявляем переменную как global synaptic_weights для доступа к глобальной переменной с именем synaptic_weights (потому что в python определение и объявление объединены, и это приведет к ошибке, если мы обновим synaptic_weights перед их объявлением, также они будут присутствовать в локальной области).

Остальная часть программы просто передает значения в функцию train() и затем распечатывает результаты.

Мы только что напечатали случайные начальные синаптические веса и вызванную функцию train(), передав train_inputs, train_outputs и 10000 в качестве количества запусков.

Затем мы распечатали синаптические веса после обучения и протестировали нейронную сеть с пользовательским вводом [1,1,0], в идеале мы должны получить 1, как он находится во 2-й строке, и мы просто скопировали 2-ю строку в выходных данных (см. Верхнюю часть этого сообщения. ). Давай посмотрим что происходит!

Обратите внимание, что наш результат - [0.9999225], что очень близко к 1, именно тот результат, который мы хотели. Кроме того, веса синапсов изменились и выглядят намного более согласованными. Мы обучили нашу модель 10000 раз, и она может так точно предсказывать выходные данные, и это всего лишь один нейрон, представьте себе мощность нейронных сетей с тысячами нейронов!

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