Improving Deep Neural Networks: Hyperparameter Tuning, Regularization and Optimization

改善深层神经网络:超参数调试、正则化以及优化

Practical Aspects of Deep Learning

Train/Dev/Test sets

训练神经网络时,我们需要做很多决策,例如:神经网络分为多少层、每层含有多少个隐藏单元、学习速率是多少、各层采用哪些激活函数……

在创建新应用的过程中,我们不能从一开始就准确预测出这些信息和其它超参数,实际上,应用型机器学习是一个高度迭代的过程

image-20220325223659264

同时,创建高质量的训练数据集、验证集和测试集也有助于提高循环效率

需要注意的是,要确保验证集和测试集的数据来自于同一分布


Bias/Variance(偏差/方差)

image-20220327195357379

理解偏差与方差的重要依据是,训练集误差和验证集误差

Train set error 1% 15% 15%
Dev set error 11% 16% 30%
high variance high bias high variance and high bias

最优误差,一般也被称为标准误差,其值接近于0%

通过查看训练集误差,可以判断数据的拟合情况可以判断是否有偏差(bias)问题,从而查看错误率的高低,当完成训练集训练,开始验证集验证时,可以来判断方差是否过高


Basic “recipe” for machine learning

训练神经网络时用到的基本方法:

当初始模型训练完成后,首先判断算法的偏差高不高,如果偏差较高,就去评估训练集/测试集的性能,如果偏差确实比较高,甚至无法拟合训练集,就去选择一个新网络或是用更长的时间来训练网络

当偏差降低到可以接受的数值,先通过检查验证集性能检查一下方差是否无误,如果方差高,最好的解决办法就是采用更多数据,但当我们无法获得更多数据时,可以通过尝试正则化来减少过拟合

不断尝试,直到找到一个低偏差、低方差的框架

正则化是一种非常有效的减少方差的手段,正则化时会出现偏差方差权衡问题,偏差可能略有增加,如果网络足够大,增幅通常不会太高


Regularization(正则化)

当怀疑神经网络过度拟合了数据,即存在高偏差问题,一种方法是准备更多的数据,另一种方法就是正则化

对于成本函数,$L2$正则化之后是这样的

$J(w,b)\,=\,\frac{1}{m}*\sum_{i=1}^ml(\widehat{y}^{(i)},y^{[i]})\,+\,\frac{\lambda}{2m}||w||^2_2$ $||w||^2_2\,=\,\sum^{nx}_{j=1}w^2_j\,=\,w^Tw$($L2$范数)

Q:为什么只需要正则化$w$,而不需要正则化$b$呢?

A:是可以加上的,不过因为$w$通常是一个高维参数矢量,已经可以表达高偏差问题,$w$有很多参数,我们不可 能拟合所有参数,而$b$只是单个数字,所以$w$几乎涵盖所有参数,而不是$b$,因为$b$只是众多参数中的一个

$L1$正则化则是:

$\frac{\lambda}{2m}\sum^{nx}_{i=1}||w||\,=\,\frac{\lambda}{2m}||w|_1$

$\lambda$是正则化参数,python中要用$lambd$来代替$lambda$,防止与保留字冲突

如何在神经网络中实现正则化?

神经网络含有一个成本函数

$J(w^{[1]},\,b^{[1]},\,...\,,\,w^{[l]},\,b^{[l]})\,=\,\frac{1}{m}*\sum_{i=1}^ml(\widehat{y}^{(i)},y^{[i]})\,+\,\frac{\lambda}{2m}||w||^2_2$ $||w||^2_2\,=\,\sum^{n^{[l - 1]}}_{i=1}\sum^{n^{[l]}}_{j=1}(w^{[l]}_j)^2$

上述表达式是因为$w$是形状为$(n^{[l-1]},n^{[l]})$的矩阵,该矩阵范数被称为”Frobenius norm”(弗洛贝尼乌斯范数),它表示一个矩阵中所有元素的平方和

还如何使用该范数实现梯度下降呢?

用backprop计算出$dw$的值,backprop会给出j对$w^{[l]}$的偏导数,将$w^{[l]}$替换为$w^{[l]}\,-\,\alpha w^{[l]}$,就是之前我们额外增加的正则化项

