文章目录

  • 声明
  • 一、任务描述
  • 二、编程实现
    • 1.数据
    • 2.参数初始化
      • 2.1 初始化参数为0
      • 2.2 参数随机初始化
      • 2.3 抑梯度异常初始化
      • 2.4 主控函数
      • 2.5 测试结果对比
        • 2.5.1 初始化为0
        • 2.5.2 随机初始化参数
        • 2.5.3抑梯度异常初始化
    • 3.模型正则化
      • 3.1 未使用正则化
      • 3.2 L2正则化
      • 3.3 dropout正则化
  • 总结

声明

  本博客只是记录一下本人在深度学习过程中的学习笔记和编程经验,大部分代码是参考了【中文】【吴恩达课后编程作业】Course 2 - 改善深层神经网络 - 第一周作业(1&2&3)这篇博客,对其代码实现了复现,代码或文字表述中还存在一些问题,请见谅,之前的博客也是主要参考这个大佬。

一、任务描述

  这次作业我们的主要任务是以下三个:

1.初始化参数:0初始化,随机初始化,使用抑梯度异常初始化参数。
2.正则化:L2正则化,dropout正则化。
3.梯度校验  :对模型使用梯度校验,检测它是否在梯度下降的过程中出现误差过大的情况。

  本次作业的重点是在参数初始化,正则化和梯度检验上,因此对于神经网络的相关实现进行过多描述。三个知识点对于神经网络的要求并不完全相同,在正向和反向传播上存在差异,分别创建对应的 init_utils.py ,reg_utils.py 和 gc_utils.py 文件,封装神经网络的相关操作,神经网络统一为两层结构,即一个输入层,一个隐藏层和一个输出层。

二、编程实现

1.数据

  本次作业提供了一份数据,用matplotlib绘制:

  本次作业中要处理的问题也是一个二分类问题。

2.参数初始化

  根据课程知识,我们可以分别对三种初始化的情形编程。

2.1 初始化参数为0

def initialize_zeros(layers_dims):"""将参数都设置成0:param layers_dims:列表,各层的神经元个数:return:"""parameters = {}for i in range(1, len(layers_dims)):parameters["W" + str(i)] = np.zeros((layers_dims[i], layers_dims[i - 1]))parameters["b" + str(i)] = np.zeros((layers_dims[i], 1))assert(parameters["W" + str(i)].shape == (layers_dims[i], layers_dims[i - 1]))assert (parameters["b" + str(i)].shape == (layers_dims[i], 1))return parameters

2.2 参数随机初始化

def initialize_random(layers_dims):"""将W随机初始化,b依旧初始化为0:param layers_dims:列表,各层的神经元个数:return:"""np.random.seed(3)parameters = {}for i in range(1, len(layers_dims)):parameters["W" + str(i)] = np.random.randn(layers_dims[i], layers_dims[i - 1])*10parameters["b" + str(i)] = np.zeros((layers_dims[i], 1))assert (parameters["W" + str(i)].shape == (layers_dims[i], layers_dims[i - 1]))assert (parameters["b" + str(i)].shape == (layers_dims[i], 1))return parameters

2.3 抑梯度异常初始化

  抑梯度异常初始化需要在随机初始化W矩阵的基础上乘上系数(1/n[L-1])^(1/2),即上层神经元个数(也就是当前神经元的输入个数)的倒数取平方根。

def initialize_random_he(layers_dims):"""将W随机初始化,b依旧初始化为0:param layers_dims:列表,各层的神经元个数:return:"""np.random.seed(3)parameters = {}for i in range(1, len(layers_dims)):parameters["W" + str(i)] = np.random.randn(layers_dims[i], layers_dims[i - 1])*np.sqrt(2 / layers_dims[i - 1])parameters["b" + str(i)] = np.zeros((layers_dims[i], 1))assert (parameters["W" + str(i)].shape == (layers_dims[i], layers_dims[i - 1]))assert (parameters["b" + str(i)].shape == (layers_dims[i], 1))return parameters

2.4 主控函数

