目录
1)Neural Network Overview
2)Neural Network Representation
3)Computing a Neural Network’s Output(重点)
4)Vectorizing across multiple examples
5)Activation functions
6)Why need a nonlinear activation function
7)Derivatives of activation functions
8)Gradient descent for neural networks(重点)
9)Backpropagation intuition(选修)(掌握)
10)Random Initialization
11)Summary
以下笔记是吴恩达老师深度学习课程第一门课第三周的的学习笔记:Shallow neural networks。笔记参考了黄海广博士的内容,在此表示感谢。
1)Neural Network Overview
本周我们开始学习如何实现一个神经网络。现在我们开始快速浏览一下如何实现神经网络,上周我们讨论了逻辑回归。神经网络的结构与逻辑回归类似,神经网络可以看作是多个sigmoid单元堆叠而成。下图中上方为单个sigmoid单元,而另一个就是神经网络了。在这个神经网络里首先对应的3个节点,计算第一层网络中各个节点的输出,紧接着计算,位于第二层的节点计算和。整个过程如下:
第一层:输入层到隐藏层
第一层:隐藏层到输出层
在这里,我们规定方括号上标 [i] 表示当前所处的层数。
2)Neural Network Representation
我们再来看看我们上一小节中的二层神经网络图片(一般规定输入层为零层),下图中的神经网络包含一个隐藏层。输入特征被称作神经网络的输入层(the input layer)。 神经网络的隐藏层(a hidden layer)“隐藏”的含义是在训练集中,这些中间节点的真正数值是无法看到的。输出层(the output layer)负责输出预测值。
在写法上,我们通常把输入特征记为,隐藏层记为,隐藏层包含四个节点,从上往下,下标依次递增。隐藏层写成矩阵向量形式为:
最后,输出层为。隐藏层和输出层都是带有参数 W 和 b 的。它们都使用上标[1]
来表示是和第一个隐藏层有关,或者上标[2]
来表示是和输出层有关。
3)Computing a Neural Network’s Output(重点)
介绍完神经网络的表示,现在我们来推导神经网络的推导过程,我们就把两层神经网络看作是两次计算逻辑回归。逻辑回归计算分为两个部分,分别计算 z 和 a。
回到两层的神经网络,我们从隐藏层的第一个神经元开始计算,如上图第一个最上面的箭头所指。从上图可以看出,输入与逻辑回归相似,这个神经元的计算与逻辑回归一样分为两步,小圆圈代表了计算的两个步骤。
- 第一步,计算 。
- 第二步,通过激活函数计算 。
隐藏层的第二个以及后面两个神经元的计算过程一样,只是注意符号表示不同,最终分别得到 ,详细结果见下:
从隐藏层到输出层的计算公式为:
其中为:
值得注意的是层与层之间参数矩阵的规格大小。
- 输入层和隐藏层之间:的 shape 为
(4,3)
,前面的 4 是隐藏层神经元的个数,后面的 3 是输入层神经元的个数;的 shape 为(4,1)
,和隐藏层的神经元个数相同。 - 隐藏层和输出层之间:的 shape 为
(1,4)
,前面的 1 是输出层神经元的个数,后面的 4 是隐藏层神经元的个数;的 shape 为(1,1)
,和输出层的神经元个数相同。
为了提高程序运算速度,我们引入向量化和矩阵运算的思想,将上述表达式转换成矩阵运算的形式:
4)Vectorizing across multiple examples
上一部分我们只是介绍了单个样本的神经网络正向传播的运算过程。而对于m个训练样本,我们也可以使用矩阵相乘的形式来提高计算效率。而且它的形式与上一部分单个样本的矩阵运算十分相似,比较简单。先来看使用for循环计算多个样本输出:
上图中,我们使用for循环计算了神经网络的输出,现在我们把上面的for循环写成矩阵运算的形式:
从水平上看,矩阵A代表了各个训练样本。从竖直上看,矩阵A的不同的索引对应于不同的隐藏单元。对于矩阵Z,X情况也类似,水平方向上,对应于不同的训练样本;竖直方向上,对应不同的输入特征,而这就是神经网络输入层中各个节点。神经网络上通过在多样本情况下的向量化来使用这些等式。
5)Activation functions
之前我们都是选用 sigmoid 函数作为激活函数,但有时其他函数的效果会好得多。 下面我们来总结深度学习中常见的激活函数:
sigmoid函数:对出输出层的激活函数,因为二分类取值范围在(0,1),一般会选择sgmoid函数。
tanh函数:效果几乎总比 sigmoid 函数好(除二元分类的输出层,因为我们希望输出的结果介于 0 到 1 之间),因为函数输出介于 -1 和 1 之间,激活函数的平均值就更接近 0,有类似数据中心化的效果。
然而,tanh 函数存在和 sigmoid 函数一样的缺点:当 z 趋紧无穷大(或无穷小),导数的梯度(即函数的斜率)就趋紧于 0,这使得梯度算法的速度大大减缓。
ReLU函数:当 z > 0 时,梯度始终为 1,从而提高神经网络基于梯度算法的运算速度,收敛速度远大于 sigmoid 和 tanh。然而当 z < 0 时,梯度一直为 0,但是实际的运用中,该缺陷的影响不是很大。
Leaky ReLU函数:Leaky ReLU 保证在 z < 0 的时候,梯度仍然不为 0。理论上来说,Leaky ReLU 有 ReLU 的所有优点,但在实际操作中没有证明总是好于 ReLU,因此不常用。
6)Why need a nonlinear activation function
为什么神经网络需要非线性激活函数?事实证明:要让你的神经网络能够计算出有趣的函数,你必须使用非线性激活函数。
假设所有的激活函数都是线性的,为了简化计算,我们直接令激活函数g(z)=z,即a=z。那么,浅层神经网络的各层输出为:
对上式化简得:
输出仍是输出x的线性组合,使用线性函数作为激活函数,最终的输出仍然是输入x的线性模型。
7)Derivatives of activation functions
在梯度下降反向计算过程中少不了计算激活函数的导数。
我们先来看一下sigmoid函数的导数:
tanh函数的导数:
ReLU函数的导数:
Leaky ReLU函数导数:
8)Gradient descent for neural networks(重点)
现在我们来看卡在神经网络中如何计算梯度。还是我们前面提到的二层神经网络,你的单隐层神经网络会有,,,这些参数,还有个表示输入特征的个数,表示隐藏单元个数,表示输出单元个数。
二层神经网络的正向传播过程为:
反向传播是计算梯度的过程,这里我们直接给出损失函数对各个参数的梯度:左边是梯度下降公式,右边是其向量化代码。
9)Backpropagation intuition(选修)(掌握)
这一节虽然是选修内容,但还是希望大家掌握,当然不理解也不要紧。
我们仍然使用计算图的方式来推导神经网络反向传播过程。记得之前介绍逻辑回归时,我们就引入了计算图来推导正向传播和反向传播,其过程如下图所示:
由于多了一个隐藏层,神经网络的计算图要比逻辑回归的复杂一些,如下图所示。对于单个训练样本,正向过程很容易,反向过程可以根据梯度计算方法逐一推导。
10)Random Initialization
如果在初始时将两个隐藏神经元的参数设置为相同的大小,那么两个隐藏神经元对输出单元的影响也是相同的,通过反向梯度下降去进行计算的时候,会得到同样的梯度大小,所以在经过多次迭代后,两个隐藏层单位仍然是对称的。无论设置多少个隐藏单元,其最终的影响都是相同的,那么多个隐藏神经元就没有了意义。
在初始化的时候,W 参数要进行随机初始化,不可以设置为 0。而 b 因为不存在对称性的问题,可以设置为 0。
以 2 个输入,2 个隐藏神经元为例:
W = np.random.rand(2,2)* 0.01
b = np.zeros((2,1))
这里将 W 的值乘以 0.01(或者其他的常数值)的原因是为了使得权重 W 初始化为较小的值,这是因为使用 sigmoid 函数或者 tanh 函数作为激活函数时,W 比较小,则 Z所得的值趋近于 0,梯度较大,能够提高算法的更新速度。而如果 W 设置的太大的话,得到的梯度较小,训练过程因此会变得很慢。
ReLU 和 Leaky ReLU 作为激活函数时不存在这种问题,因为在大于 0 的时候,梯度均为 1。
11)Summary
本节课主要介绍了浅层神经网络。
- 首先,我们简单概述了神经网络的结构:包括输入层,隐藏层和输出层;
- 然后,我们以计算图的方式推导了神经网络的正向传播,并以向量化的形式归纳出来;
- 接着,介绍了不同的激活函数并做了比较,实际应用中根据不同需要选择合适的激活函数。激活函数必须是非线性的;
- 然后,我们重点介绍了神经网络的反向传播过程以及各个参数的导数推导;
- 最后,介绍了权重随机初始化的重要性,必须对权重W进行随机初始化操作。
下面我们就要进行深层神经网络的学习了。