再对上式做出如下改变

$dw^{[l]}\,=\,(backprop)\,+\,\frac{\lambda}{m}w^{[l]}$

替换后,$w^{[l]}$的定义就更新为了:

$w^{[l]}\,=\,w^{[l]}\,-\,\alpha\,[(backprop)\,+\,\frac{\lambda}{m}w^{[l]}]\,=\,w^{[l]}\,-\,\frac{\alpha\lambda}{m}w^{[l]}\,-\,\alpha(backprop)$

在其中,矩阵$W$减去$\frac{\alpha\lambda}{m}$倍的它,即令矩阵$W$乘以系数$(1\,-\,\frac{\alpha\lambda}{m})$,该系数小于1,因此$L2$正则化也被称为“权重衰减”


Why regularization reduces overfitting (为什么正则化可以减少方差问题)

当$\lambda$被设置的足够大,权重矩阵$W$被设置为接近于0的值,直观理解就是把多隐藏单元的权重设为0,于是基本消除了这些隐藏单元的许多影响


Dropout regularization(随机失活正则)

image-20220327214208180

假设在训练上图所示的神经网络,它存在过拟合,这即是dropout要处理的

dropout会遍历网络的每一层,并设置消除神经网络中结点的概率

选择一些节点,删除一些节点的连线,得到一个更小的网络,然后用backprop方法进行训练

image-20220327214557566

那么,该如何实施dropout呢

方法有几种,最常用的是inverted dropout(反向随机失活),以下为例子

1
2
3
4
5
6
7
8
9
10
11
# 这是一个随机矩阵
# 这里的keep.prop是一个常数,表示保留某个隐藏单元的概率
# 假设让krrp.prop为0.8,则意味着消除任意一个隐藏单元的概率为0.2
d3 = np.random.rand(a3.shape[0], a3.shape[3]) < keep.prop

# 从三层中获取激活函数
# 其作用即时过滤d3中所有等于0的元素
a3 = np.multply(a3, d3)

# 向外拓展a3
a3 /= keep.prop

需要注意的是,我们在测试阶段不使用dropout函数,因为在测试阶段进行预测时,我们不期望输出结果是随机的如果测试阶段应用dropout函数,预测会受到干扰,即确保在测试阶段不执行dropout来调整数值范围,激活函数的预期结果也不会发生变化。


Understanding dropout

image-20220327222129134

如果担心某些层比其他层更容易发生过拟合,可以把某些层的keep_prob值设置的比其他层更低,确定是为了使用交叉验证,需要搜集更多的超级参数;另一种方案是在一些层上应用dropout,而一些层则不用,应用dropout的层只含有一个超级参数,即keep_prob

但请牢记,dropout是一种正则化方法,它有助于预防过拟合,因此,除非算法过拟合,一般是不会用到的


Other regularization methods

除了上述的两种方法,还有几种方法可以减少神经网络中的过拟合

一 数据扩增

当数据不足时,对于图片,可以翻转/随意裁剪来扩大数据集,额外生成假训练数据;对于文字,可以随意旋转/扭曲数字来增加数据

因此,数据扩增可以作为正则化方法使用,实际功能也与其类似

image-20220327223830175

二 early stopping

运行梯度下降时,我们可以绘制训练误差,或只绘制代价函数$J$的优化过程,在训练集上用0-1记录分类误差次数呈下降趋势

除此之外,我们还可以绘制验证集误差

image-20220327223936537

可以发现,验证集误差通常先呈下降趋势,在某个节点处重新回升

当还未在神经网络上运行太多迭代过程时,参数$w$接近于0,因为在随机初始化$w$时,它的值可能是较小的随机值,而在迭代和训练过程中,$w$的值会变得越来越大,early stopping即是,在中间点停止迭代过程,我们得到一个$w$值中等大小的弗洛贝尼乌斯范数

其优点是,只运行一次坡度下降,找出$w$的值,而无需尝试$L2$正则化超级参数$\lambda$的很多值


Normalizing inputs(归一化输入)

当训练神经网络时,其中一个加速训练的方法就是归一化输入

归一化输入需要两个步骤:

第一是零均值化