def model(X, Y, learning_rate=0.01, num_iterations=15000, print_cost=True, initialization="he", is_plot=True):"""实现一个三层(双层隐藏层一层输出层)神经网络:RELU,RELU,SIGMOID:param X: 输入数据:param Y: 输入数据标签:param learning_rate:学习率:param num_iterations: 迭代次数:param print_cost: 是否打印损失值:param initialization: 参数初始化类型:param is_plot: 是否绘制梯度下降曲线:return:"""grads = {}costs = []layers_dim = [X.shape[0], 10, 5, 1]sample_num = X.shape[1]# 随机初始化神经网络参数if initialization == "zeros":parameters = initialize_zeros(layers_dim)elif initialization == "random":parameters = initialize_random(layers_dim)elif initialization == "random_he":parameters = initialize_random_he(layers_dim)else:print("传参错误")for i in range(0, num_iterations):a3, cache = init_utils.forward_propagation(X, parameters)cost = init_utils.compute_loss(a3, Y)grads = init_utils.backward_propagation(X, Y, cache)parameters = init_utils.update_parameters(parameters, grads, learning_rate)if i % 1000 == 0:costs.append(cost)if print_cost:print("第" + str(i) + "次迭代,成本值为:" + str(cost))if is_plot:plt.plot(costs)plt.ylabel('cost')plt.xlabel('iterations (per hundreds)')plt.title("Learning rate =" + str(learning_rate))plt.show()return parameters

2.5 测试结果对比

2.5.1 初始化为0

  初始化参数为0时的损失函数曲线:

  用matplotlib绘制初始化参数为0时的决策边界:

  得到的模型在训练集和测试集上的表现效果:

  可以看出,初始化参数为0时,模型的表现效果非常差,预测的每个结果都为0。用0初始化神经网络参数无法打破网络的对称性。

2.5.2 随机初始化参数

  绘制随机初始化损失曲线如下:

  用matplotlib绘制决策边界:

  得到的模型在训练集和测试集上的表现效果:

  从结果可以看出,随机初始化的效果比初始化为0的效果好的多,但是随机初始化存在一些问题,上次作业中我提到过,如果权重矩阵随机初始化为较大的值会导致梯度消失和梯度爆炸,之前的解决方案是直接在初始化权重矩阵时乘上系数0.01,这里将尝试采用抑梯度异常初始化的方式来对权重矩阵的初始化进行控制。

2.5.3抑梯度异常初始化

  绘制损失曲线如下:

  用matplotlib绘制决策边界:


  得到的模型在训练集和测试集上的表现效果:

  从结果可以看出,抑梯度异常初始化的方法得到的模型表现效果特别好。

3.模型正则化

  吴恩达老师的视频中主要讲述了两种正则化的方法:L2正则化和dropout正则化。这次我们需要使用到的数据分布如下:

  我们还是以两层神经网络为基础编写代码,主控函数代码如下:

def model(X, Y, learning_rate=0.3, num_iterations=30000, print_cost=True, is_plot=True, lambd=0, keep_drop=1):"""三层神经网络(两层隐藏层):RELU,RELU,SIGMOID:param X: 输入数据:param Y: 标签值:param learning_rate:学习率:param num_iterations: 迭代次数:param print_cost: 是否打印损失值:param is_plot: 是否绘制损失曲线:param lambd: 正则化参数:param keep_drop: dropout参数:return:"""grads = {}costs = []num_sample = X.shape[1]layers_dims = [X.shape[0], 20, 3, 1]parameters = reg_utils.initialize_parameters(layers_dims)for i in range(0, num_iterations):# 前向传播if keep_drop == 1:a3, cache = reg_utils.forward_propagation(X, parameters)elif keep_drop < 1:a3, cache = reg_utils.forward_propagation_with_dropout(X, parameters, keep_prob=keep_drop)# 计算损失if lambd == 0:cost = reg_utils.compute_cost(a3, Y)else:cost = reg_utils.compute_cost_with_regularization(a3, Y, parameters, lambd)# 反向传播if lambd == 0 and keep_drop == 1:grads = reg_utils.backward_propagation(X, Y, cache)elif lambd != 0:grads = reg_utils.backward_propagation_with_regularization(X, Y, cache, lambd)elif keep_drop < 1:grads = reg_utils.backward_propagation_with_dropout(X, Y, cache, keep_drop)# 更新参数parameters = reg_utils.update_parameters(parameters, grads, learning_rate)if i % 1000 == 0:## 记录成本costs.append(cost)if print_cost and i % 1000 == 0:# 打印成本print("第" + str(i) + "次迭代,成本值为:" + str(cost))if is_plot:plt.plot(costs)plt.ylabel('cost')plt.xlabel('iterations (x1,000)')plt.title("Learning rate =" + str(learning_rate))plt.show()# 返回学习后的参数return parameters

  主控函数model需要传入参数 lambd 和 keep_drop 分别是L2正则化和dropout正则化需要的超参数。当lambd>0时,L2正则化才起作用。当keep_drop<1时,dropout正则化才起作用。接下来分别对这两种正则化方法进行编程。

