Глубокая нейронная сеть с прямым и обратным распространением с нуля - Python

Опубликовано: 21 Июля, 2021

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

1. Визуализация входных данных
2. Определение формы матрицы веса и смещения.
3. Инициализирующая матрица, функция, которая будет использоваться.
4. Реализация метода прямого распространения.
5. Осуществление расчета стоимости
6. Обратное распространение и оптимизация
7. прогнозирование и визуализация результатов

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

Модель Архитектура

Веса и смещения:
Веса и смещение, которые будут использоваться для обоих уровней, должны быть объявлены изначально, а также веса будут объявлены случайным образом, чтобы избежать одинакового вывода всех единиц, в то время как смещение будет инициализировано нулем. Расчет будет производиться с нуля и в соответствии с правилами, приведенными ниже, где W1, W2 и b1, b2 - веса и смещения первого и второго слоя соответственно. Здесь A означает активацию определенного слоя.



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



Код: визуализация данных




# Package imports
import numpy as np
import matplotlib.pyplot as plt
# here planar_utils.py can be found on its github repo
from planar_utils import plot_decision_boundary, sigmoid, load_planar_dataset
# Loading the Sample data
X, Y = load_planar_dataset()
# Visualize the data:
plt.scatter(X[ 0 , :], X[ 1 , :], c = Y, s = 40 , cmap = plt.cm.Spectral);

Код: инициализация матрицы веса и смещения
Здесь количество скрытых единиц равно четырем, поэтому весовая матрица W1 будет иметь форму (4, количество характеристик), а матрица смещения будет иметь форму (4, 1), которая после трансляции будет добавлена к весовой матрице в соответствии с к приведенной выше формуле. То же самое можно сказать и о W2.

Код: Прямое распространение:
Теперь мы выполним прямое распространение, используя W1, W2 и смещение b1, b2. На этом этапе соответствующие выходы рассчитываются в функции, определенной как forward_prop.




def forward_prop(X, W1, W2, b1, b2):
Z1 = np.dot(W1, X) + b1
A1 = np.tanh(Z1)
Z2 = np.dot(W2, A1) + b2
A2 = sigmoid(Z2)
# here the cache is the data of previous iteration
# This will be used for backpropagation
cache = { "Z1" : Z1,
"A1" : A1,
"Z2" : Z2,
"A2" : A2}
return A2, cache

Код: определение функции стоимости:




# Here Y is actual output
def compute_cost(A2, Y):
m = Y.shape[ 1 ]
# implementing the above formula
cost_sum = np.multiply(np.log(A2), Y) + np.multiply(( 1 - Y), np.log( 1 - A2))
cost = - np. sum (logprobs) / m
# Squeezing to avoid unnecessary dimensions
cost = np.squeeze(cost)
cost return

Код: Наконец, функция обратного распространения:
Это очень важный шаг, поскольку он включает в себя много линейной алгебры для реализации обратного распространения глубоких нейронных сетей. Формулы для нахождения производных могут быть получены с помощью некоторой математической концепции линейной алгебры, вывод которой мы здесь не собираемся. Просто имейте в виду, что dZ, dW, db - это производные функции стоимости по взвешенной сумме, весам и смещению слоев.




def back_propagate(W1, b1, W2, b2, cache):
# Retrieve also A1 and A2 from dictionary "cache"
A1 = cache[ 'A1' ]
A2 = cache[ 'A2' ]
# Backward propagation: calculate dW1, db1, dW2, db2.
dZ2 = A2 - Y
dW2 = ( 1 / m) * np.dot(dZ2, A1.T)
db2 = ( 1 / m) * np. sum (dZ2, axis = 1 , keepdims = True )
dZ1 = np.multiply(np.dot(W2.T, dZ2), 1 - np.power(A1, 2 ))
dW1 = ( 1 / m) * np.dot(dZ1, XT)
db1 = ( 1 / m) * np. sum (dZ1, axis = 1 , keepdims = True )
# Updating the parameters according to algorithm
W1 = W1 - dW1 learning_rate *
b1 = b1 - learning_rate * db1
W2 = W2 - dW2 learning_rate *
b2 = b2 - learning_rate * db2
return W1, W2, b1, b2

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




# Please note that the weights and bias are global
# Here num_iteration is epochs
for i in range ( 0 , num_iterations):
# Forward propagation. Inputs: "X, parameters". return: "A2, cache".
A2, cache = forward_propagation(X, W1, W2, b1, b2)
# Cost function. Inputs: "A2, Y". Outputs: "cost".
cost = compute_cost(A2, Y)
# Backpropagation. Inputs: "parameters, cache, X, Y". Outputs: "grads".
W1, W2, b1, b2 = backward_propagation(W1, b1, W2, b2, cache)
# Print the cost every 1000 iterations
if print_cost and i % 1000 = = 0 :
print ( "Cost after iteration % i: % f" % (i, cost))

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

Визуализация границ данных

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

Внимание компьютерщик! Укрепите свои основы с помощью базового курса программирования Python и изучите основы.

Для начала подготовьтесь к собеседованию. Расширьте свои концепции структур данных с помощью курса Python DS. А чтобы начать свое путешествие по машинному обучению, присоединяйтесь к курсу Машинное обучение - базовый уровень.