$\mu\,=\,\frac{1}{m}\sum^m_{i=1}x^{[i]}$;$x\,:=\,x\,-\,\mu$

上面式子的意思是:移动训练集,直到它完成零均值化

如下图

image-20220327205611102image-20220327205653755

第二步是归一化方差

上图中的特征$X1$方差比特征$X2$的方差要大得多

我们要做的:

$\sigma^2\,=\,\frac{1}{m}\sum^m_{i=1}x^{[i]}**2$

**是节点$y$的平方,$\sigma^2$是一个向量,它的每个特征都有方差

$x \,/=\sigma^2$

image-20220328113020031

为什么要归一化输入?

对于代价函数,如果我们使用非归一化输入,函数就会如下图一般,呈细长狭窄状

image-20220328113429162

而归一化之后

image-20220328113718942image-20220328113750855

不归一化时,由于在空间上分布也不是平滑的,使得梯度下降法需要小步长、多次迭代才可能实现目的,而归一化后,梯度下降法能够更直接的使用较大步长查找最小值,这使得代价函数优化起来更简单也更快速


Vanishing/exploding gradients(梯度 消失/爆炸 )

当训练一个极深的神经网络时

image-20220328120206908

如果权重$w$只比1略大一点,或者说只比单位矩阵大一点,神经网络的激活函数将爆炸式增长

如果权重$w$只比1略小一点,在神经网络中,激活函数将以指数级递减

一个防止办法就是 — 权重初始化


Weight initialization for deep networks(神经网络的权重初始化)

image-20220328134918716

对于这样一个简易的神经元

$Z\,=\,w_1x_1\,+w_2x_2\,+\,…\,+\,w_nx_n$(暂且省略$b$)

我们可以发现,$n$越大,我们希望的$w$越小

最合理的方法就是,设置$w_i\,=\,\frac{1}{n}$ ($n$表示神经元的输入特征数量)

实际上要做的就是,设置某层的权重矩阵$w^{[l]}\,=\,np.random.randn(shape)\,*\,np.sqrt(\frac{1}{n^{[l-1]}})$

对于tanh函数,可以使用下图第一个公式

image-20220328140054458


Numerical approximation of gradients(梯度的数值逼近)

在执行backprop时,有一个步骤叫做梯度检验,它的作用是确保backprop正确实施,为了逐渐实现梯度检验,首先要了解如何对梯度做数值逼近

image-20220328141035130

image-20220328141256250

在梯度检验时,我们使用双边误差,即$\frac{f(\theta+\epsilon)-f(\theta-\epsilon)}{2\epsilon}$,而不使用单边公差,因为它不够准确


Gradient Checking

假设网络中有以下参数image-20220328141856456,为了执行梯度检验,首先要做的就是把所有参数转换成一个巨大的向量数据$\theta$

即$J(w^{[1]},\,b^{[1]},\,…\,,\,w^{[l]},\,b^{[l]})\,=\,J(\theta)$

接着,得到与$w$和$b$顺序相同的数据image-20220328142235180,用他们来初始化巨大向量$d\theta$,它与$\theta$具有相同维度

下面的问题是$d\theta$与代价函数$J$的梯度或坡度有何关系,下面即是检验的过程

首先要明确$J$是超级参数$\theta$的一个函数

为了实施梯度检验,需要做的就是循环执行,从而对每个i,也就是对每个$\theta$组成元素,计算$d\theta \,approx[i]$的值

image-20220328143305406

由上节课的的知识我们知道

上述式子的值

$\approx\,d\theta^{[i]}\,=\,\frac{\delta J}{\delta \theta}$

$d\theta^{[i]}$是代价函数的偏导数

经过对所有值进行此运算,最后得到两个向量,其中之一即使$d\theta$的逼近值$d\theta approx$,它与$d\theta$具有相同维度,我们要做的就是验证这些向量是否彼此接近

如何定义两个向量互相接近?

计算两个向量距离$d\theta approx-d\theta$的欧几里得范数$||d\theta approx-d\theta||_2$(误差平方之和),然后求平方根,得到欧式距离,之后用向量长度做归一化,结果为

$\frac{||d\theta approx-d\theta||_2}{||d\theta approx||_2 + ||d\theta||_2}$