3.1 未使用正则化

  当我们往model中传入的参数lambd=0,keep_drop=1时表示不使用正则化。

if __name__ == "__main__":train_X, train_Y, test_X, test_Y = reg_utils.load_2D_dataset(is_plot=True)parameters = model(train_X, train_Y, is_plot=True)print("训练集:")predictions_train = reg_utils.predict(train_X, train_Y, parameters)print("测试集:")predictions_test = reg_utils.predict(test_X, test_Y, parameters)plt.title("Model without regularization")axes = plt.gca()axes.set_xlim([-0.75, 0.40])axes.set_ylim([-0.75, 0.65])

  绘制损失曲线如下:

  绘制决策边界:

  模型在训练集和测试集上的表现:

  可以看到训练集上的准确率高于测试集上的准确率,可以视为过拟合现象,接下来通过L2正则化降低过拟合现象。

3.2 L2正则化

  L2正则化是在损失函数的基础上加了正则项,这样其实并不会影响神经网络的正向传播,只需要对神经网络的反向传播代码和损失函数计算代码进行调整。

def backward_propagation_with_regularization(X, Y, cache, lambd):"""实现正则化后的反向传播:param X: 输入数据:param Y: 实际标签值:param cache: forward的cache:param lambd: 正则化参数:return:"""m = X.shape[1](Z1, A1, W1, b1, Z2, A2, W2, b2, Z3, A3, W3, b3) = cachedZ3 = A3 - YdW3 = (1 / m) * np.dot(dZ3, A2.T) + ((lambd * W3) / m)db3 = (1 / m) * np.sum(dZ3, axis=1, keepdims=True)dA2 = np.dot(W3.T, dZ3)dZ2 = np.multiply(dA2, np.int64(A2 > 0))dW2 = (1 / m) * np.dot(dZ2, A1.T) + ((lambd / W2) / m)db2 = (1 / m) * np.sum(dZ2, axis=1, keepdims=True)dA1 = np.dot(W2.T, dZ2)dZ1 = np.multiply(dA1, np.int64(A1 > 0))dW1 = (1 / m) * np.dot(dZ1, X.T) + ((lambd * W1) / m)db1 = (1 / m) * np.sum(dZ1, axis=1, keepdims=True)gradients = {"dZ3": dZ3, "dW3": dW3, "db3": db3, "dA2": dA2,"dZ2": dZ2, "dW2": dW2, "db2": db2, "dA1": dA1,"dZ1": dZ1, "dW1": dW1, "db1": db1}return gradients

  损失函数计算代码:

def compute_cost_with_regularization(A3, Y, parameters, lambd):"""实现L2正则化的损失函数计算:param A3: 输出层的输出值:param Y: 实际标签值:param parameters:神经网络参数:param lambd: 正则化参数:return:"""cost_part1 = compute_cost(A3, Y)m = Y.shape[1]W1 = parameters["W1"]W2 = parameters["W2"]W3 = parameters["W3"]L2_regularization_cost = lambd * (np.sum(np.square(W1)) + np.sum(np.square(W2)) + np.sum(np.square(W3))) / (2 * m)cost = cost_part1 + L2_regularization_costreturn cost

  设置超参数lambd=0.7,损失曲线绘制如下:

  决策边界绘制如下:

  模型在训练集和测试集上的表现:

  从结果可以看出,使用L2正则化的后,模型在训练集和测试集上的表现效果十分接近,有效的解决了过拟合。

