此分类用于记录吴恩达深度学习课程的学习笔记。
课程相关信息链接如下:
本篇为第二课第一周的内容,1.10到1.14的内容,也是本周理论部分的最后一篇。
本周为第二课的第一周内容,就像课题名称一样,本周更偏向于深度学习实践中出现的问题和概念,在有了第一课的机器学习和数学基础后,可以说,在理解上对本周的内容不会存在什么难度。
当然,我也会对一些新出现的概念补充一些基础内容来帮助理解,在有之前基础的情况下,按部就班即可对本周内容有较好的掌握。
在了解了归一化后,本周课程最后一部分内容介绍了一些实际运行中的梯度现象和相应的一些处理方法。
要提前说明的是,这部分内容涉及较多的数学基础。而涉及到的核心概念:梯度检验,又因为现在技术的成熟而几乎不再使用,即使使用,现有的流行框架也都有相应封装好的方法。
因此,相比课程里的推公式,我会更偏向减少公式的出现,用实例和比喻来解释概念,当然,仍会对核心的公式和原理进行解释。
同样,如果你希望只了解概念及其作用,我会在最后,用一版“人话版总结”来做这部分内容。
假设我们有一个 4 层的简单神经网络,不设激活函数(或者设为原值)每层权重的平均值是 0.9。
梯度反向传播时,每经过一层都会乘上该层的导数,大约为 0.9:
梯度稍微变小了一点,这没问题。
但如果层数再多,比如 20 层:
[text{总梯度} = 0.9^{20} = 0.12 ]
这时梯度几乎消失了。
如果再更多层呢?这样下来,每次参数的更新就会小的几乎没有,就像一个步履蹒跚的老人下山,让模型的学习永无尽头,这就是梯度消失(vanishing gradient)。
反过来,如果每层平均值是 1.2:
[1.2^{20} = 38.3 ]
这时梯度变得极大,出现“爆炸”,这样次次迭代后参数就会像一个超人一样次次进化,最后飞在天上下不来,更别说“找谷底”了,这就是梯度爆炸(Exploding Gradient)。

再用一个例子来说明二者在实际运行中的效果:
再来看一个实例:
假设现在我们使用 Sigmoid 激活函数:
[sigma(x) = frac{1}{1 + e^{-x}} ]

其导数最大值为 (0.25)。
如果网络有 10 层,那么误差信号传回输入层的幅度最多为:
[(0.25)^{10} = 9.5 times 10^{-7} ]
几乎为零。
这就是为什么深层网络用 Sigmoid 会难以训练,我们通常在二分类的输出层使用它而不是隐藏层的原因之一。
最后总结一下判断二者的实验现象:
而如何避免这种情况产生?很明显,在数据合理的前提下,我们就要给参数一个合理的初值,让它在后续更新中既不会太大,也不会太小。
也就是初始化问题,之前在简单的神经网络里,我们学习了随机初始化,而现在深层神经网络中,我们也有相应的初始化方法。
梯度之所以不稳定,是因为初始权重太小或太大导致信号在层间放大或缩小。
因此我们希望每一层的输入和输出方差保持一致。
好像有些模糊,为什么方差一致就能让梯度稳定? 我们由此来展开解释:
在神经网络中,每一层都会对输入做一次线性变换,看一眼老公式,就不再重复了:
[z^{(l)} = W^{(l)}x^{(l-1)} + b^{(l)} ]
而现在,我们希望:
[Var(z^{(l)}) approx Var(x^{(l-1)}) (Var:方差,variance) ]
也就是说,一层输出的波动幅度(方差)不要比输入大或小太多。
其实这和我们刚刚阐述的梯度现象是一个道理,只是刚刚是用反向传播说明,现在是用正向传播说明:
想象每层都稍微放大一点信号(方差增加):
[Var(x^{(l)}) = 1.2 times Var(x^{(l-1)}) ]
如果有 20 层:
[Var(x^{(20)}) = 1.2^{20} times Var(x^{(0)}) approx 38 times Var(x^{(0)}) ]
这意味着信号在传播过程中被放大了 38 倍,
→ 在反向传播时,梯度也会被同样放大 → 梯度爆炸。
反过来,如果每层都缩小一点信号(方差减少):
[Var(x^{(l)}) = 0.9 times Var(x^{(l-1)}) ]
那么:
[Var(x^{(20)}) = 0.9^{20} times Var(x^{(0)}) approx 0.12 times Var(x^{(0)}) ]
→ 信号越来越小,最终接近 0,
→ 梯度反向传播时也会逐层消失 → 梯度消失。
还是刚刚那个比方:

