吴恩达深度学习课程一:神经网络和深度学习 第三周:浅层神经网络(二)
此分类用于记录吴恩达深度学习课程的学习笔记。课程相关信息链接如下:
[*]原课程视频链接:[双语字幕]吴恩达深度学习deeplearning.ai
[*]github课程资料,含课件与笔记:吴恩达深度学习教学资料
[*]课程配套练习(中英)与答案:吴恩达深度学习课后习题与答案
本篇为第一课第三周,3.6到3.10部分的笔记内容。
经过第二周的基础补充,本周内容的理解难度可以说有了很大的降低,主要是从逻辑回归扩展到浅层神经网络,讲解相关内容,我们按部就班梳理课程内容即可,当然,依旧会尽可能地创造一个较为丝滑的理解过程。
我们继续上一篇的内容,来展开一下激活函数对浅层神经网络拟合效果的影响,并完成浅层神经网络的反向传播部分,这样,我们就大致了解了浅层神经网络相比逻辑回归,是如何提高算法性能的。
1. 浅层神经网络里的激活函数
1.1 隐藏层激活函数的作用
在逻辑回归中,我们知道,最后使用sigmoid激活函数是为了让加权和映射为概率从而实现分类效果。
而现在,如果我们仍要进行二分类,而浅层神经网络输出层的sigmoid函数已经实现了分类效果,那隐藏层再使用激活函数的作用是什么?
我们看一看如果不设隐藏层神经元的激活函数,正向传播的输出是什么形式:
[*]首先,隐藏层只有线性组合,那么隐藏层的输出就是加权和本身:
\[\mathbf{Z^{}} = \mathbf{W^{}} \mathbf{X} + \mathbf{b^{}}\]
[*]现在,隐藏层的加权和就是输出层的输入,即:
\[\mathbf{Z^{}} = \mathbf{W^{}}( \mathbf{W^{}} \mathbf{X} + \mathbf{b^{}} ) + \mathbf{b^{}}= \mathbf{W^{}}\mathbf{W^{}} \mathbf{X}+(\mathbf{W^{}}\mathbf{b^{}} + \mathbf{b^{}})\quad (1 \times m)\]
[*]我们观察一下就会发现,\(\mathbf{Z^{}}\) 的实际形式没有发生任何变化,我们换一个示例看一下:
\
可以发现,其形式依旧是“权重 × 输入 + 偏置”的线性表达式。
也就是说,无论我们堆叠多少层这样的“线性层”,最后得到的结果仍然等价于一个没有任何非线性能力的线性模型。这与逻辑回归本质上并没有区别。
在这种情况下,多层和一层的区别就相当于:
\
\
这便是激活函数的核心作用:引入非线性
1.2 激活函数如何引入非线性?
我们已经知道, 在没有激活函数的情况下,神经元的输出是:
\[\mathbf{A^{}} = \mathbf{Z^{}} = \mathbf{W^{}}\mathbf{X} + \mathbf{b^{}}\]
而当我们加入激活函数 \(g(x)\) 后,输出就变成:
\[\mathbf{A^{}} = g(\mathbf{Z^{}}) = g(\mathbf{W^{}}\mathbf{X} + \mathbf{b^{}})\]
因为此时,下一层的输入就变成了一个经过非线性映射的结果:
\[\mathbf{Z^{}} = \mathbf{W^{}},g(\mathbf{W^{}}\mathbf{X} + \mathbf{b^{}}) + \mathbf{b^{}}\]
这意味着:
如果 \(g(x)\) 是线性的(例如恒等函数 \(g(z)=z\)),网络整体依旧是线性关系;
而只要 \(g(x)\) 是非线性函数(如 Sigmoid、ReLU、tanh 等),网络整体的映射关系就无法再化简为一个单一的线性变换。
我们继续刚刚那个例子:
\
现在我们只改一点,把激活函数换成ReLU,即:
\
隐藏层的传播过程即为:
\} = 2x + 1,\quad A^{} = \max(0, 2x+1)\]
再输入输出层:
\} = 3A^{} + 1 = 3\max(0, 2x+1) + 1\]
这个时候,整体的输出函数变成:
\
这就是一个分段线性函数,可以拐弯、有“折点”,不再是单一直线。
那如果再换成更复杂的激活函数呢?
这也意味着网络具备了拟合非线性关系的能力。
最后看一张图:
我们想通过图中的几个数据点进行拟合,没有激活函数,我们就只能像左侧一样画一条直线,而只有使用了激活函数,我们才能让这条直线弯曲,来实现更好拟合效果。
1.3 常见的激活函数
在了解了激活函数的作用——为神经网络引入非线性能力之后,我们来看看几种常见的激活函数及其特性。不同的激活函数,会对神经元的输出特征、梯度传播和训练效果产生显著影响。
(1)Sigmoid 函数
Sigmoid 的表达式为:
\
其输出范围在 \((0, 1)\) 之间,形状如“S”型曲线。
Sigmoid 的优点在于它可以将任意实数映射为 \((0,1)\),非常适合二分类任务的输出层,例如预测概率。
缺点是当输入较大或较小时,梯度接近 0,容易出现梯度消失问题,导致网络难以训练。
(2)Tanh函数
Tanh 是 Sigmoid 的改进版本,其表达式为:
\
输出范围在 \((-1, 1)\) 之间,同样是“S”型曲线。
Tanh 的优点在于输出均值为 0,有助于加快梯度下降的收敛,并在一定程度上缓解了梯度消失问题。
缺点在于,当输入过大或过小时,依然会出现梯度趋于 0 的饱和现象。
如果把 Sigmoid 看作“挤压到 ”,那么 Tanh 就是“挤压到 [-1,1]”,更加对称,有利于后续层学习,因此,Tanh比sigmoid更适合作为隐藏层的激活函数。
(3)ReLU函数
ReLU 是目前最常用的激活函数之一,定义为:
\
当输入为正时,输出等于自身;当输入为负时,输出为 0。
ReLU 的优点在于计算简单,梯度传播效率高,并且在正区间保持线性,减少了梯度消失问题,从而加快训练速度。
缺点在于对于负输入,梯度恒为 0,容易出现“神经元死亡”现象,即某些神经元永远输出 0,无法更新。
(4)Leaky ReLU(带泄漏的 ReLU)
为了缓解 ReLU 的“神经元死亡”问题,便出现了 Leaky ReLU:
\
其中 \(\alpha\) 是一个很小的常数(通常取 0.01)。Leaky ReLU 的优点在于对负区间保留一个微小的斜率,避免梯度完全为 0,从而训练更加稳定,减少“死神经元”的出现。
缺点是其输出仍然不是严格的零中心,且 \(\alpha\) 的选取需要进行调试。
2.浅层神经网络的反向传播
我们知道,在浅层神经网络里,我们涉及到两个层级各自的权重和偏置,因此,不同于逻辑回归中的一次更新,我们这次需要在一次反向传播过程中,更新两个层级的参数。
参数的传递过程如下:
\[\begin{aligned}&\text{隐藏层参数(4个神经元):} \\&\Delta W^{}, \Delta b^{} \;\; \to \;\; \Delta Z^{} \;\; \to \;\; \Delta A^{} \\\\&\text{输出层参数(1个神经元):} \\&\Delta W^{}, \Delta b^{} \;\; \to \;\; \Delta Z^{} \;\; \to \;\; \Delta A^{} \to \;\; \Delta L\\\end{aligned}\]
2.1 损失函数
我们知道二分类交叉熵成本函数格式如下:
\[\mathcal{L} = -\frac{1}{m} \sum_{i=1}^{m} \Big[ y^{(i)} \log a^{(i)} + (1 - y^{(i)}) \log (1 - a^{(i)}) \Big]\]
向量化后即可表示为: $$ \mathcal{L}(\mathbf{A^{}}, \mathbf{Y}) $$
我们依旧通过损失函数,使用链式法则来计算梯度。
2.2 输出层梯度
输出层激活函数为 \(sigmoid(x)\)
而输出层误差定义为:
\[\mathbf{dZ^{}} = \frac{\partial \mathcal{L}}{\partial \mathbf{Z^{}}} \]
在第二周的推导中,我们已经知道,对于二分类交叉熵 + sigmoid,损失对加权和的导数可简化为:
\[\mathbf{dZ^{}} = \mathbf{A^{}} - \mathbf{Y} \quad (1 \times m)\]
继续通过链式法则,我们得到输出层权重和偏置的梯度(详细过程可看第二周的推导):
\[\mathbf{dW^{}} = \frac{1}{m} \mathbf{dZ^{}} (\mathbf{A^{}})^T \quad (1 \times 4)\]
\[\mathbf{db^{}} = \frac{1}{m} \sum_{i=1}^{m} \mathbf{dZ^{(i)}} \quad (1 \times 1)\]
3.3 隐藏层梯度
对于隐藏层,这里我们便不定义具体的激活函数,用通式来展示过程:
先梳理一下我们现在有的量:
[*]损失对输出层加权和的导数\(\mathbf{dZ^{}}\)
[*]隐藏层的加权和\(\mathbf{Z^{}}\)
[*]隐藏层的的加权和经过激活函数的输出\(\mathbf{A^{}}\)
[*]隐藏层的激活函数\(g(\mathbf{Z^{}})\) 和它的导数\(g'(\mathbf{Z^{}})\)
[*]隐藏层的参数\(\mathbf{W^{}}\),\(\mathbf{b^{}}\)
现在,我们要求隐藏层参数的梯度,首先要得到损失关于隐藏层输出的导数,即:
\[\mathbf{dA^{}} = \frac{\partial \mathcal{L}}{\partial \mathbf{A^{}}} \]
再通过链式法则细化一下,我们得到:
\[\mathbf{dA^{}} = \mathbf{dZ^{}}⋅ \frac{\partial \mathbf{Z^{}}}{\partial \mathbf{A^{}}} \]
再看一眼加权和公式:
\[\mathbf{Z^{}} = \mathbf{W^{}}\mathbf{A^{}}+ \mathbf{b^{}} \quad (1 \times m)\]
所以,通过求导我们得到:
\[\mathbf{dA^{}} = \mathbf{(W^{})^T}\mathbf{dZ^{}},转置为了匹配维度\quad (4 \times m)\]
下一步,得到损失关于隐藏层加权和的输出,即:
\[\mathbf{dZ^{}} = \mathbf{dA^{}}⋅ \frac{\partial \mathbf{A^{}}}{\partial \mathbf{Z^{}}} \]
而隐藏层输出对加权和求导,其实就是激活函数的导数:\(g'(\mathbf{Z^{}})\)
因此,我们得到:
\[\mathbf{dZ^{}} = \mathbf{dA^{}}⋅ g'(\mathbf{Z^{}})\quad (4 \times m)\]
注意!这里的乘是Hadamard 乘。
Hadamard 乘激活导数 = 对每个神经元每个样本的误差单独乘上对应的激活导数
到了这一步,我们就可以得到最后的梯度:
\[\mathbf{dW^{}} = \frac{1}{m} \mathbf{dZ^{}} \mathbf X^T \quad (4 \times n)\]
\[\mathbf{db^{}} = \frac{1}{m} \sum_{i=1}^{m} \mathbf{dZ^{}_{:,i}} \quad (4 \times 1)\]
还没完,这里还有一点要强调,注意看这个符号:\(\mathbf{dZ^{}_{:,i}}\)
我们之前的逻辑回归,以及本次传播的输出层偏置,使用的符号都是\(\mathbf{dZ^{(i)}}\),对这个符号求平均就代表对 \(m\) 个样本在同一神经元上的误差求平均。
而现在,我们的隐藏层有四个神经元,由此解释一下\(\frac{1}{m} \sum_{i=1}^{m} \mathbf{dZ^{}_{:,i}}\) 的含义:
[*]"\(:\)"代表所有行
[*]"\(:,i\)"代表第 \(i\) 列
[*]"\(\sum_{i=1}^{m} \mathbf{dZ^{}_{:,i}}\)"代表对\(dZ^{}\) 的每一列求和,得到的结果是所有样本分别在四个隐藏神经元总误差
[*]最后求平均值,即为平均误差,现在, 每个元素就对应一个隐藏神经元的偏置梯度。
我们也总结一下反向传播过程中各个量和其维度:
量维度说明Xn × m输入特征W4 × n隐藏层权重b4 × 1 → 4×m隐藏层偏置(广播)Z4 × m隐藏层线性组合A4 × m隐藏层激活输出W1 × 4输出层权重b1 × 1 → 1×m输出层偏置(广播)Z1 × m输出层线性组合A1 × m输出层激活输出dZ1 × m输出层误差dW1 × 4输出层权重梯度db1 × 1输出层偏置梯度dA4 × m输出层误差传回隐藏层dZ4 × m隐藏层误差(Hadamard乘激活导数)dW4 × n隐藏层权重梯度db4 × 1隐藏层偏置梯度3.4 更新参数
在完成所有梯度计算后,我们就可以使用梯度下降法来更新网络的权重和偏置,公式如下:
(1) 输出层参数更新
\[\mathbf{W^{}} := \mathbf{W^{}} - \eta\mathbf{dW^{}}\]
\[\mathbf{b^{}} := \mathbf{b^{}} - \eta \mathbf{db^{}}\]
(2) 隐藏层参数更新
\[\mathbf{W^{}} := \mathbf{W^{}} - \eta\mathbf{dW^{}}\]
\[\mathbf{b^{}} := \mathbf{b^{}} - \eta\mathbf{db^{}}\]
这样,我们就完成了浅层神经网络的一个反向传播过程的梳理。
相比逻辑回归,浅层神经网络在一次反向传播中更新了两层参数,而在之后的更复杂的神经网络结构中,隐藏层数量也不只一层,这样,在一次反向传播中,就会更新更多的参数。
但其形式,也只是像现在这样的通过链式法则的层层求导,更新即可。
所以,之后便会尽量少的出现这样比较繁杂的求导,但前提是要了解神经网络通过反向传播更新参数的逻辑。
下一篇即为本周理论部分的最后一部分,是神经网络的参数初始化,也是多个隐藏层神经元能发挥不同作用的原因。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! 这个好,看起来很实用 感谢分享,下载保存了,貌似很强大
页:
[1]