3.3 dropout正则化

  dropout正则化会影响常规的正向传播和反向传播,损失函数的计算没有影响。正向传播代码如下:

 """dropout正则化前向传播:RELU+DROPOUT,RELU+DROPOUT,SIGMOID:param X:输入数据:param parameters:神经网络参数:param keep_prob: dropout参数:return:"""np.random.seed(1)W1 = parameters["W1"]b1 = parameters["b1"]W2 = parameters["W2"]b2 = parameters["b2"]W3 = parameters["W3"]b3 = parameters["b3"]Z1 = np.dot(W1, X) + b1A1 = relu(Z1)D1 = np.random.rand(A1.shape[0], A1.shape[1])D1 = D1 < keep_probA1 = A1 * D1A1 = A1 / keep_probZ2 = np.dot(W2, A1) + b2A2 = relu(Z2)D2 = np.random.rand(A2.shape[0], A2.shape[1])D2 = D2 < keep_probA2 = A2 * D2A2 = A2 / keep_probZ3 = np.dot(W3, A2) + b3A3 = sigmoid(Z3)cache = (Z1, D1, A1, W1, b1, Z2, D2, A2, W2, b2, Z3, A3, W3, b3)return A3, cache

  反向传播代码如下:

def backward_propagation_with_dropout(X, Y, cache, keep_prob):"""实现dropout正则化后的反向传播:param X: 输入数据:param Y: 标签值:param cache: 正向传播的缓存:param keep_prob: dropout正则化参数:return:"""m = X.shape[1](Z1, D1, A1, W1, b1, Z2, D2, A2, W2, b2, Z3, A3, W3, b3) = cachedZ3 = A3 - YdW3 = (1 / m) * np.dot(dZ3, A2.T)db3 = (1 / m) * np.sum(dZ3, axis=1, keepdims=True)dA2 = np.dot(W3.T, dZ3)dA2 = dA2 * D2dA2 = dA2 / keep_probdZ2 = np.multiply(dA2, np.int64(A2 > 0))dW2 = (1. / m) * np.dot(dZ2, A1.T)db2 = (1. / m) * np.sum(dZ2, axis=1, keepdims=True)dA1 = np.dot(W2.T, dZ2)dA1 = dA1 * D1dA1 = dA1 / keep_probdZ1 = np.multiply(dA1, np.int64(A1 > 0))dW1 = (1. / m) * np.dot(dZ1, X.T)db1 = (1. / m) * np.sum(dZ1, axis=1, keepdims=True)gradients = {"dZ3": dZ3, "dW3": dW3, "db3": db3, "dA2": dA2,"dZ2": dZ2, "dW2": dW2, "db2": db2, "dA1": dA1,"dZ1": dZ1, "dW1": dW1, "db1": db1}return gradients

  将主控函数中的keep_drop的值设为0.86,绘制损失曲线如下:

  绘制决策边界:

  模型在训练集和测试集上的表现效果:

  dropout正则化降低了模型在训练集上的准确率,提高了模型在测试集上的准确率,成功地解决了过拟合现象。另外,在写代码的过程中,初始化矩阵D时,使用了randn函数而不是rand函数,导致结果偏低。
  rand和randn都是numpy库中生成的随机数的函数,但是rand是生成一个数组,并在数组中加入在[0,1]之间均匀分布的随机样本。randn则是创建一个数组,数组中的元素符合正态分布。很明显在dropout正则化中,我们需要初始化数组D中的数据在[0,1]之间均与分布,这样就可以保证D中小于keep_drop的元素占比为keep_drop。

总结

  再次声明,本博客的主要代码参考来源为【中文】【吴恩达课后编程作业】Course 2 - 改善深层神经网络 - 第一周作业(1&2&3) - 初始化、正则化、梯度校验,原博客讲述更加详细。本人的代码已上传到百度网盘中,提取码:uu35。

