吴恩达深度学习第一门课第二周—神经网络的编程基础学习笔记

第一周的课程主要是对神经网络和深度学习的介绍(发展,价值,前景),于是我从第二周开始记录学习笔记。

本周学习概要:

通过逻辑回归的实例学习了神经网络的基础知识,以及神经网络的计算(前向传播和反向传播),如何不使用 for 循环处理训练集(向量化)。

一.二分类

逻辑回归是一个用于二分类(binary classification)的算法。

先引入一个二分类问题的例子,假如有一张图片作为输入,比如这只猫,如果识别这张图片为猫,则输出标签 1 作为结果;如果识别出不是猫,那么输出标签 0 作为结果。现在可以用字母𝑦来表示输出的结果标签,如下图所示:

在二分类问题中,我们的目标就是习得一个分类器,它以图片的特征向量作为输入,然后预测输出结果𝑦为 1 还是 0,也就是预测图片中是否有猫。

一些符号说明(后续课程里会用到):

用一对(𝑥, 𝑦)来表示一个单独的样本,𝑥代表𝑛𝑥维的特征向量,𝑦 表示标签(输出结果)只
能为 0 或 1。 而训练集将由𝑚个训练样本组成,其中(𝑥(1), 𝑦(1))表示第一个样本的输入和输
出,(𝑥(2), 𝑦(2))表示第二个样本的输入和输出,直到最后一个样本(𝑥(𝑚), 𝑦(𝑚)),然后所有的
这些一起表示整个训练集。有时候为了强调这是训练样本的个数,会写作𝑀𝑡𝑟𝑎𝑖𝑛,当涉及
到测试集的时候,我们会使用𝑀𝑡𝑒𝑠𝑡来表示测试集的样本数。

二.逻辑回归

逻辑回归的 Hypothesis Function(假设函数)

对于二元分类问题来讲,给定一个输入特征向量𝑋,它可能对应一张图片,想识别这张图片看它是否是一只猫或者不是一只猫,需要一个算法能够输出预测,称之为𝑦^,也就是对实际值 𝑦 的估计(对于上节课识别猫的问题,𝑦^即表示这张图是一只猫的图片的几率)。

用𝑤来表示逻辑回归的参数,这也是一个𝑛𝑥维向量(因为𝑤实际上是特征权重,维度与特征向量相同),参数里面还有𝑏,这是一个实数(表示偏差)。所以给出输入𝑥以及参数𝑤和𝑏之后,𝑦^ = 𝑤𝑇𝑥 + 𝑏,这是一个关于输入𝑥的线性函数,实际上这是在做线性回归时所用到的,但是这对于二元分类问题来讲不是一个非常好的算法,因为你想让𝑦^表示实际值𝑦等于 1 的机率的话,𝑦^ 应该在 0 到 1 之间,因此在逻辑回归中,我们的输出应该是𝑦^等于由上面得到的线性函数式子作为自变量的sigmoid 函数中,将线性函数转换为非线性函数:

实现了逻辑回归,下一步要做的就是训练参数𝑤以及𝑏,使得𝑦^成为对𝑦 = 1这一情况的概率的一个很好的估计。 

逻辑回归的代价函数

为什么需要代价函数:为了训练逻辑回归模型的参数𝑤和参数𝑏,需要一个代价函数,通过训练代价函数来得到参数𝑤和参数𝑏。

损失函数:
损失函数又叫做误差函数,用来衡量算法的运行情况,Loss function:𝐿(𝑦^ , 𝑦).
我们通过这个𝐿称为的损失函数,来衡量预测输出值和实际值有多接近。在逻辑回归中用到的损失函数是:𝐿(𝑦^ , 𝑦) = −𝑦log(𝑦^) − (1 − 𝑦)log(1 − 𝑦^)

解释:当𝑦 = 1时损失函数𝐿 = −log(𝑦^),如果想要损失函数𝐿尽可能得小,那么𝑦^就要尽可能
大,因为 sigmoid 函数取值[0,1],所以𝑦^会无限接近于 1。
当𝑦 = 0时损失函数𝐿 = −log(1 − 𝑦^),如果想要损失函数𝐿尽可能得小,那么𝑦^就要尽
可能小,因为 sigmoid 函数取值[0,1],所以𝑦^会无限接近于 0。(也就是损失函数越小,y与𝑦^越相近,这样就可以通过找损失函数的最小值,找到最优的参数w,b)。

算法的代价函数(对于全部训练样本)是对𝑚个样本的损失函数(对于单个训练样本)求和然后除以𝑚:

