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

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

Итак, давайте начнем с примера, а затем мы сможем построить нейронную сеть на этом примере. Рассмотрим задачу XOR, в которой противоположные знаки дают 1, а те же знаки дают ноль.

Ввод: 0,0 - - - - - - -Выход: 0
Ввод: 0,1 - - - - - - -Выход: 1
Ввод: 1,0 - - - - - - - Выход: 1
Вход: 1,1 - - - - - - -Выход: 0

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

Итак, если мы введем в нашу нейронную сеть «0,0», она должна предсказать «0» и так далее.

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

Подробнее о том, как мы пришли к архитектуре нейронной сети, читайте в этой статье: https://medium.com/@jayeshbahire/the-xor-problem-in-neural-networks-50006411840b

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

Таким образом, нейронная сеть, которую мы используем, имеет ОДИН скрытый слой с двумя нейронами и входной слой, который может принимать два входа и один выходной слой, который, как ожидается, даст 1, если вход 0,1 или 1,0. еще 0.

Вот как выглядит наш прямой проход:

а также

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

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

Если мы расширим h1 и h2, мы также можем записать прямой проход этой нейронной сети как:

Пока мы знаем значения всех переменных, кроме:

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

Но изначально мы не знаем подходящих значений w1, w2, w3, w4, wh1, wh2, b1, b2 и c. Поэтому сначала мы просто инициализируем его случайными значениями и пытаемся найти значения, которые делают Yp как можно ближе к правильному значению. Это можно сделать с помощью стохастического градиентного спуска, которого здесь можно достичь с помощью обратного распространения.

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

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

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

Давайте сначала найдем wh1

Для вычисления w1, w2, w3, w4, b1 и b2 мы должны использовать правило цепочки.

Здесь мы используем ReLU в качестве функции активации, а для производной от relu в этой статье объясняется, какой подход использовать для ее поиска:



В нашем коде мы говорим, что для Relu (x), если x≤0, производная Relu равна 0, иначе это будет x.

Теперь, когда мы нашли производную от w и b, вот как мы собираемся ее обновить:

n - скорость обучения.

Теперь перейдем к нашему коду

Теперь давайте посмотрим на код нейронной сети, и я обещаю, что в нем нет MATRIC или numpy.

Давайте посмотрим, как наши нейронные сети работают с данными XOR с 10000 эпох (или итерациями).

Это было результатом выполнения приведенного выше кода.

Как мы видим, наш алгоритм для 1,0 и 0,1 предсказал значение, близкое к 1.

Аналогично для 0,0 и 1,1 алгоритм предсказал значения, близкие к 0.

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

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

Ссылки:
Глубокое обучение от IanGoodfellow
https://medium.com/@14prakash/back-propagation-is-very-simple-who-made- it-complex-97b794c97e5c
https://sudeepraja.github.io/Neural/ (наиболее полезен для понимания матричного представления нейронных сетей)
https://www.analyticsvidhya.com / blog / 2017/05 / neural-network-from-scratch-in-python-and-r /
http://www.wildml.com/2015/09/implementing-a-neural-network -с самого начала /
« это помогло понять, почему xor gate не работает с меньшим количеством скрытых нейронов в сети