吴恩达深度学习课程第二章第一周编程作业相关推荐

  1. 神经网络隐藏层个数怎么确定_含有一个隐藏层的神经网络对平面数据分类python实现(吴恩达深度学习课程1第3周作业)...

    含有一个隐藏层的神经网络对平面数据分类python实现(吴恩达深度学习课程1第3周作业): ''' 题目: 建立只有一个隐藏层的神经网络, 对于给定的一个类似于花朵的图案数据, 里面有红色(y=0)和 ...

  2. 吴恩达深度学习第四课第一周 卷积神经网络

    文章目录 前言 一.计算机视觉(引言) 二.边缘检测示例(过滤器) 三.更多边缘检测内容(由亮到暗还是由暗到亮?) 四.Padding(Valid.Same.p) 五.卷积步长(s) 六.三维卷积(通 ...

  3. 吴恩达深度学习笔记(假期第一周)

    什么是超参数? 比如算法中的 learning rate

  4. 吴恩达深度学习课程之第四门课 卷积神经网络 第二周 深度卷积网络

    本文参考黄海广主编针对吴恩达深度学习课程DeepLearning.ai <深度学习课程 笔记 (V5.1 )> 第二周 深度卷积网络 2.1 为什么要进行实例探究?(Why look at ...

  5. 360题带你走进深度学习!吴恩达深度学习课程测试题中英对照版发布

    吴恩达的深度学习课程(deepLearning.ai)是公认的入门深度学习的宝典,本站将课程的课后测试题进行了翻译,建议初学者学习.所有题目都翻译完毕,适合英文不好的同学学习. 主要翻译者:黄海广 内 ...

  6. github标星8331+:吴恩达深度学习课程资源(完整笔记、中英文字幕视频、python作业,提供百度云镜像!)...

    吴恩达老师的深度学习课程(deeplearning.ai),可以说是深度学习入门的最热门课程,我和志愿者编写了这门课的笔记,并在github开源,star数达到8331+,曾经有相关报道文章.为解决g ...

  7. 吴恩达深度学习课程笔记(四):卷积神经网络2 实例探究

    吴恩达深度学习课程笔记(四):卷积神经网络2 实例探究 吴恩达深度学习课程笔记(四):卷积神经网络2 实例探究 2.1 为什么要进行实例探究 2.2 经典网络 LeNet-5 AlexNet VGG- ...

  8. 吴恩达深度学习课程笔记之卷积神经网络(2nd week)

    0 参考资料 [1]  大大鹏/Bilibili资料 - Gitee.com [2] [中英字幕]吴恩达深度学习课程第四课 - 卷积神经网络_哔哩哔哩_bilibili [3]  深度学习笔记-目录 ...

  9. 吴恩达深度学习课程的漫画版来了!(漫画、视频、笔记都可以下载了!)

    吴恩达深度学习课程,个人认为是对初学者最友好的课程,非常系统.初学者如果希望快速入门,建议从这门课开始.由于是视频课,除了课程笔记之外,可以先看看课程漫画,更有助于理解. 尽管是英文版,但英文水平达到 ...

  10. 吴恩达深度学习课程笔记(初步认识神经网络)

    吴恩达深度学习课程笔记1 课程主要内容 1.神经网络与深度学习介绍 2.Improving Deep Neural Networks:超参数调整,正则化,优化方法 3.结构化机器学习工程:比如如何分割 ...

最新文章

  1. linux高性能网络编程,Linux高性能网络编程的介绍
  2. 多组两两比较用什么检验方法_用SPSS进行不同变量多组间两两比较卡方检验.pdf...
  3. jquery-autoComplete 插件使用
  4. cpp 条件判断 大于等于_第31p,if条件语句,请满足我的要求
  5. [骨科手术导航]2D/3D医学图像配准研究_罗博博_南方科技大学
  6. 基本数据类型之间的运算
  7. linux命令 正则表达式,详解Linux命令中的正则表达式
  8. java中的codereview
  9. postgresql python连接不用把密码写在代码里[.pgpass]
  10. 为什么 12306 时不时要崩那么一下?
  11. Elasticsearch.service failed after enable elasticsearch security features
  12. 如何量化考核软件开发人员绩效
  13. 智能影视站系统 光线 CMS1.5 正式版
  14. 如何做到长期稳定的禅修?
  15. 如何使用微信、支付宝提现免手续费
  16. 互联网界的IT巨变:从DOS的编辑器,到如今的无代码开发
  17. linux下top指令参数详解及用法
  18. 首例 3次IPO:前2次申请科创板、创业板均撤回、第3次改为主板、难圆其说变更保代及券商……
  19. VC6代码移植VS2008的SDK总结,包括OPENGL和DireX还有Cimage 【总结】
  20. 论文复刻:排污权机制是否提高了企业全要素生产率(附代码、数据、原文献)

热门文章

  1. 机顶盒怎样配置服务器信息,网络机顶盒 桌面配置服务器
  2. MSDE 下载安装、创建管理数据库
  3. GJB 软件质量保证计划(模板)
  4. ARM指令集--相关指令的功能
  5. IAR8.3 STM8安装过程
  6. 得到app产品体验报告
  7. 2021/9/7 ad9361 SPI 通信与数据接口
  8. C#照片合成PDF_ PDF合成或拆分PDF_PDF获取页数
  9. python定时任务启动与停止_Python启动定时任务
  10. 阵列信号处理知识点合集