深层神经网络的构建 18号的时候就已经学完了,自己写激活函数导数的时候遇到了一点困难,再加上懒癌发作,现在才弄到博客上来。
本次需要构建一个深层的神经网络,层数可以在训练时确定,主要流程跟之前的两次实践仍然是计算量的差别。主要流程还是一致的:
初始化参数W
、b
根据W
、b
以及输入X
求得输出Z
和A
根据输入X
和输出Z
、A
求得梯度下降量dW
、db
使用dW
、db
来更新W
、b
循环2-5
直至满足学习终止条件,如迭代300次。
算法实现 假定训练集输入为X
,训练集结果为Y
在实现流程之前依然是加载使用到的python
库
1 2 import numpy as npimport math
初始化参数W
和b
因为我们构建的是一个深层网络,所以对每一层都需要进行参数初始化
1 2 3 4 5 6 7 8 9 10 11 def initial (layers_dims ): L = len (layers_dims) parameters = {} for i in range (1 , L): W = np.randm.randn(layers[l], layers[l - 1 ]) * 0.01 b = np.zeros((layers[1 ], 1 )) parameters["W" + str (l)] = np.random.randn(layers_dims[l], layers_dims[l - 1 ]) parameters["b" + str (l)] = np.zeros((layers_dims[l])) return parameters
根据W
、b
、输入X
求得输出A
和Z
根据前向公式计算输出A
和Z
前向公式
两个激活函数已经在math
以及numpy
中实现了,直接调用即可。
1 2 3 4 5 6 7 8 9 10 def forward (W, b, X, activation ): Z = np.dot(W, X) + b if activation == "sigmoid" : A = sigmoid(Y) elif activation == "relu" : A = relu(Y) return A, Z
前向传播函数实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def forward_progate (parameters, X ): caches = [] A = X L = len (parameters) // 2 for l in range (1 , L): cache = {} A_pre = A A, Z = forward(parameters["W" + str (l)], parameters["b" + str (l)], A_prev, "relu" ) cache["A" + str (l)] = A cache["Z" + str (l)] = Z caches.append(cache) AL, ZL = forward(parameters["W" + str (L)], parameters["b" + str (L)], caches[L]["A" + str (L - 1 )], "sigmoid" ) cache = {"A" + str (L): AL, "Z" + str (L): ZL} caches.append(cache) return AL, caches
根据X
、Y
和A
求dW
和db
根据反向传播公式求出dW
和db
,这一步主要由两个函数构成,一个是之前的反向求导,另外一个就是激活函数的导数了。
反向公式
1 2 3 4 5 6 7 def activation_back (Z, activation ): if activation == "sigmoid" : Y = sigmoid(Z) * (1 - sigmoid(Z)) elif activation == "relu" : Y = (Y > 0 ) return Y
反向求导
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 def backward_progate (caches, AL, parameters ): m = Y.shape[1 ] dAL = -(np.divide(Y, AL) - np.divide(1 - Y, 1 - AL)) grads = {} L = parameters // 2 dZ = dAL * activation_back(Z, "relu" ) dW = np.dot(dZ, A) / m db = np.sum (dZ, axis = 1 , keepdims = True ) / m dA = np.sot(parameters["W" + str (L)].T, dZ) grads["db" + str (l)] = db grads["dW" + str (l)] = dW for l in reversed (range (L)): cache = caches[l] Z = cache["Z" + str (l)] A = cache["A" + str [l]] dZ = dA * activation_back(Z, "relu" ) dW = np.dot(dZ, A) / m db = np.sum (dZ, axis = 1 , keepdims = True ) / m dA = np.sot(parameters["W" + str (L)].T, dZ) grads["db" + str (l)] = db grads["dW" + str (l)] = dW return grads
使用dW
和db
来更新W
、b
根据公式更新参数W
和b
更新参数
1 2 3 4 5 6 7 8 9 10 11 12 def update_parameters (parameters, grads, learning_rate = 1.2 ): L = parameters // 2 for i in range (1 , L): parameters["W" + str (l)] = parameters["W" + str (l)] - learning_rate * grads["W" + str (l)] parameters["b" + str (l)] = parameters["b" + str (l)] - learning_rate * grads["b" + str (l)] return parameters
建立深层神经网络 为简单起见,这里建立一个4层的神经网络,每一层但神经单元分别是5,3,2,1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 def nn_models (X, Y, iterations ): layers_dims = [X.shape[0 ], 5 , 3 , 2 , Y.shape[0 ]] parameters = random_initial(layers_dims) for i in range (0 , iterations): AL, caches = forward_progate(parameters, X) grads = backward_progate(caches, AL, parameters) parameters = update_parameters(parameters, grads) return parameters
结果 使用这个神经网络对包含“猫”的图片进行识别,经过2500次的迭代学习,最终这个神经网络对训练集的识别准确率达到了98.5%
,而测试集的准确率从第一次作业的72%
提升到80%
。不过这个神经网络其实还存在过拟合的问题,训练集与测试集的差距较大,之后的课程会对过拟合以及超参数进行优化。
至此,吴恩达老师的深度学习课程中的第一门课已经全部完成。
最后更新时间:2019-06-14 22:54:54