浅层神经网络理论学习已经被拿下了,现在把编程作业自己实现一下

本次需要实现的浅层神经网络结构如下

模型
模型

整个神经网络结构实现的过程跟深度学习实践01-Logistic Regression识别包含猫的图片类似,不过增加了计算量而已。主要流程如下:

  1. 初始化参数W1b1W2b2
  2. 根据W1b1W2b2以及输入X求得输出Z1Z2A1A2
  3. 根据输入X和输出Z1Z2A1A2求得梯度下降量dW1db1``dW2db2
  4. 使用dW1db1``dW2db2来更新W1b1W2b2
  5. 循环2-5直至满足学习终止条件,如迭代300次。

算法实现

假定训练集输入为X,训练集结果为Y
在实现流程之前依然是加载使用到的python

1
2
import numpy as np
import math

初始化参数Wb

这一步与逻辑回归有所不同的是,我们需要根据神经网络的结构来初始化不同维度的W1W2;其次,我们需要随机的初始化W1W2,为什么呢?假设W1W2都是初始化为全0矩阵,那么第一层的所有神经单元做的工作都是相同的,计算出来的是同一个值,类似的,当第二次迭代的时候每一层的不同神经单元计算也是相同的,这样的话神经单元的个数就没有什么意义了。并且,W初始化的值不能太大,以sigmoid激活函数为例子,如果W值较大,那么最终计算出来的Y^数值也会比较大,在点(Y^, sidmoid(Y^))处的斜率接近于0,根据梯度下降法的特性,整个神经网络刚开始的学习速度就会大大降低,不利于提高效率。因此初始化的代码更改如下:

1
2
3
4
5
6
7
8
def initial(n_x, n_h, n_y):
W1 = np.random.randn(n_h, n_x) * 0.01
b1 = np.zeros((n_h ,1))
W1 = np.random.randn(n_y, n_h) * 0.01
b1 = np.zeros((n_y ,1))

parameters = {"W1": W1, "W2": W2, "b1": b1, "b2": b2}
return parameters

根据Wb、输入X求得输出AZ

根据前向公式计算输出AZ

前向公式
前向公式

两个激活函数已经在math以及numpy中实现了,直接调用即可。前向传播函数实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
def forward(parameters, X):
W1 = parameters['W1']
b1 = parameters['b1']
W2 = parameters['W2']
b2 = parameters['b2']

Z1 = np.dot(W1, X) + b1
A1 = np.tanh(Z1)
Z2 = np.dot(W2, A1) + b2
A2 = sigmoid(Z2)
cache = {"Z1": Z1, "Z2": Z2, "A1": A1, "A2": A2}
return cache

根据XYAdWdb

根据反向传播公式

反向公式
反向公式

求出dWdb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def backward(X, Y, cache, parameters):
m = X.shape[1]
A2 = cache['A2']
A1 = cache['A1']
W2 = parameters['W2']
W1 = parameters['W1']

dZ2 = A2 - Y
dW2 = np.dot(dZ2, A1.T) / m
db2 = np.sum(dZ2, axis = 1, keepdims = True) / m
dW1 = np.dot(dZ1, X.T) / m
dZ1 = np.dot(W2.T, dZ2) * (1 - A1**2)
db1 = np.sum(dZ1, axis = 1, keepdims = True) / m
grads = {"dW1": dW1, "dW2": dW2, "db1": db1, "db2": db2}

return grads

使用dWdb来更新Wb

根据公式更新参数Wb

更新参数
更新参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def update_parameters(parameters, grads, learning_rate=1.2):
dW1 = grads['dW1']
db1 = grads['db1']
dW2 = grads['dW2']
db2 = grads['db2']
W1 = parameters['W1']
b1 = parameters['b1']
W2 = parameters['W2']
b2 = parameters['b2']

W1 = W1 - learning_rate * dW1
W2 = W2 - learning_rate * dW2
b1 = b1 - learning_rate * db1
b2 = b2 - learning_rate * db2

parameters = {"W1": W1, "W2": W2, "b1": b1, "b2": b2}
return parameters

浅层神经网络的建立

1
2
3
4
5
6
7
8
9
10
11
12
13
def nn_model(X, Y, iteration_times):
n_x = X.shape[0]
n_h = 4
n_y = Y.shape[0]

parameters = initial(n_x, n_h, n_y)

for i in range(iteration_times):
cache = forward(parameters, X)
grads = backward(X, Y, cache, parameters)
parameters = update_parameters(parameters, grads)

return parameters

经过大量学习过程,我们习得了模型中的参数Wb

结果

使用这个神经网络对包含“猫”的图片进行识别,经过2500次的迭代学习,最终这个深层的神经网络训练集识别率为98.5%,而测试集相比于之前的逻辑回归的72%得到了提升,准确率为80%

至此,吴恩达老师的深度学习五门课的第一门课“深度学习初步以及构建神经网络”已经全部完成。