吴恩达深度学习课程笔记(二):改善深层神经网络
- 吴恩达深度学习课程笔记(二):改善深层神经网络
第一周 深度学习的实用层面
1.1 训练 / 开发 / 测试集
- 应用机器学习算法是一个高度迭代的过程。从一开始的idea,一直要进行不断的尝试、更新。超参数的选择就在这个不断地迭代尝试过程中产生。
- 创建高质量的训练集、验证集、测试集有助于提高迭代效率。
- 训练集训练几个模型;验证集选出最好的模型;在测试集上评估该模型的性能。
- 在小数据时代,可以60%/20%/20%;
- 在大数据时代,验证集和测试集的比例更小;比如1 000 000 条数据,可能取10000条进行验证即可。
训练集和测试集分布不匹配的情况很多:
- 训练猫咪图像分类,训练集图片来组互联网,高清,制作精良;验证集和测试集图像来自用户手机拍摄,质量差,像素低,模糊;
- 经验:确保验证集和测试集的数据来自同一分布。
- 经验:就算没有测试集也ok,测试集的目的是对最后的模型做出无偏的评估,但是如果不需要无偏的评估,就可以不设置测试集。
如果没有测试集,仅有训练集和验证集,那么这个时候验证集被有些人们称之为测试集,但其实这个“测试集”起到的是验证集的作用。所以叫做测试集是错误的。只有两个划分的时候,就只有训练集和验证集。
- 验证集和测试集可以加速神经网络的集成。也可以更有效的衡量算法的偏差和方差。
1.2 偏差 / 方差
通过训练集的误差和验证集的误差查看:
存在高偏差高方差的情况:
上述结论是在基础误差很小的情况下成立的。
1.3 机器学习基础
- 用训练集和验证集检测模型是否存在高偏差or高方差问题。
- 机器学习早期存在方差偏差平衡问题。
- 在大数据和深度学习时代,可以做到只降低偏差(方差),而基本不影响方差(偏差),即在降低一方的同时,不过多影响另一方。比如:
- 适度正则化的情况下,更大的network可以在不影响方差的情况下降低偏差;
- 用更多的数据训练网络能够在不过多影响偏差的情况下降低方差。
在大数据和深度学习时代,不用过多关心如何平衡偏差和方差。这是大数据和深度学习带来的一个益处。
在网络比较规范的情况下,训练一个更大的网络的主要代价也只是计算时间(or算力)。其他负面影响很小。
1.4 正则化
regularization
逻辑回归:
J(w,b)=1m∑mi=1L(y^(i),y(i))+λ2m||w||22 J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m | | w | | 2 2L2 L 2 正则化: λ2m||w||22 λ 2 m | | w | | 2 2 ,其中, ||w||22=∑nxj=1w2j=wTw | | w | | 2 2 = ∑ j = 1 n x w j 2 = w T w
L1 L 1 正则化: λ2m||w||1=λ2m∑nxj=1|wj| λ 2 m | | w | | 1 = λ 2 m ∑ j = 1 n x | w j | ; L1 L 1 正则化之后的 w w 是稀疏的。
神经网络:
J(w[1],b[1],w[2],b[2],...,w[L],b[L])=1m∑mi=1L(y^(i),y(i))+λ2m∑Ll=1||w[l]||2F J ( w [ 1 ] , b [ 1 ] , w [ 2 ] , b [ 2 ] , . . . , w [ L ] , b [ L ] ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m ∑ l = 1 L | | w [ l ] | | F 2
L2 L 2 正则化: λ2m∑Ll=1||w[l]||2F λ 2 m ∑ l = 1 L | | w [ l ] | | F 2 ,其中, ||w||2F=∑n[l]i=1∑n[l−1]j=1w2ij | | w | | F 2 = ∑ i = 1 n [ l ] ∑ j = 1 n [ l − 1 ] w i j 2
则:
dw[l]=∂J∂w[l]+λmw[l] d w [ l ] = ∂ J ∂ w [ l ] + λ m w [ l ]
那么:
w[l]=w[l]−αdw[l]=w[l]−α(∂J∂w[l]+λmw[l])=(1−αλm)w[l]−α∂J∂w[l] w [ l ] = w [ l ] − α d w [ l ] = w [ l ] − α ( ∂ J ∂ w [ l ] + λ m w [ l ] ) = ( 1 − α λ m ) w [ l ] − α ∂ J ∂ w [ l ]
即正则化与没有正则化相比,就是在 w[l] w [ l ] 更新的时候减去了一个 αλmw[l] α λ m w [ l ] ,也就是为原来 w[l] w [ l ] 的 1−αλm 1 − α λ m 倍。
1.5 为什么正则化可以减少过拟合?
如果将 λ λ 取得非常大,那么很多 w w 接近于0,也就是网络变得更加简单,这样会从高方差(过拟合)导致到高偏差(欠拟合)。
但是
适中的时候,我们会减少很多隐藏单元的影响,神经网络变得更简单,不容易发生过拟合。但也不会简化到欠拟合的程度。
直观理解:
如果 w w 在一个很小的区间,那么最后的
也很小,经过激活函数的时候一直在其线性部分,如果整个网络都是这样,那么实际上,这就是个线性分类器。非线性的部分很少。也就是说,如果 w w 的范围小,那么网络去拟合数据集的非线性决策边界的能力就弱,不容易发生过拟合。
1.6 Dropout 正则化
dropout是一种正则化
方法。
能防止过拟合。
除非算法过拟合,不然不使用dropout。
dropout:以一定概率随机删除网络中的神经单元。让每次训练的网络都不同。防止过拟合的问题。
dropout有很多种。
inverted dropout (反向随机失活):
训练阶段:
以神经网络的第三层为例:
keep_prob = 0.8 # 保留80%的节点,删除20%的节点。
d3 = np.random.rand(a3.shape[0], a3.shape[1]) < keep_prob # d3,第三层的dropout矩阵,a3,第三层的输出。
a3 = np.mutiply(a3, b3) # a3 *= b3,点乘
a3 /= keep_prob # 保持a3的期望和与dropout之前相比,不发生变化
a3 /= keep_prob
这一步,保持了a3
的期望不变,所以和不除相比,在测试阶段变得更容易,因为平均值不会发生太大变化。
inverted dropout 最常用。
测试阶段:
测试阶段不使用dropout,所以在训练阶段除以keep_prob
的意义就在于此。即让训练阶段和测试阶段的激活函数的预期结果不要发生太大变化。
1.7 理解 Dropout
对下一层的神经单元来说,上一次神经单元就是这个神经单元的输入。
因为神经单元的输入随时有可能被删除,所以该神经单元不能依赖于某一个特定的单一特征,必须将权重在所有特征上分配,也就是传播权重。
dropout的效果就是:收缩权重的平方范数。即:压缩权重。正则化
,防止过拟合。
功能上类似L2正则化
,不同之处是应用的方式不同,dropout也会有相应变化。更适用于不同的输入范围。
keep_prob=1
,即没有dropout正则化;- 对输入层,即输入特征,一般不使用dropout,即
keep_prob=1
,即使使用,keep_prob
的值也接近1
; - 不同层的
keep_prob
可以不同:
- 对比其他层更容易发生过拟合的层,
keep_prob
可以设置的小一些; - 对不太可能出现过拟合或者程度小的层,
keep_prob
可以设置的大一些,甚至是1
;
- 对比其他层更容易发生过拟合的层,
- 将不同层的dropout的
keep_prob
设置成不一样的,这样做的缺点是:为了使用交叉验证,必须寻找更多的超参数。 - 另一种方案是:
仅对一部分层设置dropout,其他层不设置,且这些设置dropout的层用同一个keep_prob
值。
dropout的缺点:
代价函数J
没有办法去明确定义。因此,我们失去了调试工具,没有办法绘制梯度下降迭代的J
的下降曲线。
- 解决办法:
先将keep_prob=1
,即关闭dropout,待模型的代价函数的曲线下降后,再打开dropout。
1.8 其他正则化方法
- 数据增强
比如讲图像数据集的训练集数据图像都水平翻转一次。
因为数据有冗余,所以没有加入新的数据集那么好,但比起新加数据集,节省了很多成本和时间。
对图像:随机翻转、裁剪等手段增大数据集。
对字符:随意旋转、扭曲字符。 - 早停法
- 优点:耗费时间少
- 缺点:验证集J和训练集J的差距比较小的地方,偏差有可能很大。早停法一种方法必须兼顾两种问题,没有办法分开解决。
- 如果不用早停法解决问题,那么使用L2正则化,则神经网络的训练时间就长。同时需要花时间去选择正则化参数 λ λ 的值。
1.9 归一化输入
Normalizing inputs
训练集数据算出 μ μ 和 σ2 σ 2 ;
用 μ μ 和 σ2 σ 2 对整个数据集(训练集、验证集、测试集)进行归一化;
- 为什么要归一化?
如果不归一化,代价函数有可能就是一个非常细长狭窄的函数。归一化后的代价函数图像个更加对称。
对前者,梯度下降不得不用更小的学习速率。
对后者,梯度下降能更直接的找到最小值。可以使用较大的步长。
1.10 梯度消失与梯度爆炸
- 参考资料:
详解机器学习中的梯度消失、爆炸原因及其解决方法
梯度消失和梯度爆炸在本质上是一种情况。
梯度消失经常出现在深层网络和采用了不合理的损失函数之时,如sigmoid;
梯度爆炸经常出现在深层网络和权重初始化值太大之时。
- 深层网络角度:
BP过程中,由链式法则,对激活函数的导数大于1,不断的相乘,最终导致梯度爆炸;
对激活函数的导数小于1,不断的相乘,最终导致梯度消失;
梯度爆炸和消失的根本原因就是反向传播算法的先天不足导致的。 激活函数角度
sigmoid函数的导数最大不超过0.25,选择这样的激活函数很容易导致梯度消失;
tanh比sigmoid略佳,但导数仍然小于1;解决办法:
- 预训练+微调:
- 单独训练每一隐层,微调后,再BP,很少使用;
- 梯度裁剪:
- 主要针对梯度爆炸 ,设置梯度阈值,把超过阈值的梯度强制限制在范围内;
- 权重正则化:
- 可以减少梯度爆炸的概率;
- 激活函数:
- relu,在>0的部分导数恒为1;解决梯度消失和梯度爆炸的问题;
优点:
解决梯度爆炸、梯度消失;
计算方便、速度快;
加速网络的训练。
缺点:
输出不是以0为中心的;
负数部分导数恒为0,会导致一些神经元无法激活。 - leaky relu:
包含relu的优点;
解决relu的缺点; - elu:
比leaky relu计算耗时
- relu,在>0的部分导数恒为1;解决梯度消失和梯度爆炸的问题;
- BN:bacth normalization, 批规范化
- 残差结构
- LSTM
- 预训练+微调:
1.11 神经网络的权重初始化
权重初始化是对一开始的 w w 进行初始化的技巧,可以减缓梯度消失和梯度爆炸。属于加快训练速度的技巧之一。
思想是,神经元的输入越多,所有的随机化的
乘以 xi x i 的之和就越大。为了不变大,将 w w 的方差减小。即
的方差为 1/n 1 / n
权重初始化,即对随机生成的 w w 的方差进行初始化。
W_l=np.random.randn((l_n, L_n_1))*np.sqrt(1/n)
在实际操作过程中,针对不同的激活函数,
有不同的方差。
- relu:
2n[n−1] 2 n [ n − 1 ]
w[l]=np.random.randn(shape)∗np.sqrt(2n[n−1]) w [ l ] = n p . r a n d o m . r a n d n ( s h a p e ) ∗ n p . s q r t ( 2 n [ n − 1 ] )
- tanh:
1n[n−1] 1 n [ n − 1 ] 或者 2n[n−1]+ n[n] 2 n [ n − 1 ] + n [ n ]
w[l]=np.random.randn(s