吴恩达深度学习笔记(二)02.29

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

深度学习的实用层面

训练、验证、测试集
应用型机器学习是一个高度迭代的过程,训练神经网络时,我们需要做出很多决策

# l a y e r s \#layers #layers
# h i d d e n    u n i t s    \#hidden\,\,units\,\, #hiddenunits
l e a r n i n g    r a t e s    learning\,\,rates\,\, learningrates
a c t i v a t i o n    f u n c t i o n s ⋯ activation\,\,functions\cdots activationfunctions

现如今,深度学习已经在自然语言处理,计算机视觉,语音识别以及结构化数据应用等众多领域取得巨大成功。结构化数据无所不包,从广告到网络搜索。其中网络搜索不仅包括网络搜索引擎,还包括购物网站,从所有根据搜索栏词条传输结果的网站。再到计算机安全,物流,比如判断司机去哪接送货,范围之广,不胜枚举。

应用深度学习是一个典型的迭代过程,需要多次循环往复,才能为应用程序找到一个称心的神经网络,因此循环该过程的效率是决定项目进展速度的一个关键因素,而创建高质量的训练数据集,验证集和测试集也有助于提高循环效率。
\text{图一}
验证集的目的是验证不同的算法,检验哪种算法更有效,测试集的主要目的是正确评估分类器的性能。

在机器学习发展的小数据量时代,常见做法是将所有数据按照60%训练,20%验证和20%测试集来划分。

但是在大数据时代,比如我们有100万条数据,那么取1万条数据作验证集便足以找出其中表现最好的1~2种算法。同样地,只需10000条数据作测试集,便足以评估单个分类器,并且准确评估该分类器的性能。即:训练集占98%,验证集和测试集各占1%。对于数据量过百万的应用,训练集可以占到99.5%,验证和测试集各占0.25%,或者验证集占0.4%,测试集占0.1%.

现代深度学习的另一个趋势是越来越多的人在训练和测试集分布不匹配的情况下进行训练,假设你要构建一个用户可以上传大量图片的应用程序,目的是找出并呈现所有猫咪图片。

训练集可能是从网上下载的猫咪图片,而验证集和测试集是用户在这个应用上上传的猫的图片。

针对这种情况,要确保验证集和测试集的数据来自同一分布。因为要用验证集来评估不同的模型,尽可能地优化性能。如果验证集和测试集来自同一个分布就会很好。

最后一点,就算没有测试集也不要紧,测试集的目的是对最终所选定的神经网络系统做出无偏估计,如果不需要无偏估计,也可以不设置测试集。

所以如果只有验证集,没有测试集,我们要做的就是,在训练集上训练,尝试不同的模型框架,在验证集上评估这些模型,然后迭代并选出适用的模型。

偏差、方差
在这里插入图片描述
上面第一个图高偏差,欠拟合;第三个图高方差,过拟合。

例子 猫咪图片分类

Train set error1%15%15%0.5%
Dev set error11%16%30%1%
high variancehigh biashigh bias & high variancelow bias & low variance

这些分析都是基于假设预测的,假设人眼辨别的错误率接近0%,一般来说,最优误差也被称为贝叶斯误差,所以,最优误差接近0%. 如果最优误差或贝叶斯误差非常高,比如15%. 我们再看看这个分类器(训练误差15%,验证误差15%),15%的错误率对训练集来说也是非常合理的,偏差不高,方差也非常低。

以上分析的前提都是假设贝叶斯误差很小,训练集和验证集数据来自相同分布。

高偏差和高方差的情况

这条曲线中间部分灵活性非常高,却过度拟合了这两个错误样本,产生高方差。这类分类器偏差很高,因为它几乎是线性的。

机器学习基础
在这里插入图片描述
如果偏差的确很高,甚至无法拟合训练集,那么要做的就是选择一个新的网络,比如含有更多隐藏层或者隐藏单元的网络,或者花费更多时间来训练网络,或者尝试更先进的优化算法,找到一个更合适解决此问题的新的神经网络架构。

如果方差高,最好的解决办法就是采用更多数据,但有时候,我们无法获得更多数据,我们也可以尝试通过正则化来减少过拟合。如果能找到更合适的神经网络框架,有时它可能会同时减少方差和偏差。

但在当前的深度学习和大数据时代,只要正则适度,通常构建一个更大的网络便可以在不影响方差的同时减少偏差,而采用更多数据通常可以在不过多影响偏差的同时减少方差。现在我们有工具可以做到在减少偏差或方差的同时,不对另一方产生过多不良影响。

正则化
正则化通常有助于避免过拟合或减少你的网络误差。

逻辑回归
min ⁡ w , b J ( w , b ) = min ⁡ w , b 1 m ∑ i = 1 m L ( y ∧ ( i ) , y ( i ) ) , w ∈ R n x , b ∈ R \min_{w,b} J\left( w,b \right) =\min_{w,b} \frac{1}{m}\sum_{i=1}^m{\mathscr{L}\left( \overset{\land}{y}^{\left( i \right)},y^{\left( i \right)} \right)}\text{,}w\in \mathbb{R}^{n_x},b\in \mathbb{R} minw,bJ(w,b)=minw,bm1i=1mL(y(i),y(i))wRnx,bR
L 2 L_2 L2正则化: J ( w , b ) = 1 m ∑ i = 1 m L ( y ∧ ( i ) , y ( i ) ) + λ 2 m ∥ w ∥ 2 2 J\left( w,b \right) =\frac{1}{m}\sum_{i=1}^m{\mathscr{L}\left( \overset{\land}{y}^{\left( i \right)},y^{\left( i \right)} \right)}+\frac{\lambda}{2m}\lVert w \rVert _{2}^{2} J(w,b)=m1i=1mL(y(i),y(i))+2mλw22
其中 ∥ w ∥ 2 2 = ∑ j = 1 n x w j 2 = w T w \lVert w \rVert _{2}^{2}=\sum_{j=1}^{n_x}{w_{j}^{2}}=w^Tw w22=j=1nxwj2=wTw

L 1 L_1 L1正则化: λ m ∑ j = 1 n x ∣ w j ∣ = λ m ∥ w ∥ 1 \frac{\lambda}{m}\sum_{j=1}^{n_x}{\left| w_j \right|}=\frac{\lambda}{m}\lVert w \rVert _1 mλj=1nxwj=mλw1

w w w最终会是稀疏的,也就是说向量 w w w中有很多0, L 1 L_1 L1正则化不是为了压缩模型,人们在训练网络时,越来越倾向于使用 L 2 L_2 L2正则化。

λ \lambda λ是正则化参数,通常使用验证集或交叉验证集来配置这个参数,尝试各种各样的数据,寻找最好的参数,要考虑训练集之间的权衡,把参数设置为较小值,这样可以避免过拟合,所以 λ \lambda λ是另外一个需要调整的超参数。在Python编程语言中 λ \lambda λ写成lambd

神经网络
L 2 L_2 L2正则化: 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\left( W^{\left[ 1 \right]},b^{\left[ 1 \right]},\cdots ,W^{\left[ L \right]},b^{\left[ L \right]} \right) =\frac{1}{m}\sum_{i=1}^m{\mathscr{L}\left( \overset{\land}{y}^{\left( i \right)},y^{\left( i \right)} \right)}+\frac{\lambda}{2m}\sum_{l=1}^L{\lVert W^{\left[ l \right]} \rVert _{F}^{2}} J(W[1],b[1],,W[L],b[L])=m1i=1mL(y(i),y(i))+2mλl=1LW[l]F2
其中 ∥ W [ l ] ∥ F 2 = ∑ i = 1 n [ l − 1 ] ∑ j = 1 n [ l ] ( w i j [ l ] ) 2 \lVert W^{\left[ l \right]} \rVert _{F}^{2}=\sum_{i=1}^{n^{\left[ l-1 \right]}}{\sum_{j=1}^{n^{\left[ l \right]}}{\left( w_{ij}^{\left[ l \right]} \right) ^2}} W[l]F2=i=1n[l1]j=1n[l](wij[l])2(Frobenius范数:矩阵中所有元素的平方和), W [ l ] W^{\left[ l \right]} W[l]维度为 n [ l ] × n [ l − 1 ] n^{\left[ l \right]}\times n^{\left[ l-1 \right]} n[l]×n[l1].

