If you can’t explain it simply, you don’t understand it well enough ——Albert Einstein
标题:Improving Deep Neural Networks: Hyperparameter tuning, Regularization and Optimization
第一周
标题:Practical aspects of Deep Learning (即一些实践上的知识)
1.1 Train / Dev / Test sets
在训练一个能解决实际问题的 NN 前,需要做一些决策:NN 的层数、hidden layer 中 unit 的个数等等。但这些决策一般无法在一开始就做对,需要不断地迭代,在一次次迭代中调整这些决策的内容,以来达到更好的效果。而创建高质量的训练集、验证集以及测试集可以提高迭代的效率。
为了训练和评估神经网络,数据集可以划分为训练集、交叉验证集 hold-out cross validation set
(或称验证集 development set
)和测试集。在数据量比较小的时代,划分比例一般为 6:2:2 。但在如今的大数据时代,却不同。例如,有一个数据集,数据集中有一百万个样本,那么分配给验证集的样本实际上只要一万个就足够了,同样测试集中分配一万个数据量也足矣。
划分数据集是门学问,具体如何划分,后面会学到。
要保证测试集和验证集中的样本来自同一分布。什么叫来自不同分布?比如,对于数字识别,测试集中数据来自于一个灰度数字图片数据集,而验证集中的数据却来自于一个彩色数字图片数据集。
1.2 Bias / Variance
如何判断假设函数的偏差/方差是否过高?
下图中,欠拟合对应的是高偏差的情况,过拟合对应的是高方差的情况。
在特征数比较少时,可以通过画图的方式来判断假设函数的偏差/方差是否过高。在特征数较多时,画图的方式不再管用,需要通过一些指标来判断。这些指标是理解偏差和方差的关键数据,分别是训练集误差 Train set error
和验证集误差 Dev set error
:
训练集误差 | 1% | 15% | 15% | 0.5% |
验证集误差 | 11% | 16% | 30% | 1% |
高方差 | 高偏差 | 高方差 & 高偏差 | 低偏差 & 低方差 |
高偏差和高方差的情况举例:局部过拟合 & 局部欠拟合
偏差/方差过高时,该怎么办?
正则化
正则化可以缓解过拟合问题,也就是可以降低方差。使用正则化,通过在 cost function 中加入一个正则项,来惩罚模型的复杂度。
为什么正则化能缓解过拟合?
使用
tanh
\tanh
tanh 作为激活函数的神经网络中,当正则化参数
λ
\lambda
λ 变大时,
W
[
l
]
W^{[l]}
W[l] 值就会下降,
Z
[
l
]
Z^{[l]}
Z[l] 的值会因此变小,当
Z
[
l
]
Z^{[l]}
Z[l] 的值比较小时,处在
tanh
\tanh
tanh 图像的中间部分,这个中间部分接近于线性函数,通过这一点可以缓解过拟合。
下面罗列了一些正则化方法:
① L2 正则化
1.1 logistic regression
logistic 回归的代价函数加入正则化项后: J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m ∣ ∣ w ∣ ∣ 2 2 J(w,b)=\frac{1}{m}\sum^m_{i=1}L(\hat{y}^{(i)},y^{(i)})+\frac{\lambda}{2m}||w||^2_2 J(w,b)=m1∑i=1mL(y^(i),y(i))+2mλ∣∣w∣∣22
- L2 正则化: ∣ ∣ w ∣ ∣ 2 2 = ∑ j = 1 n x w j 2 = w T w ||w||^2_2=\sum^{n_x}_{j=1}w_j^2=w^Tw ∣∣w∣∣22=∑j=1nxwj2=wTw
- L1 正则化: ∣ ∣ w ∣ ∣ 1 = ∑ j = 1 n x ∣ w j ∣ ||w||_1=\sum^{n_x}_{j=1}|w_j| ∣∣w∣∣1=∑j=1nx∣wj∣
λ \lambda λ 为正则化参数
1.2 Neural Network
神经网络的代价函数加入正则化项后:
J ( w [ 1 ] , b [ 1 ] , … , w [ l ] , b [ l ] ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m ∑ l = 1 L ∣ ∣ w [ l ] ∣ ∣ F 2 J(w^{[1]},b^{[1]},\dots,w^{[l]},b^{[l]})=\frac{1}{m}\sum^m_{i=1}L(\hat y^{(i)},y^{(i)})+\frac{\lambda}{2m}\sum^L_{l=1}||w^{[l]}||^2_F J(w[1],b[1],…,w[l],b[l])=m1∑i=1mL(y^(i),y(i))+2mλ∑l=1L∣∣w[l]∣∣F2
其中 ∣ ∣ w [ l ] ∣ ∣ F 2 = ∑ i = 1 n [ l − 1 ] ∑ j = 1 n [ l ] ( w i j [ j ] ) 2 ||w^{[l]}||^2_F=\sum^{n^{[l-1]}}_{i=1}\sum^{n^{[l]}}_{j=1}(w^{[j]}_{ij})^2 ∣∣w[l]∣∣F2=∑i=1n[l−1]∑j=1n[l](wij[j])2,其中 w w w 的大小为 n [ j − 1 ] × n [ l ] n^{[j-1]} \times n^{[l]} n[j−1]×n[l]。该矩阵范数被称为“Frobenius norm”
② Dropout 正则化
Dropout 随机失活
该方法的主要思想是,遍历神经网络的各层,随机删除每层的一些神经元,最后可以得到一个相对更简单的神经网络。神经元被删除或者被保留的概率可以自行设置,下图中,这个概率是 0.5 。
实现 Dropout
实现 dropout 的方式有很多种,其中最常用的一种方式是 inverted dropout 反向随机失活
,实现代码如下:
keep_prob = 0.8 # 神经元被保留下来的概率
d3 = np.random.rand(a3.shape[0], a3.shape[1]) < keep_prob
a3 = np.multiply(a3, d3)
a3 /= keep_prob
代码解释:
这里以上图
a
[
3
]
a^{[3]}
a[3] (第三层神经元)为例。
d3
\text{d3}
d3 是第三层的 dropout vector 。np.random.rand(a3.shape[0], a3.shape[1])
会生成一个随机矩阵,矩阵中元素的值都在 0 到 1 之间,矩阵的规格与
a
[
3
]
a^{[3]}
a[3] 一样。
np.random.rand(a3.shape[0], a3.shape[1]) < keep_prob
的目的是让新生成的随机矩阵中小于 keep_prob
的值都变为 True
,大于的则变为 False
,表示是否保留网络中对应位置的神经元。
np.multiply(a3, d3)
,使用 multiply()
方法会先转化 d3
中的布尔值,将 True
变为 1
,False
变为 0
。然后将 a3
中的元素与 d3
中的元素相乘,这样子 0
对应位置的神经元就会被“消去”。
a3 /= keep_prob
,代码运行到这,由于 20% 的神经元被消去了,而之后还要计算:
z
[
4
]
=
w
[
4
]
a
[
3
]
+
b
[
4
]
z^{[4]}=w^{[4]}a^{[3]}+b^{[4]}
z[4]=w[4]a[3]+b[4],为了不影响
z
[
4
]
z^{[4]}
z[4] 的期望值,需要在
w
[
4
]
a
[
3
]
w^{[4]}a^{[3]}
w[4]a[3] 这一部分除以 keep_prob
。
通过
a3 /= keep_prob
,可保证无论keep_prob
设置为多少,都不会对 z [ 4 ] z{[4]} z[4] 的期望值产生影响。
注意:在测试阶段不要用 dropout,因为那样会使得预测结果变得随机。
正则化为什么能够缓解过拟合?
正则化的效果就好似将复杂的函数图像简化为一个相对简单的函数图像,以达到缓解过拟合的目的。
其他正则化方法
除去 L2 正则化和 dropout 以外,还有一些缓解过拟合的方法:
① Data augmentation
对于一个图像识别问题,可以通过将原来数据集中的图像进行水平翻转、旋转、放大来生成一些“新”的数据,通过这种方式来收集更多的数据来缓解过拟合问题。
这些额外的假的数据无法包含像全新数据那么多的信息,但我们这么做基本没有花费,代价几乎为零,除了一些对抗性代价。以这种方式扩增算法数据,进而正则化数据集,减少过拟合比较廉价。
② early stopping
该方法的主要思想是提早停止训练神经网络。在训练神经网络的过程中,我们的目标是使代价函数的值越小越好,但随着代价函数的值越来越小,过拟合的问题可能会出现,也就是像下图这样:
而 early stopping 的方法就是在验证集的误差最小的时候停止训练神经网络。
神经网络的训练过程分若干个步骤,其中一步是优化代价函数 J,让该函数的值变得越小越好,在最优化这个函数以后,可能会遇到过拟合问题,第二步就是缓解过拟合问题。对于这两步,也就是两个问题,一般来说将两个问题分开来解决会更好一些,但 early stopping 则是在用一个方法同时解决这两个问题,为了避免过拟合而提前停止优化代价函数,导致训练集的训练误差可能还不够小,这是 early stopping 的缺点。
吴恩达老师解决过拟合问题时更倾向于使用 L2 正则化(为什么?),有时会用 early stopping 。
归一化
现在有下图中的数据集,数据集有两个特征 x 1 x_1 x1 与 x 2 x_2 x2,我们需要对数据集进行一些调整以使得学习算法运行地更快:
首先进行零均值化 zero to the mean
,使用下列算式:
-
μ = 1 m ∑ i = 1 m x ( i ) \mu=\frac{1}{m}\sum^m_{i=1}x^{(i)} μ=m1∑i=1mx(i)
-
x : = x − μ x:=x-\mu x:=x−μ
在图中可以发现,特征 x 1 x_1 x1 的方差要大于 x 2 x_2 x2 的方差,我们希望使两个特征的方差相似,即使得点的分布趋于圆形或正方形这类图形,对此,使用下列算式可以达到所要的效果:
- σ 2 = 1 m ∑ i = 1 m ( x ( i ) ) 2 \sigma^2=\frac{1}{m}\sum^m_{i=1}(x^{(i)})^2 σ2=m1∑i=1m(x(i))2
- x = x / σ 2 x = x\, /\, \sigma^2 x=x/σ2
数据点分布就变为:
为什么要使用归一化处理?
在归一化前,代价函数
J
(
w
,
b
)
=
1
m
∑
i
=
1
m
L
(
y
^
(
i
)
,
y
(
i
)
)
J(w,b)=\frac{1}{m}\sum^m_{i=1}L(\hat{y}^{(i)},y^{(i)})
J(w,b)=m1∑i=1mL(y^(i),y(i)) 的图形如下图左边所示,这时候如果学习率设置的比较小,则在梯度下降的过程中,若在下图蓝笔所标的那个点开始梯度下降,可能要迭代非常多次才能最终到达全局最优解所在的位置。而归一化后,无论在哪个地方开始,都可以用相对较少的迭代次数来达到全局最优解所在的位置。
参考:
吴恩达 深度学习课程
吴恩达Coursera深度学习课程 DeepLearning.ai 提炼笔记(2-1)-- 深度学习的实践方面