因此,我们才需要每一层的输入和输出方差保持一致。
理清楚逻辑后,我们来看看如何通过初始化来实现方差一致:
对于单个神经元:(偏置不影响方差,这里省去)
[z = sum_{i=1}^n w_i x_i ]
假设:
[Var(z) = sum_{i=1}^n Var(w_i x_i) ]
又因为 (w_i) 与 (x_i) 独立:(这是数学里概率论部分的知识)
[Var(w_i x_i) = Var(w_i),Var(x_i) = sigma_w^2 sigma_x^2 ]
因此:
[Var(z) = n ,sigma_w^2 sigma_x^2 ]
若我们希望输出的方差与输入的方差相同(即方差保持一致),设 (Var(z) = sigma_x^2),则:
[n ,sigma_w^2 sigma_x^2 = sigma_x^2 quadRightarrowquad sigma_w^2 = frac{1}{n} ]
最终,我们得出结论:如果输入方差为 (sigma_x^2) 且满足上述独立性假设,那么把权重的方差设为 (1/n)((n) 为该层的输入维度,也称 fan_in)可以使输出方差与输入方差保持一致。
来看一个具体的例子:
假设 fan_in = n = 100,且输入每个通道方差 (sigma_x^2 = 1)(应用归一化的结果)。
若不这么做,比如 (sigma_w = 0.5)((sigma_w^2=0.25))更大:
若 (sigma_w = 0.01)((sigma_w^2=1e-4))更小:
这便是权重初始化的核心概念:即通过控制权重的方差,让信号方差保持恒定。 既避免了梯度爆炸,又避免了梯度消失。
在此思想上,便发展出了以下几种适应不同激活函数的初始化,涉及具体实验和文献,就不再展开了:
| 初始化方法 | 核心思想 | 适用激活函数 | 公式 | 举例说明 |
|---|---|---|---|---|
| Xavier (Glorot) | 让输入输出方差一致 | Sigmoid / Tanh | (Var(W)=frac{1}{n_{in}+n_{out}}) | 若一层输入神经元 100 个、输出 50 个: (Var(W)=1/(150)=0.0067), 权重可在 ([-0.08, 0.08]) 之间随机取值 |
| He (Kaiming) | 针对 ReLU 激活的特性调整 | ReLU / Leaky ReLU | (Var(W)=frac{2}{n_{in}}) | 输入 100 个神经元 → (Var(W)=0.02), 标准差 ≈ (0.14),可从 ([-0.28,0.28]) 随机取值 |
总结一下,把权重初始化为合适的方差,相当于在网络刚开始训练时把“信号音量”调到合适的档位,这能让信号在层间既不被放大成噪音(爆炸),也不被削弱成耳语(消失)。不同激活函数会改变信号统计特性,所以需要不同的初始化。
梯度检验的目标是验证反向传播计算的梯度是否正确。
这在早期手写反向传播时代是非常重要的调试工具。
梯度检验的核心思想是:用数值方法逼近梯度,再与反向传播计算的梯度对比,检查实现是否正确,我们用实例来更好的说明这个过程。
首先,假设损失函数为:(J(theta) = theta^2)
当前参数:(theta = 3)
然后,用有限差分法近似梯度:
[frac{partial J(theta)}{partial theta} approx frac{J(theta + varepsilon) - J(theta - varepsilon)}{2varepsilon}, quad varepsilon = 10^{-4} ]
计算:
[J(3 + 0.0001) = 9.00060001 ,J(3 - 0.0001) = 8.99940001 ]
[grad_{num}= frac{9.00060001 - 8.99940001}{0.0002} = 6.000 ]
现在我们就得到了数值梯度,这是我们用有限差分计算得到的实际数值。
现在,对损失函数求导代入:
[grad_{bp}=frac{dJ}{dtheta} = 2theta = 6 ]
现在我们就得到了理论梯度,这是我们通过求导得到的理论答案。
梯度检验的公式如下:
[error = frac{|grad_{num} - grad_{bp}|}{|grad_{num}| + |grad_{bp}|} = frac{|6.000 - 6|}{6.000 + 6} =0 ]
结果为 (0),说明反向传播梯度实现正确,但实际上的数值不会这么简单。
若我们的反向传播错误(例如少乘了一项),数值梯度与反向传播梯度之间的差异就会很明显,从而发现问题。
对梯度检验的结果判别如下:
| error 量级 | 含义 |
|---|---|
| (error | 极小误差,反向传播实现完全正确 |
| (10^{-7} le error | 误差较小,可接受,可能存在微小数值舍入差异 |
| (10^{-4} le error | 误差明显,反向传播可能有小错误,需要检查 |
| (error ge 10^{-2}) | 误差很大,反向传播实现错误明显 |
这便是早期梯度检验的主要过程,但在现在已经很少使用了。
在实际使用梯度检验时,需要注意以下几点:
| 概念 | 原理 | 作用 | 比喻 |
|---|---|---|---|
| 梯度消失 | 信号在多层网络中逐层缩小,导致反向传播梯度几乎为 0 | 网络学习极慢,权重几乎不更新 | 传话游戏越传越小声,最后听不见 |
| 梯度爆炸 | 信号在多层网络中逐层放大,导致反向传播梯度非常大 | 网络训练不稳定,loss 发散或 NaN | 传话游戏越传越大声,最后系统崩溃 |
| 权重初始化 | 给权重一个合适方差,使每层输出方差 ≈ 输入方差 | 避免梯度消失或爆炸,让信号稳定传播 | 调音器把每层信号音量调到合适档位,既不吵也不小声 |
| 梯度检验 | 用数值方法近似梯度,与反向传播梯度比对 | 验证反向传播是否正确 | 对照答案检查作业,发现漏算或写错的地方 |
登录查看全部
参与评论
手机查看
返回顶部