梯度下降
d W [ l ] = ( f r o m    b a c k p r o p ) dW^{\left[ l \right]}=\left( from\,\,backprop \right) dW[l]=(frombackprop),backprop会给出 J J J W [ l ] W^{\left[ l \right]} W[l]的偏导数: ∂ J ∂ W [ l ] = d W [ l ] \frac{\partial J}{\partial W^{\left[ l \right]}}=dW^{\left[ l \right]} W[l]J=dW[l]
W [ l ] : = W [ l ] − α d W [ l ] W^{\left[ l \right]}:=W^{\left[ l \right]}-\alpha dW^{\left[ l \right]} W[l]:=W[l]αdW[l]

正则化(权重衰减)
d W [ l ] = ( f r o m    b a c k p r o p ) + λ m W [ l ] dW^{\left[ l \right]}=\left( from\,\,backprop \right) +\frac{\lambda}{m}W^{\left[ l \right]} dW[l]=(frombackprop)+mλW[l]
W [ l ] : = W [ l ] − α [ ( f r o m    b a c k p r o p ) + λ m W [ l ] ] = ( 1 − α λ m ) W [ l ] − α ( f r o m    b a c k p r o p ) W^{\left[ l \right]}:=W^{\left[ l \right]}-\alpha \left[ \left( from\,\,backprop \right) +\frac{\lambda}{m}W^{\left[ l \right]} \right] =\left( 1-\frac{\alpha \lambda}{m} \right) W^{\left[ l \right]}-\alpha \left( from\,\,backprop \right) W[l]:=W[l]α[(frombackprop)+mλW[l]]=(1mαλ)W[l]α(frombackprop)

其中 1 − α λ m < 1 1-\frac{\alpha \lambda}{m}<1 1mαλ<1

为什么正则化有利于预防过拟合呢?
J ( w , b ) = 1 m ∑ i = 1 m L ( y ∧ ( i ) , y ( i ) ) + λ 2 m ∥ w ∥ 2 2 J\left( w,b \right) =\frac{1}{m}\sum_{i=1}^m{\mathscr{L}\left( \overset{\land}{y}^{\left( i \right)},y^{\left( i \right)} \right)}+\frac{\lambda}{2m}\lVert w \rVert _{2}^{2} J(w,b)=m1i=1mL(y(i),y(i))+2mλw22
正则化项可以避免数据权值矩阵过大,如果 λ \lambda λ设置得足够大,权重矩阵 W W W被设置为接近于0的值 ( W [ l ] ≈ 0 ) \left( W^{\left[ l \right]}\approx 0 \right) (W[l]0),直观理解就是把多隐藏单元的权重设为0,于是基本上消除了这些隐藏单元的许多影响(实际上是该神经网络的所有隐藏单元依然存在,但是它们的影响变得更小了) 。

如果是这种情况,复杂神经网络会变成一个很小的网络,小到如同一个逻辑回归单元,会使这个网络从过拟合的状态更接近高偏差状态。但是 λ \lambda λ会存在一个中间值,于是会有一个接近“Just Right”的中间状态。
在这里插入图片描述
g ( z ) = tanh ⁡ ( z ) , λ ↑    W [ l ] ↓    z [ l ] ↓    g ( z ) g\left( z \right) =\tanh \left( z \right) \text{,}\lambda \uparrow \,\,W^{\left[ l \right]}\downarrow \,\,z^{\left[ l \right]}\downarrow \,\,g\left( z \right) g(z)=tanh(z)λW[l]z[l]g(z)大致呈线性,每层几乎都是线性的,那么整个网络就是一个线性网络,这个线性函数非常简单,并不是一个极复杂的高度非线性函数,不会发生过拟合。因此,它不适用于非常复杂的决策,以及过度拟合数据集的非线性决策边界。

为了调试梯度下降, J J J必须包含正则化项,否则 J J J可能不会在所有迭代范围内都单调递减。

Dropout 正则化
假设训练一个神经网络,它存在过拟合,复制这个神经网络,Dropout会遍历网络的每一层,并设置消除神经网络中节点的概率。假设网络中的每一层,每个节点都以抛硬币的方式设置概率,每个节点得以保留和消除的概率都是0.5,设置完节点概率,我们会消除一些节点,然后删除掉从该节点进出的连线,最后得到一个节点更少,规模更小的网络,然后用Backprop方法进行训练。
在这里插入图片描述
对于其它样本,我们照旧以抛硬币的方式设置概率,保留一类节点集合,删除其它类型的节点集合。

实施Dropout的方法:Inverted Dropout

d [ 3 ] d^{\left[ 3 \right]} d[3]表示一个三层的Dropout向量:
d3=np.random.rand(a3.shape[0],a3.shape[1])<keep_prob
其中keep-prob=0.8.

keep-prob表示保留某个隐藏单元的概率是0.8,消除任意一个隐藏单元的概率是0.2. d [ 3 ] d^{\left[ 3 \right]} d[3]的作用就是生成随机矩阵,如果对 a [ 3 ] a^{\left[ 3 \right]} a[3]进行因子分解,效果也是一样的。 d [ 3 ] d^{\left[ 3 \right]} d[3]是一个矩阵,其中对应值为1的概率都是0.8,对应为0的概率是0.2.

接下来要做的就是从第三层中获取激活函数,a3=np.multiply(a3,d3) ,这里是元素相乘,也可写为a3 /= d3.

如果用Python实现该算法的话,则是一个布尔型数组,值为true和false,乘法运算依然有效,python会把true和false翻译为1和0.

最后,对 a [ 3 ] a^{\left[ 3 \right]} a[3]进行scale up处理a3 /= keep_prob(Inverted Dropout方法)

a [ 3 ] a^{\left[ 3 \right]} a[3]进行scale up是为了保证在经过Dropout后, a [ 3 ] a^{\left[ 3 \right]} a[3]作为下一层神经元的输入值尽量保持不变。

假设第三隐藏层上有50个单元或神经元,保留和删除它们的概率分别为80%和20%,这意味着 a [ 3 ] a^{\left[ 3 \right]} a[3]最后被删除或归零的单元平均有10(50×20%=10)个,那么得到的 a [ 3 ] a^{\left[ 3 \right]} a[3]只相当于原来的80%, z [ 4 ] = W [ 4 ] a [ 3 ] + b [ 4 ] z^{\left[ 4 \right]}=W^{\left[ 4 \right]}a^{\left[ 3 \right]}+b^{\left[ 4 \right]} z[4]=W[4]a[3]+b[4],为了不影响 z [ 4 ] z^{\left[ 4 \right]} z[4]的期望值,需要用 W [ 4 ] a [ 3 ] / 0.8 W^{\left[ 4 \right]}a^{\left[ 3 \right]}/0.8 W[4]a[3]/0.8,它将会修正或弥补我们所需的那20%, a [ 3 ] a^{\left[ 3 \right]} a[3]的期望值不会变。

在测试阶段不使用Dropout函数,因为在测试阶段进行预测时,我们不期望输出结果是随机的,如果测试阶段应用Dropout函数,预测会受到干扰。

因为在训练时,使用scale up保证 a [ 3 ] a^{\left[ 3 \right]} a[3]的期望值没有大的变化,测试时就不需要再对样本数据进行类似的尺度伸缩操作了。

Inverted Dropout函数在除以keep-prob时可以记住上一步的操作,目的是确保即使在测试阶段不执行Dropout来调整数值范围,激活函数的预期结果也不会发生变化,所以没必要在测试阶段额外添加尺度参数,这与训练阶段不同。

理解 Dropout
不能依赖于任何一个特征,因为该单元的输入(特征) 可能被随机清除。通过传播所有权重,Dropout将产生收缩权重的平方范数的效果,和 L 2 L_2 L2正则化类似; L 2 L_2 L2对不同权重的衰减是不同的,它取决于激活函数倍增的大小。

L 2 L_2 L2正则化不同的是被应用的方式不同,Dropout也会有所不同,甚至更适用于不同的输入范围。

这是一个拥有三个输入特征的网络,其中一个要选择的参数是keep-prob.

第1层:0.7,第2层:0.5 ( W [ 2 ] W^{\left[ 2 \right]} W[2]维度为7×7),第3层:0.7,第4层:1.0,第5层:1.0,

输入层:1.0 (消除一半的输入特征是不太可能)

如果担心某些层比其它层更容易发生过拟合,可以把某些层的keep-prob值设置得比其它层更低,缺点是为了使用交叉验证,要搜索更多的超参数,另一种方案是在一些层上应用Dropout,而有些层不用Dropout,应用Dropout的层只含有一个超参数keep-prob.