(实际上,从输入到计算出J的整个过程就是前向传播) 

 训练逻辑回归模型时候,我们需要找到合适的𝑤和𝑏,来让代价函数 𝐽 的总代价降到最低。下面将学习如何找到代价函数 𝐽的最小点及对应的最优𝑤和𝑏。

三.梯度下降

简介梯度下降法

 

 在这个图中,横轴表示你的空间参数𝑤和𝑏,在实践中,𝑤可以是更高的维度,但是为
了更好地绘图,定义𝑤和𝑏,都是单一实数,代价函数(成本函数)𝐽(𝑤, 𝑏)是在水平轴
𝑤和𝑏上的曲面,因此曲面的高度就是𝐽(𝑤, 𝑏)在某一点的函数值。我们所做的就是找到使得代价函数(成本函数)𝐽(𝑤, 𝑏)函数值是最小值,对应的参数𝑤和𝑏。

由于逻辑回归的代价函数(成本函数)𝐽(𝑤, 𝑏)特性,必须定义代价函数(成本函数)𝐽(𝑤, 𝑏)为凸函数。 初始化𝑤和𝑏,可以用从图中的小角的某一个点来初始化参数𝑤和𝑏,也可以采用随机初始化的方法,对于逻辑回归几乎所有的初始化方法都有效,因为函数是凸函数,无论在哪里初始化,应该达到同一点或大致相同的点。

 

通过以上的三个步骤我们可以找到全局最优解,也就是代价函数(成本函数)𝐽(𝑤, 𝑏)
这个凸函数的最小值点。下面是公式表示:

: =表示更新参数,
𝑎 表示学习率(learning rate),用来控制步长(step),即向下走一步的长度,

 不断重复图中的公式(迭代),直至到达最小值点,这就是梯度下降的过程。

注释:𝜕 表示求偏导符号,可以读作 round, 𝜕𝐽(𝑤,𝑏)/𝜕𝑤 就是函数𝐽(𝑤, 𝑏) 对𝑤 求偏导,在代码中会使用𝑑𝑤 表示这个结果, 𝜕𝐽(𝑤,𝑏)/𝜕𝑏 就是函数𝐽(𝑤, 𝑏)对𝑏 求偏导,在代码中会使用𝑑𝑏 表示这个结果。

 逻辑回归中的梯度下降

 

如图所示画出计算图,下面来反向计算dw,db :

首先计算da,在编写代码时,只需要用𝑑𝑎 来表示𝑑𝐿(𝑎,𝑦)/𝑑𝑎 :

接着计算dz:

 

然后得到dw,db: 

 

m对应的是多个样本的梯度下降算法,对于单个样本使用𝑑𝑤1 = 𝑥1 ⋅ 𝑑𝑧 计算𝑑𝑤1, 𝑑𝑤2 = 𝑥2 ⋅ 𝑑𝑧计算𝑑𝑤2, 𝑑𝑏 = 𝑑𝑧 来计算𝑑𝑏。

最后更新参数w,b:

更新𝑤1 = 𝑤1 − 𝑎𝑑𝑤1, 更新𝑤2 = 𝑤2 − 𝑎𝑑𝑤2, 更新𝑏 = 𝑏 − 𝛼𝑑𝑏。

这就是关于单个样本实例的梯度下降算法中参数更新一次的步骤,但是,训练逻辑回归模型不仅仅只有一个训练样本,而是有𝑚个训练样本的整个训练集。因此在下一节课中,会将这些思想应用到整个训练样本集中,而不仅仅只是单个样本上。

m个样本的梯度下降 

如图所示,用一个for循环完成了m个样本的一步梯度下降,实际上需要重复该过程很多次。还有当输入特征x很多时(即n比较大时)还会需要一个内层循环,然而代码中显式地使用 for 循环会使算法很低效。同时在深度学习领域会有越来越大的数据集,所以能够应用你的算法且没有显式的 for 循环会是重要的,并且会帮助你适用于更大的数据集。所以这里有一些叫做向量化技术,它可以允许你的代码摆脱这些显式的 for 循环。下面将学习如何应用向量化而连一个 for 循环都不使用

 四.向量化

简单引入

在深度学习领域,运行向量化是一个关键的技巧。

通过 numpy 内置函数和避开显式的循环(loop)的方式进行向量化:

如图,左半部分的循环可用右半部分 z=np.dot(w,x)+b 代替。

