Глубокая нейронная сеть с прямым и обратным распространением с нуля - Python
Эта статья направлена на реализацию глубокой нейронной сети с нуля. Мы реализуем глубокую нейронную сеть, содержащую скрытый слой с четырьмя блоками и одним выходным слоем. Реализация будет идти с нуля, и будут выполнены следующие шаги.
Алгоритм:
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. А чтобы начать свое путешествие по машинному обучению, присоединяйтесь к курсу Машинное обучение - базовый уровень.