(分母只是用来预防这些向量太小或太大,分母使得方程式变为比率)

如果得到的$\varepsilon$是$10^{-7}$,或更小一点,这意味着导数逼近很可能是正确的,

但如果其范围在$10^{-5}$范围内,需要注意一下,确保一下没有一项误差过大,如果有,那么这里可能存在bug

值为$10^{-3}$或比它更大,应该非常担心是否存在bug


Gradient Checking implementation notes

  • 不要在训练中使用梯度检验,它只用于调试

  • 如果算法的梯度检验失败,要检查所有项,试着找出bug

  • 在实施梯度检验时,,如果使用正则化,请注意正则项,当调试时,将dropout关上再进行调试

Optimization Algorithms(优化算法)

Mini-batch gradient descent(Mini-batch梯度下降法)

向量化可以有效的对m个例子进行计算,允许在处理整个训练集同时,无需明确某个明确的公式,因此我们要把数据放到巨大的矩阵$X$中去

image-20220328161513667

尽管向量化可以使我们较为轻松的处理大量数据的样本,但如果m很大的话,处理数度依旧会变缓慢

在对整个训练集执行梯度下降法时,必须处理整个训练集,然后才能执行一步梯度下降法,然后需要重新处理数据,才能进行下一步梯度下降法

如果在处理完所有数据之前,先让梯度下降法处理一部分,相信算法速度会更快

将训练集分割为小一点的子训练集,这些子集就被取名为”Mini-batch”,显示格式即为$X^$与$Y^$

image-20220328162330843

(这里回顾一下括号,小括号上标指第几个元素,中括号指神经网络的层数)

与原本同时处理整个batch训练集样本不同,Mini-batch梯度下降每次同时处理的是单个的mini-batch $X^$与$Y^$,而不是同时处理全部的$X$和$Y$训练集

通过上图可以发现,实现的基本步骤与与原本执行梯度下降法别无二致,区别就在于对象变为了 $X^$与$Y^$,


Understanding mini-batch gradient descent

image-20220328193836899

当m=1时,就变为了“随机梯度下降法”,它的每一项都是一个mini-batch。

而“随机梯度下降法”在寻找最小值时,大部分时候都是朝着全局最小值前进,但有些时候也会因为单个样本方向不对从而远离最小值,因此随机梯度下降法是有很多噪声的,平均来看,它最终会接近最小值,不过有时候也会出现方向错误。

因为随机梯度下降法永远不会收敛,而是会一直在在最小值附近活动,但并不会达到最小值并停留于此

image-20220328194715017

随机梯度下降法的优点是,在处理单个数据是表现优异;但其缺点是,会失去所有向量化带来的加速,因为一次性只处理了一个训练样本,这样效率过于低下

因此,选择不大不小的mini-batch尺寸,会发现两个好处,一方面,得到了大量向量化,加快了多次处理样本速度;另一方面,无需等待整个训练集被·处理完 ,就可以进行后续工作


Exponentially weighted averages(指数加权平均)

再去了解一些其他算法之前,首先要了解指数加权平均

以温度为例

image-20220328200940903

如果我们要计算趋势,也就是温度的局部平均值/移动平均值,要做的是

$v_0\,=\,0$;

$v_1\,=\,0.9*v_0\,+\,0.1\theta_1$;

$v_2\,=\,0.9*v_1\,+\,0.1\theta_2$.

…..;

$vt\,=\,0.9*v{t-1}\,+\,0.1\theta_t$

如此计算,再用红线作图,得到如下结果

image-20220328201420582

我们得到了移动平均值,每日温度的指数加权平均值

改写一下式子

$vt\,=\,\beta*v{t-1}\,+\,(1-\beta)\theta_t$

同时在计算时,可将$v_t$视为大概是$\frac{1}{(1-\beta)}$的每日温度,如果$\beta$为0.9,就是上面的红线

我们取一个稍大一点的值 — 0.98,这即是平均了一下过去50天的温度,作图后得到以下绿线

image-20220328202031854

当我们取高值的时候,会发现曲线平缓了一些,那是因为多平均了几天的温度,因此这个曲线波动更小、更加平坦,缺点是曲线进一步右移,平均了更多数据,指数加权公式,在温度变化时,适应地更缓慢一些