向量化逻辑回归和梯度下降

 

 其中的Z,X,A,w,b,dw,db代表的都是矩阵,实际上这一周的重点就是这几个公式,因为在编程作业中会用到的就是这几个。𝑋 是一个 𝑛𝑥 乘以 𝑚 的矩阵,Z 是一个 1 乘以 𝑚 的矩阵,初始化w= 𝑛𝑝. 𝑧𝑒𝑟𝑜𝑠(𝑛𝑥 , 1),b= 𝑛𝑝. 𝑧𝑒𝑟𝑜𝑠(1 ,m ).

补充:事 实 上 , numpy 库 有 很 多 向 量 函 数 。 比 如 u=np.log 是 计 算 对 数 函 数 ( 𝑙𝑜𝑔 ) 、np.abs() 是计算数据的绝对值、 np.maximum() 计算元素𝑦中的最大值,np.maximum(v,0) 、 𝑣 ∗∗ 2 代表获得元素 𝑦 每个值得平方、 1/𝑣 获取元素 𝑦 的倒数等等。

五.Python 中的广播

 在 numpy 中,当一个 4 × 1的列向量与一个常数做加法时,实际上会将常数扩展为一
个 4 × 1的列向量,然后两者做逐元素加法。这种广播机制对于行向量和列向量均可以使用。

看一个例子:

 用一个 2 × 3的矩阵和一个 1 × 3 的矩阵相加,其泛化形式是 𝑚 × 𝑛 的矩阵和 1 × 𝑛的
矩阵相加。在执行加法操作时,其实是将 1 × 𝑛 的矩阵复制成为 𝑚 × 𝑛 的矩阵,然后两者
做逐元素加法得到结果。

广播机制:如果两个数组的后缘维度(矩阵维度元组中的最后一个位置的值)的轴长度相符或其中一方的轴长度为 1,则认为它们是广播兼容的。广播会在缺失维度和轴长度为 1 的维度上进行。

解释:矩阵 𝐴𝑚,𝑛 和矩阵 𝐵1,𝑛 进行四则运算,后缘维度轴长度相符,可以广播,广播沿着轴长
度为 1 的轴进行,即 𝐵1,𝑛 广播成为 𝐵𝑚,𝑛′ ,之后做逐元素四则运算。
  矩阵 𝐴𝑚,𝑛 和矩阵 𝐵𝑚,1 进行四则运算,后缘维度轴长度不相符,但其中一方轴长度为 1,
可以广播,广播沿着轴长度为 1 的轴进行,即 𝐵𝑚,1 广播成为 𝐵𝑚,𝑛′ ,之后做逐元素四则运
算。
  矩阵 𝐴𝑚,1 和常数𝑅 进行四则运算,后缘维度轴长度不相符,但其中一方轴长度为 1,
可以广播,广播沿着缺失维度和轴长度为 1 的轴进行,缺失维度就是 axis=0,轴长度为 1
的轴是 axis=1,即𝑅广播成为 𝐵𝑚,1′ ,之后做逐元素四则运算。

六.小技巧(避免出bug)

尽量不要创建一维数组

当设置𝑎 = 𝑛𝑝. 𝑟𝑎𝑛𝑑𝑜𝑚. 𝑟𝑎𝑛𝑑𝑛(5)时,会生成存储在数组 𝑎 中的 5 个高斯随机数变量。之后输出 𝑎,从屏幕上可以得知,此时 𝑎 的 shape(形状)是一个(5, )的结构。这在 Python 中被称作一个一维数组。它既不是一个行向量也不是一个列向量,这也导致它有一些不是很直观的效果。举个例子,如果我输出一个转置阵,最终结果它会和𝑎看起来一样,所以𝑎和𝑎的转置阵最终结果看起来一样。而如果我输出𝑎和𝑎的转置阵的内积,你可能会想:𝑎乘以𝑎的转置返回给你的可能会是一个矩阵。但是如果我这样做 ,只会得到一个数 。

因此当编写神经网络时,不要在它的 shape 是(5, )还是(𝑛, )或者一维数组时使用数据结构。相反,如果你设置 𝑎 为(5,1),那么这就将置于 5 行 1 列向量中。在先前的操作里 𝑎 和 𝑎 的转置看起来一样,而现在这样的 𝑎 变成一个新的 𝑎 的转置,并且它是一个行向量。请注意一个细微的差别,在这种数据结构中,当我们输出 𝑎 的转置时有两对方括号,而之前只有一对方括号,所以这就是 1 行 5 列的矩阵和一维数组的差别。 

 

多使用断言语句(assertion statement)

 

继续加油,还有很多有趣又深奥的知识等着我们去探索 !

  • 29
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值