Dropout在计算机视觉中应用得比较频繁,因为通常没有足够的数据,所以一直存在过拟合。

Dropout一大缺点就是代价函数 J J J不再被明确定义,每次迭代,都会随机移除一些节点,如果再三检查梯度下降的性能,实际上是很难进行复查的。J没有明确定义,在某种程度上很难计算,所以我们失去了调试工具来绘制这样的图片(代价函数 J J J每次迭代后都会下降) 。

其他正则化方法
一. Data Augmentation

拟合猫咪图片分类器

水平翻转图片或把原图旋转并随意放大后裁剪的图片,并把它添加到训练集,可以增大数据集,额外生成假训练数据。

以这种方式扩增算法数据,进而正则化数据集,减少过拟合比较廉价。

光学字符识别(OCR)

随意旋转或扭曲数字(轻微的变形就好)来扩增数据

二. Early Stopping
在这里插入图片描述
通过Early Stopping,还可以绘制验证集误差,可以是验证集上的分类误差,或验证集上的代价函数,逻辑损失和对数损失等。

验证集误差通常会先呈下降趋势,然后在某个节点处开始上升,Early Stopping的作用是,神经网络已经在这个迭代过程中表现得很好了,在这个节点停止训练。

Early Stopping要做就是在中间点停止迭代过程(提早停止训练神经网络) ,得到一个值中等大小的Frobenius范数。

机器学习过程包括几个步骤,其中一步是选择一个算法(如梯度下降,Momentum,RMSprop和Adam等)来优化代价函数 J J J,但是优化代价函数之后,也不想发生过拟合(比如正则化,扩增数据等) 。

预防过拟合还有其他任务,就是减少方差,这一步用另外一套工具来实现,这个原理有时被称为“正交化”。思路是在一个时间做一个任务。

Early Stopping的主要缺点就是不能独立地处理这两个问题,因为提早停止梯度下降,也就是停止了优化代价函数,因为现在不再尝试降低代价函数,所以代价函数的值可能不够小,同时又希望不出现过拟合,你没有采取不同的方式来解决这两个问题,而是用一种方法同时解决两个问题,这样做的结果是要考虑的东西变得更复杂。

Early Stopping的优点是,只运行一次梯度下降,你可以找出 W W W的较小值,中间值和较大值。

如果不用Early Stopping,另一种方法就是 L 2 L_2 L2正则化,训练神经网络的时间就可能很长。这导致超参数搜索空间更容易分解,也更容易搜索,但是缺点在于,必须尝试很多正则化参数 λ \lambda λ的值,这也导致搜索大量 λ \lambda λ值的计算代价太高。更倾向于使用 L 2 L_2 L2正则化。

归一化输入
归一化输入需要两个步骤:零均值化和归一化方差
在这里插入图片描述
零均值化: μ = 1 m ∑ i = 1 m x ( i ) , x = x − μ \mu =\frac{1}{m}\sum_{i=1}^m{x^{\left( i \right)}}\text{,}x=x-\mu μ=m1i=1mx(i)x=xμ

归一化方差: σ 2 = 1 m ∑ i = 1 m ( x ( i ) ) 2 ( e l e m e n t − w i s e ) , x    / = σ 2 \sigma ^2=\frac{1}{m}\sum_{i=1}^m{\left( x^{\left( i \right)} \right) ^2\left( element-wise \right) ,x\,\,/=\sigma ^2} σ2=m1i=1m(x(i))2(elementwise)x/=σ2

最后 x 1 x_1 x1 x 2 x_2 x2的方差都等于1.

用同样的方法调整测试集(相同 μ \mu μ σ 2 \sigma ^2 σ2),其中 μ \mu μ σ 2 \sigma ^2 σ2是由训练集数据计算得来的。

使用非归一化的输入特征会得到左边的图,代价函数有点像狭长的碗,如果能画出该函数的部分轮廓,它会是这样一个狭长的函数(左下图)。
在这里插入图片描述
如果归一化特征,代价函数平均起来看更对称,如果在左图这样的代价函数上运行梯度下降法,必须使用一个非常小的学习率。因为如果是在这个位置,梯度下降法可能需要多次迭代过程,直到最后找到最小值。但如果函数是一个更圆的球形轮廓,那么不论从哪个位置开始,梯度下降法都能够更直接地找到最小值,可以在梯度下降法中使用较大步长,而不需要像在左图中那样反复执行。

确保所有特征在相似范围内。

梯度消失/梯度爆炸
训练神经网络的时候,导数或斜率有时会变得非常大,或者非常小,甚至以指数方式变小,这加大了训练的难度。
在这里插入图片描述
假设 g ( z ) = z , b [ l ] = 0 g\left( z \right) =z\text{,}b^{\left[ l \right]}=0 g(z)=zb[l]=0

输出 y ∧ = W [ L ] W [ L − 1 ] ⋯ W [ 2 ] W [ 1 ] x \overset{\land}{y}=W^{\left[ L \right]}W^{\left[ L-1 \right]}\cdots W^{\left[ 2 \right]}W^{\left[ 1 \right]}x y=W[L]W[L1]W[2]W[1]x

其中 z [ 1 ] = W [ 1 ] x , a [ 1 ] = g ( z [ 1 ] ) = z [ 1 ] , a [ 2 ] = g ( z [ 2 ] ) = z [ 2 ] = W [ 2 ] a [ 1 ] = W [ 2 ] W [ 1 ] x z^{\left[ 1 \right]}=W^{\left[ 1 \right]}x,a^{\left[ 1 \right]}=g\left( z^{\left[ 1 \right]} \right) =z^{\left[ 1 \right]},a^{\left[ 2 \right]}=g\left( z^{\left[ 2 \right]} \right) =z^{\left[ 2 \right]}=W^{\left[ 2 \right]}a^{\left[ 1 \right]}=W^{\left[ 2 \right]}W^{\left[ 1 \right]}x z[1]=W[1]xa[1]=g(z[1])=z[1]a[2]=g(z[2])=z[2]=W[2]a[1]=W[2]W[1]x

假设每个权重矩阵 W [ l ] = [ 1.5 0 0 1.5 ] , y ∧ = W [ L ] [ 1.5 0 0 1.5 ] L − 1 x W^{\left[ l \right]}=\left[ \begin{matrix} 1.5& 0\\ 0& 1.5\\ \end{matrix} \right] ,\overset{\land}{y}=W^{\left[ L \right]}\left[ \begin{matrix} 1.5& 0\\ 0& 1.5\\ \end{matrix} \right] ^{L-1}x W[l]=[1.5001.5]y=W[L][1.5001.5]L1x非常大,呈指数级增长,它增长的比率是 1. 5 L 1.5^L 1.5L.

假设每个权重矩阵 W [ l ] = [ 0.5 0 0 0.5 ] , y ∧ = W [ L ] [ 0.5 0 0 0.5 ] L − 1 x W^{\left[ l \right]}=\left[ \begin{matrix} 0.5& 0\\ 0& 0.5\\ \end{matrix} \right] ,\overset{\land}{y}=W^{\left[ L \right]}\left[ \begin{matrix} 0.5& 0\\ 0& 0.5\\ \end{matrix} \right] ^{L-1}x W[l]=[0.5000.5]y=W[L][0.5000.5]L1x非常小,呈指数级下降,它下降的比率是 0. 5 L 0.5^L 0.5L.

在深度神经网络中, W [ l ] > I W^{\left[ l \right]}>I W[l]>I,激活函数(activations)将爆炸式增长, W [ l ] < I W^{\left[ l \right]}<I W[l]<I,激活函数(activations)将指数级递减。

它也适用于与层数 L L L相关的导数或梯度函数,也是呈指数级增长或呈指数级递减。

这会导致训练难度上升,梯度下降算法的步长会非常非常小,将花费很长时间来学习。

神经网络的权重初始化

中间为经过 a = g ( z ) a=g\left( z \right) a=g(z)处理。

z = w 1 x 1 + w 2 x 2 + ⋯ + w n x n z=w_1x_1+w_2x_2+\cdots +w_nx_n z=w1x1+w2x2++wnxn(忽略b),为了预防 z z z值过大或过小, n n n越大,希望 w i w_i wi越小。

方差 V a r ( w i ) = 1 n Var\left( w_i \right) =\frac{1}{n} Var(wi)=n1 n n n为神经元的输入特征数量

初始化: 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 ( 1 n [ l − 1 ] ) W^{\left[ l \right]}=np.random.randn\left( shape \right) \ast np.sqrt\left( \frac{1}{n^{\left[ l-1 \right]}} \right) W[l]=np.random.randn(shape)np.sqrt(n[l1]1)

