Обратное обучение нейронной сети (8 строк кода)

искусственный интеллект глубокое обучение алгоритм Нейронные сети

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

import numpy as np
X = np.array([[0,0,1], [0,1,1], [1,0,1], [1,1,1]])
y = np.array([[0, 0, 1, 1]]).T
syn = 2 * np.random.random((3, 1)) - 1
for i in range(10000):
    l = 1 / (1 + np.exp(-np.dot(X, syn)))
    l_delta = (y - l) * (l * (1 - l))
    syn += np.dot(X.T, l_delta)

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

x1 x2 x3 y
0 0 1 0
1 1 1 1
1 0 1 1
0 1 1 0

Данные для тренировки такие же, как и выше.


Код объясняется ниже:
X: указывает выходные данные
y: представляет выходные данные
syn: 3 * 1 размерные инициализированные случайные веса
Структура сети следующая:

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


Процесс примерно такой:
Входные данныеxУмножить на соответствующий весw, полученное значениеzПрогнозируемое значение получается путем преобразования нелинейной функции (сигмоида)l.
рассчитатьlцелевое значениеyошибка. Цель обучения — минимизировать ошибку, чтобы ее можно было скорректировать, изменив входные данные.xи весаw. так какxДля входных данных он не может быть скорректирован. Итак, цель такова: постоянно корректируя весаw, чтобы ошибка между полученным предсказанным значением и целевым значением была наименьшей (или меньше определенного порога), и обучение было завершено. можно использовать весыwДелайте прогнозы на новые входные данные.
Итеративный процесс — это последние 3 строки кода с небольшим пояснением:
Строка 6: вводxумножить на весw,проходить черезsigmoidизменить функцию, чтобы получитьl. Строка 7: процесс минимизации ошибок — это постоянная корректировка.wпроцесс. По цепному правилу найтиlossоwПроизводная от , чтобы найти самый быстрый способ уменьшить функцию потерь. Как показано на картинке выше:
lossоwПроизводная от =lossоlПроизводная от *lоzПроизводная от *zоwПроизводная от , которая является содержанием двух последних строк.


Ниже я немного расширю код для лучшего понимания:

import numpy as np
def sigmoid(z):
    return 1 / (1 + np.exp(-z))
def sigmoid_derivative(x):
    return x * (1 - x)

X = np.array([[0,0,1], [0,1,1], [1,0,1], [1,1,1]])
y = np.array([[0, 0, 1, 1]]).T

syn = 2 * np.random.random((3, 1)) - 1
for i in range(10000):
    l = sigmoid(np.dot(X, syn))
    loss = (y - l) ** 2
    if i % 1000 == 0:
        print("Loss: ", np.sum(loss))
    loss_derivative = 2  * (y - l)
    l_delta = loss_derivative * sigmoid_derivative(l)
    syn += np.dot(X.T, l_delta)
print("syn:\n" ,syn)
print("l:\n", l)

Вот результат печати:

Loss:  0.8505452956411994
Loss:  0.0013461667714825178
Loss:  0.0006585827213748538
Loss:  0.0004348364571153864
Loss:  0.00032425670465056856
Loss:  0.0002583897080090336
Loss:  0.00021470251268552865
Loss:  0.00018361751185635365
Loss:  0.000160374621766103
Loss:  0.00014234163846899023
syn:
 [[10.38061079]
 [-0.20679655]
 [-4.98439294]]
l:
 [[0.00679775]
 [0.00553486]
 [0.99548654]
 [0.9944554 ]]

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

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

Использованная литература:
A Neural Network in 11 lines of Python (Part 1)
Алгоритм обратного распространения для глубокого обучения вверх/вниз, часть 3, версия 0.9 бета

исходный код на гитхабе