我们再取一个较小的值 — 0.5,由于数据少,波动也更为明显,如下图黄线所示

image-20220328202637480

因此,我们可以通过调整指数加权平均数来寻找适合的“中间的某个值”,就像上图的红线一样


Understanding exponentially weighted averages

沿用上一题得到的公式

image-20220328203204105

可以知道$V_{100}$即是选取的每日温度与指数衰减函数相乘,然后求和


Bais correction in exponentially weighted averages

Bais correction — 偏差修正

image-20220329214802325


Gradient descent with momentum(动量梯度下降法)

基本思想:计算梯度的指数加权平均数,并利用该梯度更新权重

image-20220329215612483

上图是batch梯度下降法的实例,可以看出,在寻找最小梯度时经历了不少上下波动,而这种频繁的上下波动也减缓了梯度下降法的速度,让我们无法使用较大的学习率,因为如果使用大学习率,结果可能会摆动偏离函数的范围

我们用另一种角度观察,在纵轴上,我们希望减慢学习;而在横轴上,我们希望加快学习

因此,在动量梯度下降法中,在第t次迭代的过程中,计算微分$dw、db$

image-20220329224851511

使用上述公式更新$w$与$b$,来减缓梯度下降的幅度


RMSprop

RMSprop算法,全称为root mean square prop算法,它也起到加速梯度下降的作用

image-20220330191918287


Adam optimization algorithm

image-20220330192646349


Learning rate decay(学习率衰减)

加快学习算法的一个办法就是,随时间慢慢减小学习率,也就是我们所说的“学习率衰减”

为什么要计算学习率衰减

假设使用mini-batch梯度下降法,mini-batch数量不大,大概64或者128个样本,如我们在前面分析的一样,它将会在迭代过程中出现“噪音”,下降朝向最小值,但不会精确收敛

但如果我们减小学习率的话,在初期,学习率较大,学习相对较快,但随着$\alpha$变小,“步伐”也会慢慢变小,最后,查找的值会在最小值附近的一小块区域里摆动,而不会在最小值附近大幅度摆动

进行学习率衰减的公式如下

image-20220330194152594

或者是指数衰减

image-20220330194316709


The problem of local optima(局部最优问题)

曾经,局部最优是一个很令人困扰的问题,

image-20220330194629145

就像上图一样,似乎每处都分布着局部最优,梯度下降,或者某个算法可能困在某个局部最优解中,而不会抵达全局最优

但这些理解并不正确

image-20220330195010797

事实上,当我们创建一个神经网络,梯度为0的点往往不是这个图中的局部最优点,实际上,成本函数的零梯度点往往是鞍点

实际上,我们对低纬度空间的大部分直觉,往往并不能应用到高维度空间中

那么,如果局部最优并非问题(在训练存在大量参数的大规模网络时不太可能困在极差的局部最优中),问题是什么?

我们可以从上图发现,平稳段会减缓学习(平稳段是一块区域,其中导数长时间接近于0),它使得学习十分缓慢,这即是我们面对的问题



Hyperparameter Tuning, Batch Normalization and Programming Frameworks

超参数调试、Batch正则化和程序框架

Tuning process(调试处理)

参数数量是训练网络时面临的大问题,结果证实,一些超参数比其他的更为重要,例如学习率$\alpha$、momentum、mini-batch的大小以及隐藏单元

在深度学习中,我们验证(两个参数)的方法是,在空间中随意取一定数量的点,分别验证参数

在找到的效果优秀的点周围再划分区域进行验证,即从粗糙到精细


Using an appropriate scale to pick hyperparameters(为超参数选择合适的范围)

在上一例中,我们知道,随机取值会提高神经网络的效率,但是,随机取值并不是在有效值范围内的随机均匀取值,而是选择合适的参数,用于探究超参数

对于取点,加入我们是在0.0001至1的数轴上取点,那么0.1至1这个范围大概率会占用90%的搜索资源,而在0.0001至0.1之间,只有10%的搜索资源

因此,使用对数标尺搜索超参数的方式会更加合理

image-20220401133756164


Hyperparameters Tuning in Practice: Pandas vs. Caviar