Re L u ( g [ l ] ( z ) = Re L u ( z ) ) : V a r ( w i ) = 2 n , 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 [ l − 1 ] ) \text{Re}Lu\left( g^{\left[ l \right]}\left( z \right) =\text{Re}Lu\left( z \right) \right) :Var\left( w_i \right) =\frac{2}{n},W^{\left[ l \right]}=np.random.randn\left( shape \right) \ast np.sqrt\left( \frac{2}{n^{\left[ l-1 \right]}} \right) ReLu(g[l](z)=ReLu(z))Var(wi)=n2W[l]=np.random.randn(shape)np.sqrt(n[l1]2)

tanh ⁡ : 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 ( 1 n [ l − 1 ] ) 或 s q r t ( 2 n [ l − 1 ] + n [ l ] ) \tanh :W^{\left[ l \right]}=np.random.randn\left( shape \right) \ast np.sqrt\left( \frac{1}{n^{\left[ l-1 \right]}} \right) 或sqrt\left( \frac{2}{n^{\left[ l-1 \right]}+n^{\left[ l \right]}} \right) tanhW[l]=np.random.randn(shape)np.sqrt(n[l1]1)sqrt(n[l1]+n[l]2),Xavier初始化。

梯度的数值逼近

f ( θ ) = θ 3 f\left( \theta \right) =\theta ^3 f(θ)=θ3,大三角形: f ( θ + ε ) − f ( θ − ε ) 2 ε = 1.0 1 3 − 0.9 9 3 2 × 0.01 = 3.0001 ≈ g ( θ ) = 3 θ 2 = 3 \frac{f\left( \theta +\varepsilon \right) -f\left( \theta -\varepsilon \right)}{2\varepsilon}=\frac{1.01^3-0.99^3}{2\times 0.01}=3.0001\approx g\left( \theta \right) =3\theta ^2=3 2εf(θ+ε)f(θε)=2×0.011.0130.993=3.0001g(θ)=3θ2=3,逼近误差为0.0001.

小三角形:3.0301,逼近误差为0.0301.

f ′ ( θ ) = lim ⁡ ε → 0 f ( θ + ε ) − f ( θ − ε ) 2 ε f'\left( \theta \right) =\lim_{\varepsilon \rightarrow 0} \frac{f\left( \theta +\varepsilon \right) -f\left( \theta -\varepsilon \right)}{2\varepsilon} f(θ)=limε02εf(θ+ε)f(θε),对 ε ≠ 0 \varepsilon \ne 0 ε=0,逼近误差为 O ( ε 2 ) O\left( \varepsilon ^2 \right) O(ε2). O O O表示一些常量乘以 ε 2 \varepsilon ^2 ε2,大写 O O O的常量有时是1.

对于单边 f ( θ + ε ) − f ( θ ) ε \frac{f\left( \theta +\varepsilon \right) -f\left( \theta \right)}{\varepsilon} εf(θ+ε)f(θ),逼近误差为 O ( ε ) O\left( \varepsilon \right) O(ε),当 ε \varepsilon ε小于1时, ε > ε 2 \varepsilon >\varepsilon ^2 ε>ε2,近似值远没有上面(双边)公式的准确。

所以在执行梯度检验时,我们使用双边误差,即 f ( θ + ε ) − f ( θ − ε ) 2 ε \frac{f\left( \theta +\varepsilon \right) -f\left( \theta -\varepsilon \right)}{2\varepsilon} 2εf(θ+ε)f(θε).

梯度检验
分别将 W [ 1 ] , b [ 1 ] , ⋯   , W [ L ] , b [ L ] W^{\left[ 1 \right]},b^{\left[ 1 \right]},\cdots ,W^{\left[ L \right]},b^{\left[ L \right]} W[1],b[1],,W[L],b[L]这些矩阵构造(reshape)成一维向量,然后将这些一维向量连接(concatenation)起来构成一个更大的一维向量 θ \theta θ. 代价函数 J ( W [ 1 ] , b [ 1 ] , ⋯   , W [ L ] , b [ L ] ) = J ( θ ) . J\left( W^{\left[ 1 \right]},b^{\left[ 1 \right]},\cdots ,W^{\left[ L \right]},b^{\left[ L \right]} \right) =J\left( \theta \right). J(W[1],b[1],,W[L],b[L])=J(θ).

同样可以把 d W [ 1 ] , d b [ 1 ] , ⋯   , d W [ L ] , d b [ L ] dW^{\left[ 1 \right]},db^{\left[ 1 \right]},\cdots ,dW^{\left[ L \right]},db^{\left[ L \right]} dW[1],db[1],,dW[L],db[L]转换成一个新的向量,用它们来初始化大向量 d θ d\theta dθ,它与 θ \theta θ具有相同维度。

实施梯度检验 ( G r a d    c h e c k ) \left( Grad\,\,check \right) (Gradcheck)的过程: ( J ( θ ) = J ( θ 1 , θ 2 , ⋯   ) ) \left( J\left( \theta \right) =J\left( \theta _1,\theta _2,\cdots \right) \right) (J(θ)=J(θ1,θ2,))

f o r    e a c h    i : for\,\,each\,\,i: foreachi

d θ a p p r o x [ i ] = J ( θ 1 , θ 2 , ⋯   , θ i + ε , ⋯   ) − J ( θ 1 , θ 2 , ⋯   , θ i − ε , ⋯   ) 2 ε ≈ d θ [ i ] = ∂ J ∂ θ i d\theta _{approx}\left[ i \right] =\frac{J\left( \theta _1,\theta _2,\cdots ,\theta _i+\varepsilon ,\cdots \right) -J\left( \theta _1,\theta _2,\cdots ,\theta _i-\varepsilon ,\cdots \right)}{2\varepsilon}\approx d\theta \left[ i \right] =\frac{\partial J}{\partial \theta _i} dθapprox[i]=2εJ(θ1,θ2,,θi+ε,)J(θ1,θ2,,θiε,)dθ[i]=θiJ

验证 d θ a p p r o x ≈ d θ ? d\theta _{approx}\approx d\theta ? dθapproxdθ?

C h e c k    ∥ d θ a p p r o x − d θ ∥ 2 ∥ d θ a p p r o x ∥ 2 + ∥ d θ ∥ 2 , ε = 1 0 − 7 Check\,\,\frac{\lVert d\theta _{approx}-d\theta \rVert _2}{\lVert d\theta _{approx} \rVert _2+\lVert d\theta \rVert _2},\varepsilon =10^{-7} Checkdθapprox2+dθ2dθapproxdθ2ε=107

i f    ≈ 1 0 − 7 if\,\,\approx 10^{-7} if107或更小,这就很好;

i f    ≈ 1 0 − 5    if\,\,\approx 10^{-5}\,\, if105检查确保没有一项误差过大;

i f    ≈ 1 0 − 3    if\,\,\approx 10^{-3}\,\, if103存在bug,仔细检查所有 θ \theta θ项,看是否有一个具体的i值,使得 d θ a p p r o x [ i ] 与 d θ [ i ] d\theta _{approx}\left[ i \right] 与d\theta \left[ i \right] dθapprox[i]dθ[i]大不相同,并用它来追踪一些求导计算是否正确。

梯度检验应用的注意事项

  • 不要在训练中使用梯度检验,它只用于debug.
  • 如果算法的梯度检验失败,要检查所有项,找到对应出错的梯度,检查其推导是否出现错误。
  • 在实施梯度检验时,如果使用正则化,请注意正则项, d θ d\theta dθ等于 θ \theta θ J J J相关的函数的梯度,记住一定要包括正则项。
  • 梯度检验不能与Dropout同时使用,因为每次迭代过程中,Dropout会随机消除隐藏层单元的不同子集,难以计算Dropout在梯度下降上的代价函数J,梯度检验时关闭Dropout,检验完毕后再打开Dropout.
  • (不常用)随机初始化过程中,运行梯度检验,然后再训练网络,w和b会有一段时间远离0,如果随机初始化值比较小,反复训练网络之后,再重新运行梯度检验。

优化算法

Mini-batch 梯度下降
如果m很大的话,处理速度仍然缓慢。比如说,如果m是500万或5000万或者更大的一个数,在对整个训练集执行梯度下降法时,必须处理整个训练集,然后才能进行一步梯度下降法,然后需要再重新处理500万个训练样本,才能进行下一步梯度下降法。所以如果在处理完整个500万个样本的训练集之前,先让梯度下降法处理一部分,算法速度会更快。

X = [ x ( 1 )    x ( 2 )    ⋯    x ( 1000 ) ⏟ X { 1 } ∣ x ( 1001 )    ⋯    x ( 2000 ) ⏟ X { 2 } ∣ ⋯ ⋯ ∣ ⋯ x ( m ) ⏟ X { 5000 } ] X=\left[ \mathop{\underbrace{x^{\left( 1 \right)}\,\,x^{\left( 2 \right)}\,\,\cdots \,\,x^{\left( 1000 \right)}}}_{X^{\left\{ 1 \right\}}}^{}|\mathop{\underbrace{x^{\left( 1001 \right)}\,\,\cdots \,\,x^{\left( 2000 \right)}}}_{X^{\left\{ 2 \right\}}}^{}|\cdots \cdots |\mathop{\underbrace{\cdots x^{\left( m \right)}}}_{X^{\left\{ 5000 \right\}}}^{} \right] X=[ x(1)x(2)x(1000)X{1} x(1001)x(2000)X{2} x(m)X{5000}],X的维数是 ( n x , m ) \left( n_x,m \right) (nx,m)

Y = [ y ( 1 )    y ( 2 )    ⋯    y ( 1000 ) ⏟ Y { 1 } ∣ y ( 1001 )    ⋯    y ( 2000 ) ⏟ Y { 2 } ∣ ⋯ ⋯ ∣ ⋯ y ( m ) ⏟ Y { 5000 } ] Y=\left[ \mathop{\underbrace{y^{\left( 1 \right)}\,\,y^{\left( 2 \right)}\,\,\cdots \,\,y^{\left( 1000 \right)}}}_{Y^{\left\{ 1 \right\}}}^{}|\mathop{\underbrace{y^{\left( 1001 \right)}\,\,\cdots \,\,y^{\left( 2000 \right)}}}_{Y^{\left\{ 2 \right\}}}^{}|\cdots \cdots |\mathop{\underbrace{\cdots y^{\left( m \right)}}}_{Y^{\left\{ 5000 \right\}}}^{} \right] Y=[ y(1)y(2)y(1000)Y{1} y(1001)y(2000)Y{2} y(m)Y{5000}],Y的维数是 ( 1, m ) \left( \text{1,}m \right) (1,m)

可以把训练集分割为小一点的子集训练,这些子集被取名为Mini-batch,假设每一个子集中只有1000个样本,共有5000个mini-batch. 对Y进行相同处理。

Mini-batch的数量 t t t组成了 X { t } 和 Y { t } X^{\left\{ t \right\}}和Y^{\left\{ t \right\}} X{t}Y{t} X { t } X^{\left\{ t \right\}} X{t}的维数是 ( n x , 1000 ) \left( n_x,1000 \right) (nx,1000) Y { t } Y^{\left\{ t \right\}} Y{t}的维数是 ( 1, 1000 ) \left( \text{1,}1000 \right) (1,1000).

r e p e a t { repeat\{ repeat{
      f o r    t = 1, ⋯   , 5000 { \,\,\,\,\,for\,\,t=\text{1,}\cdots ,5000\{ fort=1,,5000{
            F o r w a r d    p r o p    o n    X { t } \,\,\,\,\,\,\,\,\,\,\,Forward\,\,prop\,\,on\,\,X^{\left\{ t \right\}} ForwardproponX{t}
               Z [ 1 ] = W [ 1 ] X { t } + b [ 1 ] A [ 1 ] = g [ 1 ] ( Z [ 1 ] )                   ⋮                                     A [ L ] = g [ L ] ( Z [ L ] )              } V e c t o r i z e d    i m p l e m e n t a t i o n ( 1000  e x a m p l e s ) \,\,\,\,\,\,\,\,\,\,\,\,\,\,\left. \begin{array}{r} Z^{\left[ 1 \right]}=W^{\left[ 1 \right]}X^{\left\{ t \right\}}+b^{\left[ 1 \right]}\\ A^{\left[ 1 \right]}=g^{\left[ 1 \right]}\left( Z^{\left[ 1 \right]} \right)\,\,\,\,\,\,\,\,\,\,\,\,\,\,\\ \,\, \vdots \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\, \\ A^{\left[ L \right]}=g^{\left[ L \right]}\left( Z^{\left[ L \right]} \right)\,\,\,\,\,\,\,\,\,\,\,\,\\ \end{array} \right\} Vectorized\,\,implementation\left( \text{1000 }examples \right) Z[1]=W[1]X{t}+b[1]A[1]=g[1](Z[1])A[L]=g[L](Z[L])Vectorizedimplementation(1000 examples)
            C o m p u t e    C o s t    J { t } = 1 1000 ∑ i = 1 1000 L ( y ∧ ( i ) , y ( i ) ) + λ 2 ⋅ 1000 ∑ l = 1 L ∥ W [ l ] ∥ F 2 \,\,\,\,\,\,\,\,\,\,\,Compute\,\,Cost\,\,J^{\left\{ t \right\}}=\frac{1}{1000}\sum_{i=1}^{1000}{\mathscr{L}\left( \overset{\land}{y}^{\left( i \right)},y^{\left( i \right)} \right)}+\frac{\lambda}{2\cdot 1000}\sum_{l=1}^L{\lVert W^{\left[ l \right]} \rVert _{F}^{2}} ComputeCostJ{t}=10001i=11000L(y(i),y(i))+21000λl=1LW[l]F2,其中 y ∧ ( i ) , y ( i )    f r o m    X { t } , Y { t } \overset{\land}{y}^{\left( i \right)},y^{\left( i \right)}\,\,from\,\,X^{\left\{ t \right\}},Y^{\left\{ t \right\}} y(i),y(i)fromX{t},Y{t}
            B a c k p r o p    t o    c o m p u t e    g r a d i e n t s    w i t h    r e s p e c t    t o    J { t } ( u s i n g ( X { t } , Y { t } ) ) \,\,\,\,\,\,\,\,\,\,\,Backprop\,\,to\,\,compute\,\,gradients\,\,with\,\,respect\,\,to\,\,J^{\left\{ t \right\}}\left( using\left( X^{\left\{ t \right\}},Y^{\left\{ t \right\}} \right) \right) BackproptocomputegradientswithrespecttoJ{t}(using(X{t},Y{t}))
            W [ l ] = W [ l ] − α d W [ l ] , b [ l ] = b [ l ] − α d b [ l ] \,\,\,\,\,\,\,\,\,\,\,W^{\left[ l \right]}=W^{\left[ l \right]}-\alpha dW^{\left[ l \right]},b^{\left[ l \right]}=b^{\left[ l \right]}-\alpha db^{\left[ l \right]} W[l]=W[l]αdW[l]b[l]=b[l]αdb[l]
            } \,\,\,\,\,\,\,\,\,\,\,\} }
} \} }
这是使用mini-batch梯度下降法训练样本的一步,代码也可被称为进行“一代”(1 epoch)的训练。一代这个词意味着只是一次遍历了训练集。一个epoch会进行5000次梯度下降算法。

注意:视频中 J { t } = 1 1000 ∑ i = 1 l L ( y ∧ ( i ) , y ( i ) ) + λ 2 ⋅ 1000 ∑ l ∥ W [ l ] ∥ F 2 J^{\left\{ t \right\}}=\frac{1}{1000}\sum_{i=1}^l{\mathscr{L}\left( \overset{\land}{y}^{\left( i \right)},y^{\left( i \right)} \right)}+\frac{\lambda}{2\cdot 1000}\sum_l^{}{\lVert W^{\left[ l \right]} \rVert _{F}^{2}} J{t}=10001i=1lL(y(i),y(i))+21000λlW[l]F2

理解Mini-batch 梯度下降
在这里插入图片描述
噪声:也许 X { 1 } X^{\left\{ 1 \right\}} X{1} Y { 1 } Y^{\left\{ 1 \right\}} Y{1}是比较容易计算的mini-batch,因此成本会低一些。 X { 2 } X^{\left\{ 2 \right\}} X{2} Y { 2 } Y^{\left\{ 2 \right\}} Y{2}是比较难运算的mini-batch,或许你需要一些残缺的样本,成本(cost)会更高一些,所以才会出现这些摆动。

选择mini-batch的大小