image-20220401143603479

Panda是计算一个模型,然后一直去维护

Caviar是计算多个模型,选择最优

两种方法的选择是计算资源决定的


Normalizing Activations in a Network(正则化/归一化函数)

image-20220401144743028

在神经网络,已知一些中间值,假设有隐藏单元值,从$z^{[1]}$到$z^{[m]}$(以下表示为$z^{[l][i]}$)

如下计算平均值

image-20220401145316789


Fitting Batch Norm into a Neural Network

image-20220401150746337

在实践中,Batch归一化通常与训练集的mini-batch一起使用,下图是过程演示

image-20220401151037529

提示:

因为Batch归一化0超过了此层$z^{[l]}$的均值,$b^{[l]}$这个参数没有意义,必须将其去掉,因此被影响转移或偏置条件的控制参数$\beta^{[l]}$所替代

image-20220401151458510

image-20220401151945595


Why does Batch Norm work?

Batch归一化有效的第一个原因是,它对输入值以及隐藏单元的值起到了类似于归一化输入特征x,使其均值为0,方差为1,并且加速学习的作用

第二个原因是,它可以使权重,比网络更滞后或更深层

image-20220401152658629

对于上图,我们通过左方的黑猫训练出的神经网络似乎并不怎么适合右面的有色猫,因此我们通过covariate shift — 已经训练好了x到y的映射,如果x的分布改变了,那么可能需要重新训练学习算法

covariate shift 的问题应该怎样应用于神经网络呢?

image-20220401153106740

对于这样一个神经网络,我们假设从第三个隐藏层开始观察,将前面盖住

image-20220401153221002

第三隐藏层的工作是,接受前方传来的参数,并将参数通过一系列变换得到最终结果,这是我们发现,由于前方存在着w与b,实际上传来的参数值也是不断变化的,这就产生了covariate shift问题

Batch归一化做的,是它减少了,这些隐藏值分布变化的数量,绘制这些隐藏单元值的分布(以重整值z为例)

image-20220401153650429

即$z^{[2]}$、$z^{[1]}$的值可以改变,batch归一化可确保,无论其怎样变化,它们的均值与方差保持不变,因此即使它们的值发生变化,至少它们的均值与方差也会是0、1,

总的来说,batch归一化减少了输入值改变的问题,使这些值变得更加稳定,神经网络之后的层就会有更加坚实的基础,略微减少了层与层之间参数的联系,增加了单个层的独立性,有助于加速整个网络的学习

Batch还有另一个作用,它有着轻微的正则化效果,即给隐藏层添加噪音,迫使后方元素不过分依赖任何一个隐藏单元(类似于dropout),不过因为添加的噪音非常小,因此不具备巨大的正则化效果

image-20220401154328555


Batch Norm at Test Time

在训练时,$\mu$和$\sigma$是在整个mini-batch上计算出来的,但在测试时,可能需要逐一处理样本,方法是根据训练集估算$\mu$和$\sigma$,通常我们使用指数加权平均,来追踪训练过程中看到的$\mu$和$\sigma$的值,还可以粗略估算$\mu$和$\sigma$,然后用测试中$\mu$和$\sigma^{2}$的值对所需的隐藏单元$z$值的调整

image-20220401183347797


Softmax回归

截止到本节之前,我们所用的例子都属于二分分类(只有两种可能标记:0或1),softmax回归允许在试图识别某一分类时做出预测,或者说是多种分类中的一个,而不只是识别两个分类

以下图为例

image-20220401183715769

使用C来表示输入会被分入的类别的总个数(本例中为4)

针对上题,我们建立如下神经网络

image-20220401183958973

最后一层分别代表了返回四种类别的概率,它们值的和为1,

对于最后一层(我们看作L),它的输入与往常一样,接下来将应用softmax激活函数,它的作用是:

首先计算一个临时变量$t\,=\,e^{(z^{[l]})}$

然后$a^{[l]}\,=\,\frac{e^{(z^{[l]})}}{\sum^4{j=1}t_i}$,$a^{[l]_i\,=\,\frac{t_i}{\sum^4{j=1}t_i}}$

下图包含实例

image-20220401185851854

使用情况展示:

image-20220401190733841