( 1 ) m i n i − b a t c h    s i z e = m \left( 1 \right) mini-batch\,\,size=m (1)minibatchsize=m,就是Batch gradient descent, ( X { 1 } , Y { 1 } ) = ( X , Y ) \left( X^{\left\{ 1 \right\}},Y^{\left\{ 1 \right\}} \right) =\left( X,Y \right) (X{1},Y{1})=(X,Y),Batch梯度下降法从某处开始,相对噪声低些,幅度也大一些,可以继续找最小值。训练样本数量巨大的时候,单次迭代耗时太长。

( 2 ) m i n i − b a t c h    s i z e = 1 \left( 2 \right) mini-batch\,\,size=1 (2)minibatchsize=1,随机梯度下降法,每个样本都是独立的mini-batch, ( X { 1 } , Y { 1 } ) = ( x ( 1 ) , y ( 1 ) ) \left( X^{\left\{ 1 \right\}},Y^{\left\{ 1 \right\}} \right) =\left( x^{\left( 1 \right)},y^{\left( 1 \right)} \right) (X{1},Y{1})=(x(1),y(1)),大部分时候向着全局最小值靠近,有时候会远离最小值,因为那个样本恰好指的方向不对,因此随机梯度下降法是有很多噪声,因为随机梯度下降法永远不会收敛,而是会一直在最小值附近波动,并不会在达到最小值并停留在此。通过减小学习率,噪声会被改善或有所减小,但随机梯度下降法的一大缺点是,会失去所有向量化带来的加速。

( 3 ) \left( 3 \right) (3)大小在1和m之间的好处: ( i ) \left( i \right) (i) fastest learning; ( i i ) \left( ii \right) (ii)大量向量化; ( i i i ) \left( iii \right) (iii)不需要等待整个训练集被处理完就可以开始进行后续工作,比随机梯度下降要更持续地靠近最小值的方向,它也不一定在很小的范围内收敛或者波动,如果出现这个问题,可以慢慢减少学习率。

如果训练集较小 ( m ⩽ 2000 ) \left( m\leqslant 2000 \right) (m2000),直接使用Batch梯度下降法(size=m).

样本数目较大的话, s i z e = 64/128/256/512/ 1024 size=\text{64/128/256/512/}1024 size=64/128/256/512/1024(比较少见)。

注意:要确保 X { t } 和 Y { t } X^{\left\{ t \right\}}和Y^{\left\{ t \right\}} X{t}Y{t}要符合CPU/GPU内存。

指数加权平均
去年伦敦的每日温度
θ 1 = 40° F , θ 2 = 49° F , θ 3 = 45° F ⋯ θ 180 = 60° F , θ 181 = 56° F , ⋯ \theta _1=\text{40\degree}F,\theta _2=\text{49\degree}F,\theta _3=\text{45\degree}F\cdots \theta _{180}=\text{60\degree}F,\theta _{181}=\text{56\degree}F,\cdots θ1=40°Fθ2=49°Fθ3=45°Fθ180=60°Fθ181=56°F

v 0 = 0 v 1 = 0.9 v 0 + 0.1 θ 1 v 2 = 0.9 v 1 + 0.1 θ 2 ⋮    v t = 0.9 v t − 1 + 0.1 θ t } \left. \begin{array}{r} v_0=0\\ v_1=0.9v_0+0.1\theta _1\\ v_2=0.9v_1+0.1\theta _2\\ \vdots \,\, \\ v_t=0.9v_{t-1}+0.1\theta _t\\ \end{array} \right\} v0=0v1=0.9v0+0.1θ1v2=0.9v1+0.1θ2vt=0.9vt1+0.1θt每日温度的指数加权平均值.

v t = β v t − 1 + ( 1 − β ) θ t , v t v_t=\beta v_{t-1}+\left( 1-\beta \right) \theta _t,v_t vt=βvt1+(1β)θtvt可视为 1 1 − β \frac{1}{1-\beta} 1β1天的平均温度。

β = 0.9 ⇒ 1 1 − β = 10 \beta =0.9\Rightarrow \frac{1}{1-\beta}=10 β=0.91β1=10天的温度平均值(红线)。

β = 0.98 ⇒ 1 1 − β = \beta =0.98\Rightarrow \frac{1}{1-\beta}= β=0.981β1=过去50天的温度平均值(绿线),曲线要平坦一些,原因在于多平均了几天的温度,所以这个曲线,波动更小,更加平坦,缺点是曲线进一步右移,因为现在平均的温度值更多,在温度变化时,指数加权平均值适应地更缓慢一些,所以会出现一定延迟。

β = 0.5 ⇒ 1 1 − β = \beta =0.5\Rightarrow \frac{1}{1-\beta}= β=0.51β1=过去2天的温度平均值(黄线),由于仅平均了两天的温度,平均的数据太少,所以得到的曲线有更多的噪声,有可能出现异常值,但是这个曲线能够更快适应温度变化。

理解指数加权平均
v t = β v t − 1 + ( 1 − β ) θ t v_t=\beta v_{t-1}+\left( 1-\beta \right) \theta _t vt=βvt1+(1β)θt

v 100 = 0.9 v 99 + 0.1 θ 100 v_{100}=0.9v_{99}+0.1\theta _{100} v100=0.9v99+0.1θ100
v 99 = 0.9 v 98 + 0.1 θ 99 v_{99}=0.9v_{98}+0.1\theta _{99} v99=0.9v98+0.1θ99
v 98 = 0.9 v 97 + 0.1 θ 98 v_{98}=0.9v_{97}+0.1\theta _{98} v98=0.9v97+0.1θ98
⋯ \cdots

v 100 v_{100} v100
= 0.1 θ 100 + 0.9 ( 0.1 θ 99 + 0.9 ( 0.1 θ 98 + 0.9 ( ⋯   ) ) ) =0.1\theta _{100}+0.9\left( 0.1\theta _{99}+0.9\left( 0.1\theta _{98}+0.9\left( \cdots \right) \right) \right) =0.1θ100+0.9(0.1θ99+0.9(0.1θ98+0.9()))
= 0.1 θ 100 + 0.1 × 0.9 θ 99 + 0.1 ( 0.9 ) 2 θ 98 + 0.1 ( 0.9 ) 3 θ 97 + 0.1 ( 0.9 ) 4 θ 96 + ⋯ =0.1\theta _{100}+0.1\times 0.9\theta _{99}+0.1\left( 0.9 \right) ^2\theta _{98}+0.1\left( 0.9 \right) ^3\theta _{97}+0.1\left( 0.9 \right) ^4\theta _{96}+\cdots =0.1θ100+0.1×0.9θ99+0.1(0.9)2θ98+0.1(0.9)3θ97+0.1(0.9)4θ96+

这是一个加和并平均,系数为指数衰减函数。

0. 9 10 ≈ 0.35 ≈ 1 e , ( 1 − ε ) 1 ε ≈ 1 e 0.9^{10}\approx 0.35\approx \frac{1}{e},\left( 1-\varepsilon \right) ^{\frac{1}{\varepsilon}}\approx \frac{1}{e} 0.9100.35e1(1ε)ε1e1,10天后,曲线的高度下降到 1 3 \frac{1}{3} 31,相当于在峰值的 1 e \frac{1}{e} e1.

只关注过去10天的温度,因为10天后,权重下降到不到当日权重的\frac{1}{3}.

0.9 8 50 ≈ 1 e , 50 = 1 0.02 = 1 ε = 1 1 − β 0.98^{50}\approx \frac{1}{e},50=\frac{1}{0.02}=\frac{1}{\varepsilon}=\frac{1}{1-\beta} 0.9850e150=0.021=ε1=1β1

执行指数加权平均:
v θ : = 0 v_{\theta}:=0 vθ:=0
v θ : = β v θ + ( 1 − β ) θ 1 v_{\theta}:=\beta v_{\theta}+\left( 1-\beta \right) \theta _1 vθ:=βvθ+(1β)θ1
v θ : = β v θ + ( 1 − β ) θ 2 v_{\theta}:=\beta v_{\theta}+\left( 1-\beta \right) \theta _2 vθ:=βvθ+(1β)θ2
⋮ \vdots

v θ = 0 v_{\theta}=0 vθ=0
Re p e a t { \text{Re}peat\{ Repeat{
                    G e t    n e x t    θ t \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,Get\,\,next\,\,\theta _t Getnextθt
                    v θ : = β v θ + ( 1 − β ) θ t       \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,v_{\theta}:=\beta v_{\theta}+\left( 1-\beta \right) \theta _t\,\,\,\,\, vθ:=βvθ+(1β)θt #一行代码。
                    } \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\} }

指数加权平均数公式的好处之一在于,它占用极少内存。

指数加权平均的偏差修正
v t = β v t − 1 + ( 1 − β ) θ t v_t=\beta v_{t-1}+\left( 1-\beta \right) \theta _t vt=βvt1+(1β)θt

β \beta β等于0.98的时候,得到的并不是绿色曲线,而是紫色曲线,注意到紫色曲线的起点较低。

v 0 = 0 v_0=0 v0=0
v 1 = 0.98 v 0 + 0.02 θ 1 = 0.02 θ 1 v_1=0.98v_0+0.02\theta _1=0.02\theta _1 v1=0.98v0+0.02θ1=0.02θ1,得到的值会小很多,所以第一天温度的估测不准。
v 2 = 0.98 v 1 + 0.02 θ 2 = 0.0196 θ 1 + 0.02 θ 2 v_2=0.98v_1+0.02\theta _2=0.0196\theta _1+0.02\theta _2 v2=0.98v1+0.02θ2=0.0196θ1+0.02θ2
计算后 v 2 v_2 v2要远小于 θ 1 \theta _1 θ1 θ 2 \theta _2 θ2,所以 v 2 v_2 v2不能很好估测出这一年前两天的温度。

在估测初期, u s e    v t 1 − β t use\,\,\frac{v_t}{1-\beta ^t} use1βtvt
t = 2 : 1 − β t = 1 − ( 0.98 ) 2 = 0.0396 , v 2 0.0396 = 0.0196 θ 1 + 0.02 θ 2 0.0396 t=2:1-\beta ^t=1-\left( 0.98 \right) ^2=0.0396,\frac{v_2}{0.0396}=\frac{0.0196\theta _1+0.02\theta _2}{0.0396} t=21βt=1(0.98)2=0.03960.0396v2=0.03960.0196θ1+0.02θ2,去除了偏差。
随着 t t t增加, β t \beta ^t βt接近于0,所以当 t t t很大的时候,偏差修正几乎没有作用,紫线基本和绿线重合了。

Momentum梯度下降
动量梯度下降法,运行速度几乎总是快于标准的梯度下降算法,基本的想法就是计算梯度的指数加权平均数,并利用该梯度更新权重。

如果要优化成本函数,函数形状如上图,红点代表最小值的位置,假设从这里(蓝色点)开始梯度下降法,如果进行梯度下降法的一次迭代,无论是batch或mini-batch下降法,也许会指向这里,现在在椭圆的另一边,计算下一步梯度下降,结果或许如此,然后再计算一步,再一步,计算下去,梯度下降法要很多计算步骤慢慢摆动到最小值,这种上下波动减慢了梯度下降法的速度,无法使用更大的学习率,如果用较大的学习率(紫色箭头),结果可能会偏离函数的范围,为了避免摆动过大,要用一个较小的学习率。

在纵轴上,希望学习慢一点,不想要这些摆动,在横轴上,希望加快学习,快速从左向右移,移向最小值,移向红点。

动量梯度下降法:
v d W = 0 , v d b = 0 v_{dW}=0,v_{db}=0 vdW=0vdb=0
在第t次迭代的中:
                 \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\, 计算当前mini-batch的 d W dW dW d b db db. (省略上标)
                 v d W = β v d W + ( 1 − β ) d W     \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,v_{dW}=\beta v_{dW}+\left( 1-\beta \right) dW\,\,\, vdW=βvdW+(1β)dW # d W dW dW的移动平均数.
                 v d b = β v d b + ( 1 − β ) d b \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,v_{db}=\beta v_{db}+\left( 1-\beta \right) db vdb=βvdb+(1β)db
                 W : = W − α v d W , b : = b − α v d b     \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,W:=W-\alpha v_{dW},b:=b-\alpha v_{db}\,\,\, W:=WαvdWb:=bαvdb #减缓梯度下降的幅度.

纵轴上的摆动平均值接近于零,所以在纵轴方向,希望放慢一点,平均过程中,正负数相互抵消,所以平均值接近于零。但在横轴方向,所有的微分都指向横轴方向,因此横轴方向的平均值仍然较大,因此用算法几次迭代后,动量梯度下降法最终纵轴方向的摆动变小了,横轴方向运动更快。

比喻:球在碗上向下滚动(最小化碗状函数)
d W dW dW, d b db db为加速度, v d W v_{dW} vdW, v d b v_{db} vdb为速度, β \beta β表现出一些摩擦力,所以球不会无限加速下去,球可以从碗向下加速,获得动量。也就是说,当前的速度是渐变的,而不是瞬变的,是动量的过程。这保证了梯度下降的平稳性和准确性,减少振荡,较快地达到最小值处。

超参数:学习率 α \alpha α以及参数 β \beta β,控制着指数加权平均数。 β \beta β最常用的值是0.9,平均了前十次迭代的梯度。

实际中,在使用梯度下降法或动量梯度下降法时,人们不会受到偏差修正的困扰。

v d W v_{dW} vdW d W dW dW维数相同, v d b v_{db} vdb d b db db维数相同。

另一版本: v d W = β v d W + d W v_{dW}=\beta v_{dW}+dW vdW=βvdW+dW v d W v_{dW} vdW缩小了 1 − β 1-\beta 1β倍, α \alpha α要根据 1 1 − β \frac{1}{1-\beta} 1β1相应变化,一般使用第一个版本(无删 1 − β 1-\beta 1β)。

RMSprop
RMSprop算法,全称是root mean square prop算法

假设纵轴代表参数 b b b,横轴代表参数 W W W,想减缓纵轴 b b b方向的摆动,同时加快横轴 W W W方向的学习速度

On iteration t:
         \,\,\,\,\,\,\,\, Compute d W , d b dW,db dW,db on current mini-batch
         S d W = β 2 S d W + ( 1 − β 2 ) d W 2 \,\,\,\,\,\,\,\,S_{dW}=\beta _2S_{dW}+\left( 1-\beta _2 \right) dW^2 SdW=β2SdW+(1β2)dW2,element-wise operation
         S d b = β 2 S d b + ( 1 − β 2 ) d b 2 \,\,\,\,\,\,\,\,S_{db}=\beta _2S_{db}+\left( 1-\beta _2 \right) db^2 Sdb=β2Sdb+(1β2)db2
         W : = W − α d W S d W + ε , b : = b − α d b S d b + ε , ε = 1 0 − 8 \,\,\,\,\,\,\,\,W:=W-\alpha \frac{dW}{\sqrt{S_{dW}}+\varepsilon},b:=b-\alpha \frac{db}{\sqrt{S_{db}}+\varepsilon},\varepsilon =10^{-8} W:=WαSdW +εdWb:=bαSdb +εdbε=108分母不为0

希望 S d W S_{dW} SdW会相对较小, S d b S_{db} Sdb较大,这样就可以减缓纵轴上的变化。

这些微分,垂直方向的要比水平方向的大得多,所以斜率在 b b b方向特别大,所以 d b db db较大, d W dW dW较小,因为函数的倾斜程度在纵轴上,也就是 b b b方向上要大于在横轴上,也就是W方向上。 d b 2 db^2 db2较大,所以 S d b S_{db} Sdb也会较大。

从图中可以看出,梯度下降(蓝色折线)在垂直方向 b b b上振荡较大,在水平方向 W W W上振荡较小,表示在 b b b方向上梯度较大,即 d b db db较大,而在 W W W方向上梯度较小,即 d W dW dW较小。因此, S b S_b Sb较大,而 S W S_W SW较小。在更新 W W W b b b的表达式中,变化值 d W S W \frac{dW}{\sqrt{S_W}} SW dW较大,而 d b S b \frac{db}{\sqrt{S_b}} Sb db较小。也就使得 W W W变化得多一些, b b b变化得少一些。即加快了 W W W方向的速度,减小了 b b b方向的速度,减小振荡,实现快速梯度下降算法(绿色折线)。

RMSprop的影响就是纵轴方向上摆动较小,而横轴方向继续推进。可以用一个更大学习率 α \alpha α,然后加快学习。

RMSprop的首次提出是在多年前Jeff Hinton的Coursera课程上。

Adam优化算法
Adam(Adaptive Moment Estimation)优化算法基本上就是将Momentum和RMSprop结合在一起。

v d W = 0 , S d W = 0 , v d b = 0 , S d b = 0 v_{dW}=0,S_{dW}=0,v_{db}=0,S_{db}=0 vdW=0SdW=0vdb=0Sdb=0
On iteration t:
         \,\,\,\,\,\,\,\, Compute d W , d b dW,db dW,db using current mini-batch
         v d W = β 1 v d W + ( 1 − β 1 ) d W , v d b = β 1 v d b + ( 1 − β 1 ) d b \,\,\,\,\,\,\,\,v_{dW}=\beta _1v_{dW}+\left( 1-\beta _1 \right) dW,v_{db}=\beta _1v_{db}+\left( 1-\beta _1 \right) db vdW=β1vdW+(1β1)dWvdb=β1vdb+(1β1)db
         S d W = β 2 S d W + ( 1 − β 2 ) d W 2 , S d b = β 2 S d b + ( 1 − β 2 ) d b 2 \,\,\,\,\,\,\,\,S_{dW}=\beta _2S_{dW}+\left( 1-\beta _2 \right) dW^2,S_{db}=\beta _2S_{db}+\left( 1-\beta _2 \right) db^2 SdW=β2SdW+(1β2)dW2Sdb=β2Sdb+(1β2)db2
         v d W c o r = v d W 1 − β 1 t , v d b c o r = v d b 1 − β 1 t \,\,\,\,\,\,\,\,v_{dW}^{cor}=\frac{v_{dW}}{1-\beta _{1}^{t}},v_{db}^{cor}=\frac{v_{db}}{1-\beta _{1}^{t}} vdWcor=1β1tvdWvdbcor=1β1tvdb
         S d W c o r = S d W 1 − β 2 t , S d b c o r = S d b 1 − β 2 t \,\,\,\,\,\,\,\,S_{dW}^{cor}=\frac{S_{dW}}{1-\beta _{2}^{t}},S_{db}^{cor}=\frac{S_{db}}{1-\beta _{2}^{t}} SdWcor=1β2tSdWSdbcor=1β2tSdb
         W : = W − α v d W c o r S d W c o r + ε , b : = b − α v d b c o r S d b c o r + ε \,\,\,\,\,\,\,\,W:=W-\alpha \frac{v_{dW}^{cor}}{\sqrt{S_{dW}^{cor}}+\varepsilon},b:=b-\alpha \frac{v_{db}^{cor}}{\sqrt{S_{db}^{cor}}+\varepsilon} W:=WαSdWcor +εvdWcorb:=bαSdbcor +εvdbcor

Adam算法是一种极其常用的学习算法,有效适用于不同神经网络,适用于广泛的结构。

α \alpha α:need to be tuned(调试)

β 1 = 0.9 \beta _1=0.9 β1=0.9,( d W dW dW) 第一矩

β 2 = 0.999 \beta _2=0.999 β2=0.999,( d W 2 dW^2 dW2) 第二矩

ε = 1 0 − 8 \varepsilon =10^{-8} ε=108

学习率衰减
加快学习算法的一个办法就是随时间慢慢减少学习率,称为学习率衰减。

使用mini-batch梯度下降法,(mini-batch大概64或128个样本),在迭代过程中会有噪音(蓝线),下降朝向这里的最小值,但是不会精确地收敛,所以算法最后在附近摆动,并不会真正收敛,因为用的 α \alpha α是固定值,不同的mini-batch中有噪音。

但是如果慢慢减少学习率,在初期的时候,学习率 α \alpha α还较大,学习相对较快,但随着 α \alpha α变小,步伐也会变慢变小,所以最后曲线(绿线)会在最小值附近的一小块区域里摆动,而不是在训练过程中大幅度在最小值附近摆动。

学习率衰减公式:
( 1 ) α = 1 1 + d e c a y _ r a t e ∗ e p o c h _ n u m α 0 \left( 1 \right) \alpha =\frac{1}{1+decay\_rate\ast epoch\_num}\alpha _0 (1)α=1+decay_rateepoch_num1α0

( 2 ) α = 0.9 5 e p o c h _ n u m α 0 \left( 2 \right) \alpha =0.95^{epoch\_num}\alpha _0 (2)α=0.95epoch_numα0,指数衰减

( 3 ) α = k e p o c h _ n u m α 0 \left( 3 \right) \alpha =\frac{k}{\sqrt{epoch\_num}}\alpha _0 (3)α=epoch_num kα0 (k为常数) 或者 α = k t α 0 \alpha =\frac{k}{\sqrt{t}}\alpha _0 α=t kα0 (t为mini-bach number)

( 4 ) \left( 4 \right) (4)一个离散下降的学习率,也就是某个步骤有某个学习率,一会之后,学习率减少了一半,一会儿减少一半,一会儿又一半,关于t的离散值,随着t增加, α \alpha α呈阶梯式减小。

( 5 ) \left( 5 \right) (5)手动衰减(模型数量小)。

局部最优问题
梯度下降法或者某个算法可能困在一个局部最优中,而不会抵达全局最优。

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

一个具有高维度空间的函数,如果梯度为0,那么在每个方向,它可能是凸函数,也可能是凹函数。

如果在2万维空间中,那么想要得到局部最优,所有的2万个方向都需要是这样,但发生的机率也许很小,也许是 2 − 20000 2^{-20000} 220000,更有可能遇到有些方向的曲线会向上弯曲,另一些方向曲线向下弯曲,而不是所有的都向上弯曲,因此在高维度空间,更可能碰到鞍点,而不会碰到局部最优点。

平稳段会减缓学习,平稳段是一块区域,其中导数长时间接近于0,在此处,梯度会从曲面从上向下下降,因为梯度等于或接近0,曲面很平坦,得花上很长时间慢慢抵达平稳段的这个saddle point,因为左边或右边的随机扰动,然后算法能够走出平稳段(红色笔),离开saddle point,继续前进。

  • 只要是训练较大的神经网络,存在大量参数,并且成本函数被定义在较高的维度空间,不太可能困在极差的局部最优中。
  • Plateaus可能会使梯度下降变慢,降低学习速度。

动量梯度下降,RMSprop,Adam算法都能有效解决plateaus下降过慢的问题,大大提高神经网络的学习速度。

超参数调试,batch正则化和程序框架(待更新)

调试处理

为超参数选择和适合范围

超参数训练的实践:Pandas vs. Caviar

网络中的正则化激活函数

将Batch Norm拟合进神经网络

为什么Batch Norm奏效?

测试时的Batch Norm

Softmax 回归

训练一个Softmax 分类器

深度学习框架

TensorFlow
针对Tensorflow2.0版本(对原视频的代码进行修改)
例子1

import numpy as np
import tensorflow.compat.v1 as tf   #tensorflow2.0
tf.disable_eager_execution()

w = tf.Variable(0,dtype=tf.float32)   #用tf.Variable定义参数,将w初始化为0,w是想要优化的参数,称为变量
cost = tf.add(tf.add(w**2,tf.multiply(-10.,w)),25)   #定义损失函数
train = tf.train.GradientDescentOptimizer(0.01).minimize(cost)
#定义train为学习算法,0.01为学习率,使用梯度下降法优化器使损失函数最小化
#下面是惯用表达
init = tf.global_variables_initializer()
session = tf.Session()   #开启了一个tensorflow session
session.run(init)        #初始化全局变量
print(session.run(w))    #让tensorflow评估一个变量w

session.run(train)      #运行一步梯度下降
print(session.run(w))   #评估一下w的值

for i in range(1000):   #运行梯度下降1000次迭代
    session.run(train)
print(session.run(w))   #结果接近5

例子2

coefficients = np.array([[1.],[-20.],[100.]])   #要接入x的数据,可改

w = tf.Variable(0,dtype=tf.float32)
x = tf.placeholder(tf.float32,[3,1])       #x为训练数据,把x定义为placeholder,[3,1]数组
                                           #placeholder告诉tensorflow稍后会为x提供数值
cost = x[0][0]*w**2 + x[1][0]*w + x[2][0]  #x变成控制这个二次函数系数的数据

train = tf.train.GradientDescentOptimizer(0.01).minimize(cost)

init = tf.global_variables_initializer()
with tf.Session() as session:
    session.run(init)
    print(session.run(w))
    session.run(train,feed_dict={x:coefficients})   #把系数数组接入变量x,把数据加入损失函数的句法
    print(session.run(w))
    for i in range(1000):
        session.run(train,feed_dict={x:coefficients})
    print(session.run(w))

结果:

改善深层神经网络编程作业

  • 初始化、正则化、梯度校验(1 & 2 & 3)
  • 优化算法实战
  • TensorFlow入门
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值