吴恩达深度学习笔记——改善深层神经网络:超参数调整,正则化,最优化(Hyperparameter Tuning)

2023-11-18

深度学习笔记导航

前言

本系列文章是吴恩达深度学习攻城狮系列课程的笔记,分为五部分。

这一章讲了关于优化神经网络的一系列trick,注重实践,否则会忘掉。

我的笔记不同于一般的笔记,我的笔记更加凝练,除了结论以及公式,更多的是对知识的理解,结合课程可以加速理解,省去很多时间,但是请注意,笔记不能替代课程,应该结合使用。

传送门

结构化机器学习项目,我建议放在最后看。

首先学这一节对你后面的学习没有影响,我就是跳过去学的。而且他更多的讲的是策略,尤其是举了很多后面的例子,你听了不仅不太好懂,而且没啥意思,所以我建议放在最后看。

神经网络与深度学习(Neural Networks and Deep Learning)

改善深层神经网络:超参数调整,正则化,最优化(Hyperparameter Tuning)

卷积神经网络(Convolutional Neural Networks)

序列模型与循环神经网络(Sequence Models)

结构化机器学习项目(Structuring Machine Learning Projects)

改善深层神经网络:超参数调整,正则化,最优化(Improving Deep Neural Networks: Hyperparameter Tuning, Regularization, and Optimization)

深度学习实践(Practical Aspects of Deep Learning)

基础

数据集分割
  1. 训练集 train set

用来训练算法

  1. 开发集 dev set(hold-out cross validation)

调整参数,选择特征,以及对学习算法做出其他决定

  1. 测试集 test set

从开发集中选出最优的几个模型在测试集上进行评估

  1. 数据集划分比例

以前数据量小的时候,是622分,但是当数据量变大,dev set和test set的增长没有那么快,所以后面这两个的比例会缩小,比如98 1 1的比例

一般小样本会习惯于7的训练3的测试,但是实际上严格来说,开发和测试是不可以混为一谈的,其两者的目的不一样

目前的理解也仅限于此,至于dev和test的区别,网上的总结千篇一律,都是抄吴恩达的讲义,我还需要后面进一步在实践中感悟。

偏差/方差(bias/variance)
  1. 欠拟合/过拟合(under-fitting/over-fitting):

欠拟合就是没把大头当回事,过拟合就是将偶然太当真。欠拟合准确率不够,过拟合不具有普遍适应性。

  1. 错误率(error):

字面意思

  1. 偏差(bias):

模型对测试集的准确率高,则偏差低

  1. 方差(variance):

模型在测试集和开发集上的差距小,则方差低。为什么叫方差呢?因为同一个模型,两个集上差距不大,说明两个集本身的差距就不大,均匀分布,就是方差小。还可以体现出模型是否过拟合,过拟合会加大方差。

  1. 最优误差/基本误差(base error):

一般来说,默认0,这是假设人工识别准确率极高。如果这个是15%,那么在训练集上16%的错误率就是很完美的拟合。毕竟,机器的效果是要和人对比的,人不行,机器也没必要做到极致。

基本分析方法
  1. 解决高偏差

    • 这是首要的,先降低bias
    • Bigger Network:最常用的,模型够复杂,拟合的就可以够好
    • Longer Training:训练更久
    • advanced optimization algorithm:换优化算法
    • NN architecture search:换架构
  2. 解决高方差

    • regularization:正则化可以减少过拟合,抵消掉更大网络带来的过拟合。
    • more data:最常用的,通常来说,方差大就是不够均匀,那我们只需要获取更多数据,就很容易解决均匀问题
    • NN architecture search:最后的杀招
  3. 最终得到一个双低模型。一般来说,采用更多数据和更大网络可以更好的实现trade-off,

正则化(regularization)

说白了,正则化就是减弱联系,制造干扰,来提高抗干扰行。

这里要用到范数,所以可以参考这篇文章

常见范数公式

L2正则化(L2 regularization)

正则化是对J(cost function)下手的,进而影响到反向传播中的参数调整过程。

Logistic Regression,我们可以采用L2和L1

  1. L2 Regularization

J ( w , b ) = 1 m ∑ i = 1 m L ( y ( i ) ^ , y ( i ) ) + λ 2 m ∣ ∣ w ∣ ∣ 2 + λ 2 m b 2 J(w,b)=\dfrac{1}{m}\sum_{\mathclap{i=1}}^{m}L(\hat{y^{(i)}},y^{(i)})+\dfrac{\lambda}{2m}||w||_2+\dfrac{\lambda}{2m}b^2 J(w,b)=m1i=1mL(y(i)^,y(i))+2mλ∣∣w2+2mλb2
理论上,b那一项不用写,因为和高维度的w比,b那一项没什么影响。

  1. L1 Regularization

J ( w , b ) = 原有项 + λ 2 m ∣ ∣ w ∣ ∣ 1 J(w,b)=原有项+\dfrac{\lambda}{2m}||w||_1 J(w,b)=原有项+2mλ∣∣w1
L1的特点是,最后生成的w中0会多一些,有人说可以压缩模型体积,但是实际上体积没什么明显变化,所以目前主流还是采用L2

深层神经网络中,就直接用L2了,但是需要注意的是,L2并不是用2范数,而是用Frobenius范数,就一种arcane的玄学原因导致明明是2范数的特征却使用Frobenius范数的名称

  1. cost function的变化

J = 原有项 + λ 2 m ∑ i = 1 L ∣ ∣ W [ i ] ∣ ∣ F J=原有项+\dfrac{\lambda}{2m}\sum_{\mathclap{i=1}}^{L}||W^{[i]}||_F J=原有项+2mλi=1L∣∣W[i]F
可以理解为加上所有元素的平方和根号

  1. dW的变化

d W [ i ] = 原有项 + λ m W [ i ] dW^{[i]}=原有项+\dfrac{\lambda}{m}W^{[i]} dW[i]=原有项+mλW[i]
形式上,F范数里是有平方项的,所以求个导把2分母消掉就好说。

  1. W的更新

仍然是用原有的公式,但是因为dW变化,所以W更新公式可以重写:

W [ i ] = W [ i ] − α [ 原有项 + λ m W [ i ] ] W^{[i]}=W^{[i]}-\alpha [原有项+\dfrac{\lambda}{m}W^{[i]}] W[i]=W[i]α[原有项+mλW[i]]

W [ i ] = ( 1 − λ m ) W [ i ] − α 原有项 W^{[i]}=(1-\dfrac{\lambda}{m})W^{[i]}-\alpha 原有项 W[i]=(1mλ)W[i]α原有项
从这个角度理解,相当于W在更新之前先进行了缩放,常被称作weight decay。不过吴恩达不喜欢这么叫,或许这么理解没什么用。

L2正则化降低过拟合的理解

从效果上来说,L2正则化的效果是将W的权值缩小。正则化参数 λ \lambda λ 越大,W的权值下降的更快,而且越小。

而且,即使是新增了一项,从效果上来说,新的J函数依然凸的,依然随着迭代次数的增加而monotonically减少。

反过来说,如果你使用正则化计算方法但是画图的时候还是用的旧的cost function,那你的函数图可能就不是单调的了。

  1. 理解方式1

当W的权值减少,那么部分神经元的效果就会打折扣,效果上相当于收缩了神经网络的规模。随着收缩,逐渐从过拟合转移到欠拟合高偏差状态,最后就变成了Logistic Regression。

  1. 理解方式2

当W权值减小,那么Z的值也会小,那么无论是ReLU还是sigmoid或者tanh函数,0附近的是g函数近似于线性的,前面也说过,如果一个神经网络都是线性的,那么就会被简化,所以这种理解方式其实也是从简化神经网络的角度理解的。

随机失活(Dropout Regularization)

思想:随机让一部分神经元失效,生成一个简化的子神经网络。

常用方法:反向随机失活(inverted dropout)

步骤:

  1. D [ i ] = n p . r a n d o m . r a n d ( A [ i ] . s h a p e [ 0 ] , A [ i ] . s h a p e [ 1 ] ) D^{[i]}=np.random.rand(A^{[i]}.shape[0],A^{[i]}.shape[1]) D[i]=np.random.rand(A[i].shape[0],A[i].shape[1])<keep_prob
  2. A [ i ] ∗ = D [ i ] A^{[i]}*=D^{[i]} A[i]=D[i]
  3. A [ i ] / = A^{[i]}/= A[i]/=keep_prob

理解:

  1. 生成一个矩阵,决定我们要把哪些输出元素毙掉,然后将输出元素毙掉,最后放大其他元素来保持Z的范数期望不变。
  2. 直到现在,我仍然搞不明白如何毙掉一个神经元,按我的理解,应该是先算出A,然后 A ∗ = d A*=d A=d这个时候d是一个列向量,利用广播特性,一次性毙掉一行,实现毙掉神经元的操作。然而实际上只是随机毙掉元素。或许我们可以从另一个角度理解,对不同的样本,
  3. 注意测试集里不要这样干,因为我们已经有一个泛化的模型了,不需要继续泛化。
  4. 每次迭代,都会随机毙掉一些元素,所以可以避免两个神经元之间有紧密的联系,让模型的适应性更强。
  5. 不同层之间也可以选择不同的keep_prob参数来控制drop的比例
  6. dropout尤其适用于小样本情况,这种情况往往会出现过拟合。比如CNN。
  7. 缺点就是,bp和cost function会变得模糊,所以在打开drop开关之前先确保cost function是单调递减的。
数据增广(data augmentation)

将数据进行轻微改变,比如翻转之类的,制造类似的数据,可以实现类似于正则化的效果,减弱过拟合。

提前终止(early stopping)

将J函数和dev error画在一个图上,然后在要发生过拟合的附近终止训练即可。

优点:简单快速。

缺点:无法发挥出其他工具的力量,试图使用一个方法同时降低bias和variance,难以取得极致的效果。

加速

归一化/标准化输入(normalizing training sets)
  1. 归一化均值

μ n × 1 = 1 m ∑ i = 1 m X ( i ) \mu_{n\times 1} = \dfrac{1}{m}\sum_{\mathclap{i=1}}^mX^{(i)} μn×1=m1i=1mX(i)
X − = μ X-=\mu X=μ

  1. 归一化方差

σ n × 1 2 = 1 m ∑ i = 1 m X ( i ) ∗ ∗ 2 \sigma^2_{n\times 1}=\dfrac{1}{m}\sum_{\mathclap{i=1}}^mX^{(i)}**2 σn×12=m1i=1mX(i)2
X / = σ 2 X/=\sqrt{\sigma^2} X/=σ2

  1. 注意,通过训练集计算出的 μ \mu μ σ \sigma σ要直接用在测试集上,不要用测试集自己算 μ \mu μ σ \sigma σ,因为我们对数据集总体做出的处理应该是统一的。

理解:

经过实验可以观察出:归一化后,即使是相差比较悬殊的维度,最后的范围也会相近,最多只是几倍的差距。如果不归一化,正常情况的cost function是一个狭长的(elongated)碗,对于狭窄维,需要定很小的步长来保证尽量收敛。

如果归一化,就可以选择尽量大的步长,学习率。

点击跳转batch-normalization

梯度消失/爆炸的应对(vanishing/exploding gradient)

之前说过最后的结果是类似于W矩阵的累乘,那么在深度学习中很明显会产生一种指数效应,W的整体权小于1就会产生梯度消失,大于1会产生梯度爆炸,拖慢训练速度。所以我们要让W的初值权重大约为1附近

引理:如果输入特征 A [ i − 1 ] A^{[i-1]} A[i1]就是大约标准化的,经过权重为1的W矩阵处理, Z [ i ] Z^{[i]} Z[i]仍然保持近似标准化的。

常用方法是进一步特殊地初始化W矩阵,不仅要更趋近于0,而且要自适应样本数量。

首先,假设 v a r ( W ) = 1 n var(W)=\dfrac{1}{n} var(W)=n1

然后:
W [ i ] = n p . r a n d o m . r a n d n ( W [ i ] . s h a p e ) ∗ n p . s q r t ( 1 n i − 1 ) W^{[i]}=np.random.randn(W^{[i]}.shape)*np.sqrt(\dfrac{1}{n^{{i-1}}}) W[i]=np.random.randn(W[i].shape)np.sqrt(ni11)

方差选择

  1. 如果g=ReLU,那么使用 v a r ( W ) = 2 n var(W)=\dfrac{2}{n} var(W)=n2会更好
  2. Xavier初始化:如果是sigmoid或者tanh,使用 1 n \dfrac{1}{n} n1或者 2 n [ i − 1 ] + n [ i ] \dfrac{2}{n^{[i-1]}+n^{[i]}} n[i1]+n[i]2
  3. 方差也可以作为超参数调整,前面加一个乘子,但是优先级比较低。

梯度检验

偏导的近似求法:

应该使用双边误差, f ′ ( θ ) = f ( θ + ϵ ) − f ( θ − ϵ ) 2 ϵ f^\prime(\theta)=\dfrac{f(\theta+\epsilon)-f(\theta-\epsilon)}{2\epsilon} f(θ)=2ϵf(θ+ϵ)f(θϵ)

其误差为 O ( ϵ 2 ) O(\epsilon^2) O(ϵ2)比单边误差的 O ( ϵ ) O(\epsilon) O(ϵ)要小很多

求解过程(Grad Check):

  1. 将所有W,B,dW,dB,reshape为两个向量, θ , d θ \theta, d\theta θ,dθ
  2. 对每一个元素,进行双边误差计算偏导,最后形成一个向量 d θ a p p r o x d\theta_{approx} dθapprox
  3. 比较 d θ d\theta dθ d θ a p p r o x d\theta_{approx} dθapprox ∣ ∣ d θ − d θ a p p r o x ∣ ∣ 2 ∣ ∣ d θ ∣ ∣ 2 + ∣ ∣ d θ a p p r o x ∣ ∣ 2 < 1 0 − 7 \dfrac{||d\theta-d\theta_{approx}||_2}{||d\theta||_2+||d\theta_{approx}||_2}<10^{-7} ∣∣dθ2+∣∣dθapprox2∣∣dθdθapprox2<107是理想情况,-5就要多看一眼,-3必然是有突出的误差,需要去仔细寻找。

注意:

  1. 只有在debug中才需要使用,在训练的时候加入grad checking会极大地拖慢速度。
  2. 发现问题后寻找是那一个下标出现了问题,然后从下标反推是那一层出现了问题。
  3. 如果使用了正则化,你的J要变化。
  4. grad check不可以和dropout同时打开,仅仅是dropout就让cost function难以计算,因为要求和,但是你并不知道是哪些部分被丢弃了。
  5. 这是一种意外情况,假设W和B的理想值是0附近,然后初始化也是0附近,但是随着迭代,W和B越来越大。这个时候就先检查一下再初始化,后训练再检查。

优化算法(Optimization Algorithms)

Mini-batch gradient descent

方法:

  1. 将X分割为若干个Mini-batch,用 { 大括号上标 } 来区分不同的batch, X { t } , Y { t } , J { t } X^{\{t\}},Y^{\{t\}},J^{\{t\}} X{t},Y{t},J{t}
  2. 进行while循环训练,每一次迭代,都要遍历所有batch,每一个batch都进行一次W和B的调整,所以从效果上来说,曾经一次迭代只能调整一次W和B,现在可以调整若干次。
  3. 从此以后,iteration和一次mini-batch对应,epoch和mini-batch的总体对应。

理解:

  1. 相当于牺牲一点准确度,去换取快速的前进。因此,对每一个batch,他的图像 J { t } J^{\{t\}} J{t}并不是单调的,而是伴随着噪声趋势向下,这是因为其他batch在这次迭代中也会干扰W和B,但是总的方向应该正确。可以通过减少 α \alpha α来改善(ameliorate)噪声。
  2. 要选择适当的mini-batch size。
  3. 选择m,虽然方向总是正确,也充分利用了向量化,但是调整次数太少,单次迭代太慢。
  4. 如果选择1,则变成随机梯度下降,stochastic gradient descent不会收敛,只会oscillate在最值附近。而且,在提升每一次迭代的调整次数的同时,也会降低向量化的程度,不见得就比m快。
  5. 所以应该选择1-m之间作为mini-batch size,去平衡向量化和调整次数的平衡。
  6. 还需要注意的是,size最好为 2 n 2^n 2n,这是为了适应CPU-GPU的内存。

稳定波动的算法

指数加权平均(exponentially weighted moving average)

说白了,指数加权平均就是牺牲一点精准度来快速计算平均值。

在趋势预测中,我们要得出拟合线,拟合线的计算公式为:
v t = β v t − 1 + ( 1 − β ) θ t v_t=\beta v_{t-1}+(1-\beta)\theta_t vt=βvt1+(1β)θt
其中,v代表拟合值, θ \theta θ代表样本值

具体执行就是对v不断更新覆盖,如果想记录可以用一个列表来记录。这样求平均比直接求效率高很多,是一种替代方法。

我们可以这样理解:

  1. 可以很明显看出来这个公式具有记忆效应,对越近的样本记忆效应越强(权重大),越远的样本,就会被越多的 β \beta β作用,权重不断减少
  2. 可以得出结论, β \beta β越趋近于1,平均的样本就越多,曲线受当天的影响就越小,优点就是抗噪声,缺点就是呈现一种延迟(latency),对样本的适应性下降。
  3. 从更数学的角度理解,我们把公式写完整了,会发现所有 θ \theta θ的系数之和为下式,整体是逼近1的,所以有类似加权过往所有样本的效果。
    ( 1 − β ) ∑ i = 0 m − 1 β i = 1 − β m (1-\beta)\sum_{\mathclap{i=0}}^{m-1}\beta^i=1-\beta^m (1β)i=0m1βi=1βm
  4. 从效果上说,实际上 v t v_t vt是大致相当于 1 1 − β \dfrac{1}{1-\beta} 1β1,已知 ( 1 − ϵ ) 1 ϵ = 1 e ≈ 0.35 (1-\epsilon)^{\dfrac{1}{\epsilon}}=\dfrac{1}{e}\approx 0.35 (1ϵ)ϵ1=e10.35,也就是 1 1 − β \dfrac{1}{1-\beta} 1β1个距离前的样本的效果只有不到当前样本的35%,所以可以认为均值主要由这几个样本贡献。

偏差修正:

在初期求平均时,因为前面没有积累,会造成结果远低于真实值的偏差,这个时候就可以使用 v t = v t 1 − β t v_t=\dfrac{v_t}{1-\beta^t} vt=1βtvt来修正,天数越少,放大效应越明显。

最终,原来的线会收敛到修正线上。

动量梯度下降(Gradient Descent with Momentum)

实际上,无论是batch还是mini-batch,梯度下降的方向并不总是最好的方向,存在着非最优方向的波动,这限制了我们对学习率的加大。反过来说,如果能保持接近正确的方向,就意味着我们可以加大学习率。

具体执行:

  1. 我们使用 v d W [ i ] v_{dW^{[i]}} vdW[i] v d B [ i ] v_{dB^{[i]}} vdB[i]代替 d W 和 d B dW和dB dWdB,计算过程同指数加权平均。
  2. v d W = β v d W + ( 1 − β ) d W v_{dW}=\beta v_{dW}+(1-\beta)dW vdW=βvdW+(1β)dW , v d B = β v d B + ( 1 − β ) d B v_{dB}=\beta v_{dB}+(1-\beta)dB vdB=βvdB+(1β)dB

理解公式:

  1. 核心就在指数加权平均上,第一项可以理解为一种动量,第二项可以理解为冲量,冲量会对动量造成影响,但是因为动量的束缚,不会彻底改变方向。
  2. 可调超参数为 α , β \alpha,\beta α,β,当我们选择了合适的 β \beta β来降低了波动,保持正确方向,就可以提高学习率来加速
RMSprop(root mean square prop)

这同样是用来稳定方向的。

对每一次更新:

  1. S d W = β S d W + ( 1 − β ) d W 2 ; S d B = β S d B + ( 1 − β ) d B 2 S_{dW}=\beta S_{dW}+(1-\beta)dW^2 ; S_{dB}=\beta S_{dB}+(1-\beta)dB^2 SdW=βSdW+(1β)dW2;SdB=βSdB+(1β)dB2
  2. W = W − α d W S d W W=W-\alpha\dfrac{dW}{\sqrt{S_{dW}}} W=WαSdW dW ; B = B − α d B S d B B=B-\alpha\dfrac{dB}{\sqrt{S_{dB}}} B=BαSdB dB

理解:

  1. 首先 S d W S_{dW} SdW从数量级上是平方级别的,所以后面要加根号
  2. 假设 S d W S_{dW} SdW大,那么代表波动大,然后作用到分母上,就把大的变小。同理,小的就会变大,这样就变相的把大小给平衡了。从效果上,感觉就像是把一个长条碗变成了一个圆碗。
  3. 之后就可以使用更大的学习率了。

偏差修正:

  1. 可能碰到的意外就是分母太小,所以可以选择 W = W − α d W S d W + ϵ W=W-\alpha\dfrac{dW}{\sqrt{S_{dW}}+\epsilon} W=WαSdW +ϵdW ϵ \epsilon ϵ的数量级可以在 1 0 − 8 10^{-8} 108,防止分母过小的情况。
综合稳定方法:Adam(Adaptive Momentum Estimation)

综合Momentum和RMSProp,以及两种方法的修正,一种广泛适用且有效的优化算法Adam诞生了。

对t次mini-batch:

  1. 分别计算Momentum的v和RMSProp的s
    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}+(1-\beta_1)dW,v_{dB}=\beta_1v_{dB}+(1-\beta_1)dB vdW=β1vdW+(1β1)dW,vdB=β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}+(1-\beta_2)dW^2,s_{dB}=\beta_2s_{dB}+(1-\beta_2)dB^2 sdW=β2sdW+(1β2)dW2,sdB=β2sdB+(1β2)dB2
  2. 分别修正v和s的偏差(可选)
    v d W c o r r e c t = v d W 1 − β 1 t , v d B c o r r e c t = v d B 1 − β 1 t v_{dW}^{correct}=\dfrac{v_{dW}}{1-\beta_1^t},v_{dB}^{correct}=\dfrac{v_{dB}}{1-\beta_1^t} vdWcorrect=1β1tvdW,vdBcorrect=1β1tvdB
    s d W c o r r e c t = s d W 1 − β 2 t , s d B c o r r e c t = s d B 1 − β 2 t s_{dW}^{correct}=\dfrac{s_{dW}}{1-\beta_2^t},s_{dB}^{correct}=\dfrac{s_{dB}}{1-\beta_2^t} sdWcorrect=1β2tsdW,sdBcorrect=1β2tsdB
  3. 综合更新,修正0分母问题
    W = W − α v d W c o r r e c t s d W c o r r e c t + ϵ W=W-\alpha\dfrac{v_{dW}^{correct}}{\sqrt{s_{dW}^{correct}}+\epsilon} W=WαsdWcorrect +ϵvdWcorrect
    B = B − α v d B c o r r e c t s d B c o r r e c t + ϵ B=B-\alpha\dfrac{v_{dB}^{correct}}{\sqrt{s_{dB}^{correct}}+\epsilon} B=BαsdBcorrect +ϵvdBcorrect

可调节超参数:

  1. α \alpha α是最常调节的
  2. β 1 \beta_1 β1默认为0.9
  3. β 2 \beta_2 β2默认为0.999
  4. ϵ \epsilon ϵ默认为 1 0 − 8 10^{-8} 108

学习率衰减(learning rate decay)

为了最后的收敛(converge),在最后阶段学习率不能太大。但是并不意味着在初始阶段学习率就不能大。理论上,刚开始大后面小是最佳选择。

使得初期快速向最低点迈进,后期快速收敛。

随epoch减少的各种实现方法:

  1. α = 1 1 + D e c a y − r a t e × E p o c h − n u m × α 0 \alpha=\dfrac{1}{1+Decay-rate\times Epoch-num}\times \alpha_0 α=1+Decayrate×Epochnum1×α0


    此方法需要调节的超参数为 α 0 , D e c a y − r a t e \alpha_0,Decay-rate α0,Decayrate

  2. 指数衰减(exponentially decay)

    α = b a s e e p o c h − n u m × α 0 \alpha=base^{epoch-num}\times \alpha_0 α=baseepochnum×α0

    此方法需要调节的超参数为 b a s e , α 0 base,\alpha_0 baseα0

  3. 还有其他各种方法,总之就是一个随着epoch-num增加而递减的系数。

    α = k e p o c h − n u m × α 0 \alpha=\dfrac{k}{\sqrt{epoch-num}}\times \alpha_0 α=epochnum k×α0


    α = k t × α 0 \alpha=\dfrac{k}{\sqrt{t}}\times \alpha_0 α=t k×α0


    α = d i s c r e t e − s t a i r c a s e \alpha=discrete-staircase α=discretestaircase,使用一个离散的分段函数来搞定。

还有手动调节方法:

就是你盯着你的模型,如果发现慢了,就自己调一下,有很多人在这么干,但是如果同时训练太多模型,这种方式就不实用了。

局部最优问题(local optima)

曾经人们担心出现大量的局部最优点,因为在二维空间上很容易产生。

但是实际上二维空间的直觉并不总是适应高维空间,比如20000维的空间,要让所有维度都是凸函数,可能性为 2 − 20000 ≈ 0 2^{-20000}\approx 0 2200000,也就是说,非全局最优点以外,导数为0的点,在高位空间大多是鞍点(saddle point)。

虽然不会造成局部最优问题,但是鞍点的平稳段(plateaus)仍然会造成学习缓慢的问题,所以优化算法就是用来加速来解决学习缓慢的问题的。

超参数调优,批量归一化,框架(Hyperparameter tuning, Batch Normalization, and Programming Frameworks)

基础知识

超参数重要性直觉

一般来说,超参数虽然多,但是也有个主次,以下是顺序

第一梯队:

  1. 学习率 α \alpha α

第二梯队:

  1. 动量系数 β \beta β
  2. 子集尺寸 mini-batch size
  3. 隐层神经元个数 hidden units

第三梯队:

  1. 隐层数量 layers
  2. 学习率衰减 learning rate decay
  3. Adam中的 β 1 , b e t a 2 , ϵ \beta_1, beta_2, \epsilon β1,beta2,ϵ,但是这个基本不用调
参数选点的组织方法(organize your search process)

首先就是有一个参数空间,维数和超参数数量相同。

有以下惯例(common practice):

  1. 在合适的范围内随机选点。 因为参数太多,所以网格化枚举选点不合适。
  2. 逐步缩小搜索区域(coarse to fine search)。

其他技巧——非均匀选点:

一般来说,均匀选点是可以应付的。

但有时候,靠近0的要取得密集一点,也就是灵敏性会发生变化。这种时候就应该先进行线性变换,然后取对数,再均匀随机取点,最后用指数变回去,实现非均匀化,从一端到另一端逐渐稀疏。

比如:

α [ 0.0001 , 1 ] \alpha [0.0001,1] α[0.0001,1],我们用
[ l g 1 0 − 4 , l g 1 ] [lg10^{-4},lg1] [lg104,lg1] 的区间
代码实现就是 r = − 4 ∗ n p . r a n d o m . r a n d ( ) r=-4*np.random.rand() r=4np.random.rand() α = 1 0 r \alpha=10^r α=10r

又比如:

β [ 0.9 , 0.999 ] \beta [0.9,0.999] β[0.9,0.999],然后对我们来说, 1 1 − β \dfrac{1}{1-\beta} 1β1才是重要的。取不取倒数对于均匀分布不影响,所以我们这里直接用 1 − β 1-\beta 1β,即 r ∈ [ − 3 , − 1 ] , 1 − β = 1 0 r r \in [-3,-1],1-\beta=10^r r[3,1],1β=10r 。从这个案例可以看出,用1做个减法就可以实现密集端的互换。

最后,再加几条技巧:

  1. 隔几个月就重新测试或者评估超参数。
  2. pandas训练法(穷人法):如果数据过多或者资源不够,一次只能训练少量模型,一个模型训练个几天,可以选择盯着随时改(babysit)
  3. caviar训练法(土豪法):计算资源充足,就可以同时(parallel)训练多个模型,把cost function同时画在一个图上,选择最好的

batch-normalization

这是logistic regression归一化的深层版本batch-normalization可以让参数优化变得更加容易,神经网络更鲁棒。

应用到单层上:
  1. 学术界也在争论是对A还是Z归一化,而实际上常用Z,有一点反直觉,毕竟我们认为A才是输入的。
  2. from i=1 to m:
    Z ( i ) Z^{(i)} Z(i),求均值以及方差具体点击这里查看,然后 Z n o r m ( i ) = Z ( i ) − μ σ 2 + ϵ Z_{norm}^{(i)}=\dfrac{Z^{(i)}-\mu}{\sqrt{\sigma^2+\epsilon}} Znorm(i)=σ2+ϵ Z(i)μ,现在 Z n o r m ( i ) 已经是 0 均值 1 方差的了 Z^{(i)}_{norm}已经是0均值1方差的了 Znorm(i)已经是0均值1方差的了
  3. from i=1 to m:
    进一步定制化均值和方差, Z ~ ( i ) = γ ∗ Z n o r m ( i ) + β \tilde{Z}^{(i)}=\gamma *Z^{(i)}_{norm}+\beta Z~(i)=γZnorm(i)+β,其中 γ 是目标标准差, β \gamma是目标标准差,\beta γ是目标标准差,β是目标均值,从目前的观察来看,可以对不同层的不同节点进行定制
应用到神经网络中:

通常和mini-batch一起使用,对iteration t:

  1. 修改原有的Z计算步骤。 Z [ i ] = W [ i ] Z [ i ] Z^{[i]}=W^{[i]}Z^{[i]} Z[i]=W[i]Z[i],$B^{[i]}可以去掉,因为后面是要重新指定均值的
  2. 计算 Z ~ [ i ] \tilde{Z}^{[i]} Z~[i]。使用Batch Norm计算,先计算归一化,再定制均值方差。 Z [ i ] ~ = γ [ i ] ∗ Z n o r m [ i ] + β [ i ] \tilde{Z^{[i]}}=\gamma^{[i]}*Z^{[i]}_{norm}+\beta^{[i]} Z[i]~=γ[i]Znorm[i]+β[i],注意,我们这个是element-wise计算,并且广播,可以看到,一个神经元(一行)会被一个 γ i 和 β i \gamma_i和\beta_i γiβi作用。
  3. 反向传播。计算出 d W , d γ , d β dW,d\gamma,d\beta dW,dγ,dβ,可以直接用gradient descent来更新,也可以使用momentum,rms,adam来更新
理解:
  1. 就是参数空间变形,把所有参数归一化,可以使整体的参数空间尽量均匀。防止elongated情况出现。
  2. 对每一层的输出强制性修改为目标方差和均值,起到稳定作用,来提高鲁棒性,适应性。
  3. 由此,层与层之间的联系会减弱,前一层对后一层的影响下降,呈现一种轻微的独立性,独立学习,就学的更快了????(迷惑)
  4. 这种隔离性会产生轻微regularization的副作用。但是请注意,我们的本意只是加速!对每一个mini-batch约束均值和方差,都会产生一点噪音。可以通过增大mini-batch size(也就是少弄点组)来减小正则化效果。其实就是这种约束的次数越少,自然噪音就越少。
应用到测试集上:
  1. 模型是归一化的,所以测试数据也要归一化,而且归一化的 μ , γ \mu, \gamma μ,γ应该和训练集整体相符合,否则训练就没意义了。
  2. 因为测试集是一个一个数据向量喂进去测试结果,所以不能对测试集求均值和方差,但是又不能对一个数据求,没意义,所以要估算。
  3. 一般来说,最后的 μ [ i ] , γ [ i ] \mu^{[i]},\gamma^{[i]} μ[i],γ[i]估计值应该为所有mini-batch在该层的指数加权平均,这样也符合我们的第1点。至于为什么不用平均,具体我没有深究,指数加权肯定是比较省事。

soft-max regression

与logistic regression的紧密联系

结果不止两种,这种判断叫soft-max regression。

实际上,softmax是logistic彻头彻尾的推广。激活函数的算法都是sigmoid的推广。(具体细节在最后)

符号约定
  1. C=classes:种类总数
  2. 维度发生变化,垂直方向扩展 Y C × m Y_{C\times m} YC×m
  3. 损失函数定义:实际上就是Logistic regression的推广,C=2的时候,就是logistic regression的形式。

    L ( y , y ^ ) = − ∑ j = 1 C y i l o g y i ^ = − ∑ j = 1 C y i l o g a i L(y,\hat{y})=-\sum_{\mathclap{j=1}}^Cy_i log\hat{y_i}=-\sum_{\mathclap{j=1}}^Cy_i log a_i L(y,y^)=j=1Cyilogyi^=j=1Cyilogai
  4. 成本函数定义,同Logistic Regression,因为我们仅仅在垂直维度推广了,水平维度没有变化。
概要

类比logistic regression,我们把输出层的sigmoid单节点层换成soft-max层,神经元个数由1变为C,激活函数使用其他的。

  1. soft-max函数也可以作为激活函数,sigmoid只不过是把1分为2种情况,而soft-max将1分为多种情况
  2. 具体表现为,原来的 y ^ 1 × m \hat{y}_{1\times m} y^1×m变成了 y ^ C × m \hat{y}_{C\times m} y^C×m,每一行代表种类,每一列之和都是1,每一个元素代表概率
  3. 实际上这就是logistic regression的推广(generalize),之所以Logistic Regression不用2高度,只是因为两种情况下有一个就好了。
训练过程

fp:

只需要推广最后一层的激活函数即可, g [ L ] 如下 g^{[L]}如下 g[L]如下:

  1. 先指数作用,保持概率大于0:

    t = e Z [ L ] t=e^{Z^{[L]}} t=eZ[L]
  2. 求和+在广播机制下求0维度占比:

    A [ L ] = t n p . s u m ( t , a x i s = ( 0 , ) , k e e p d i m s = T r u e ) A^{[L]} = \dfrac{t}{np.sum(t,axis=(0,),keepdims=True)} A[L]=np.sum(t,axis=(0,),keepdims=True)t

bp:

  1. 这是非常神奇的一点,形式竟然没有变化:(这其实就是在暗示你我们的激活函数也是sigmoid的推广!)

    d Z [ L ] = Y ^ − Y = A [ L ] − Y dZ^{[L]}=\hat{Y}-Y=A^{[L]}-Y dZ[L]=Y^Y=A[L]Y
  2. 实际上,如果使用深度学习框架,不需要具体来进行bp,你只需要专注于fp
由sigmoid推广到softmax激活函数

令C=2,然后用一个样本实验。之所以用 z 2 = 0 z_2=0 z2=0是因为sigmoid的单样本实际上只接收一个特征。

输入:
[ z 1 z 2 = 0 ] \begin{bmatrix} z_1 \\ z_2=0 \\ \end{bmatrix} [z1z2=0]

输出:
[ e z 1 e z 1 + e z 2 e z 2 e z 1 + e z 2 ] \begin{bmatrix} \dfrac{e^{z_1}}{e^{z_1}+e^{z_2}} \\ \\ \dfrac{e^{z_2}}{e^{z_1}+e^{z_2}}\\ \end{bmatrix} ez1+ez2ez1ez1+ez2ez2

化简得:
[ 1 1 + e − z 1 1 − 1 1 + e − z 1 ] = [ s i g m o i d ( z 1 ) 1 − s i g m o i d ( z 1 ) ] \begin{bmatrix} \dfrac{1}{1+e^{-z_1}} \\ \\ 1-\dfrac{1}{1+e^{-z_1}} \\ \end{bmatrix} = \begin{bmatrix} sigmoid(z_1) \\ 1-sigmoid(z_1) \\ \end{bmatrix} 1+ez1111+ez11 =[sigmoid(z1)1sigmoid(z1)]

是不是一下就明了了。

深度学习框架

之前我们都是白手起家(from scratch)的,现在为了提高效率,我们要使用框架了。

框架的核心在于使用计算图实现链式法则的自动求导,解放双手,让数据科学家能够专注于fp,而bp这种机械的工作交给机器。

存在即合理,现在大量的框架都在高速发展,所以吴恩达没有强烈推荐(endorse)某一个框架,只是给出了评选标准(criteria):

  1. 易于编程是首要的。以及便于迭代和部署(deploying)
  2. 速度,也是硬性要求。
  3. 真正地开放,即长期保持开源。不仅仅是开源,而且最好管理好,否则可能出现后期公司逐渐私有化的情况。
  4. 其他的就是语言接口,应用领域。

如果非要提出几个,其实无非就是两个,tensorflow和pytorch,一个工业,一个学术。具体用法也不必举出,涉及的东西比较多,需要独立搜索。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

吴恩达深度学习笔记——改善深层神经网络:超参数调整,正则化,最优化(Hyperparameter Tuning) 的相关文章

  • 一次内核hung task分析

    http blog chinaunix net uid 14528823 id 4406510 html 1 内核hung task检测机制由来 我们知道进程等待IO时 经常处于D状态 即TASK UNINTERRUPTIBLE状态 处于这
  • python读取csv中所遇到的中文编码问题

    由于本人准备学习使用一些机器学习算法 第一个是DecisionTree 然后使用到了西瓜案例 因为涉及到讨厌的编码问题 所以找了好多办法去尝试读取csv文件 1 pandas pandas可谓是神奇 用python学习机器学习不可缺少的一个

随机推荐

  • 如何解决WIN10中,进入本地组策略时出现“命名空间已经被定义为存储中另一文件的目标命名空间”

    1 首先 怎么打开组策略 win R gpedit msc 回车 2 当打开组策略时出现如下的提示 当然关闭后还是可以正常使用的 只是如何去掉该提示呢 3 解决办法 引起该问题的原因就是提示的C WINDOWS PolicyDefiniti
  • Linux脚本启动jar包

    这里主要为shell脚本启动部署在服务器中jar包 bin bash 这里可替换为你自己的执行程序 其他代码无需更改 APP NAME demo jar 使用说明 用来提示输入参数 usage echo Usage sh demo sh s
  • Android上层与驱动交互完整篇(二)Hal层篇

    Android上层与驱动交互完整篇 二 Hal层篇 上篇写了I2C驱动如何来编写 但是驱动里并没有交代如何具体的跟设备通信 现在我们在hal层实现这部分逻辑代码 HAL全称Hardware Abstract Layer 硬件抽象层 它向下屏
  • 基于改进二进制粒子群算法的电力系统机组组合——复现

    目录 文章摘要 研究背景 二进制粒子群算法 代码运行效果 本文代码分享 文章摘要 提出了1种改进的BS0 二进制粒子群 方法求解机组组合问题 首先 利用优先顺序法确定初始的机组组合 根据这个结果 确定优化窗口的范围 在此范围内利用BPSO进
  • WebLogic-执行队列

    一 Tuning the Application Server 二 执行队列 Using Work Managers to Optimize Scheduled WorkThis chapter describes how WebLogic
  • K-近邻算法

    一 K 近邻算法 1 介绍 K 近邻算法 K Nearest Neighbor 又叫KNN算法 指如果一个样本在特征空间中的k个最相似的样本中的大多数属于某一个类别 则该样本也属于这个类别 也就是对于新输入的实例 从数据集中找到于该实例最邻
  • Ubuntu:停掉某个网络

    ifconfig 网口名 down 例子如下 ifconfig docker0 down
  • 163_omnicore升级后无法连接

    qq群里转载的 最近由于omnicore要升级 每个要升级的人都在问rpc怎么连不了了 这里统一回复下 1 为什么连不了 这是bitcoin0 18 0更改了rpcallowip自动侦听的功能 必须使用rpcbind指定要侦听的ip 2 怎
  • 约瑟夫问题详解

    约瑟夫问题 有n个人 编号为1 n 从第一个人开始报数 从1开始报 报到m的人会死掉 然后从第m 1个人开始 重复以上过程 在死了n 1个人后 问最后一个人的编号是 暴力 题目传送门 暴力都想不到就真是让人折服了 暴力的话大模拟即可 不是重
  • 列表转链表+链表合并

    列表转链表 思路 生成一个头节点 current指向该节点 再生成新节点 给该节点赋值val 更新current位置 依次类推 class ListNode object def int self val 0 next None self
  • 腾讯28-整数反转

    腾讯28 整数反转leetcode7 给出一个 32 位的有符号整数 你需要将这个整数中每位上的数字进行反转 示例 1 输入 123 输出 321 示例 2 输入 123 输出 321 示例 3 输入 120 输出 21 注意 假设我们的环
  • mac xmind

    1 首先要安装包 XMind For Mac 本人下载的这个版本xmind8update9 2 下载破解包 XMindCrack jar 链接 https pan baidu com s 1jqpodMvKQTNQyenAIy0Y3w 密码
  • vue反向代理解决跨域及部署nginx端口转发解决跨域

    1 前言 本文是为了解决vue反向代理解决跨域及部署服务器nginx端口转发解决跨域 因为踩了不少的坑 百度了很多 也试了太多的方法 最终得以解决 所以记录一下 希望遇到同样问题的友友们可以高效的解决自己项目中遇到的问题 2 为什么会出现跨
  • 自写控件:滑动呈现控件(实现了两个以上控件间的切换)师傅的

    public class NavigatePanel Panel public enum Direction LeftToRight RightToLeft private NavigateArgs mArgs Navigate参数 pri
  • JS基础,从JS的组成到JS函数写法

    一 计算机的组成 计算机 软件 硬件 输入设备 输出设备 CPU 硬盘 内存 二 JS的组成 1 ECMAScript 是由ECMA国际 原欧洲计算机制造商协会 进行标准化的一门编程语言 这种语言在万维网上应用广泛 它往往被称为JavaSc
  • Selenium定位页面元素的方法

    一 Selenium定位页面元素的方法 selenium提供如下强大的定位元素的方法 id id name name dom javascriptExpression xpath xpathExpression link textPatte
  • java 基础重学(五)-底层-JVM

    1 JVM JVM内存结构 class 文件格式 运行时数据区 堆和栈的区别 java中对象一定在堆上分配吗 java 内存模型 计算机内存模型 缓存一致性 MESI协议 原子性 可见性 顺序性 happens before 内存屏蔽 sy
  • 刷题day65:分割等和子集

    题意描述 给你一个 只包含正整数 的 非空 数组 nums 请你判断是否可以将这个数组分割成两个子集 使得两个子集的元素和相等 思路 使用01背包 背包的体积为sum 2 背包要放入的商品 集合里的元素 重量为 元素的数值 价值也为元素的数
  • 解决qemu虚拟机图形界面卡死问题

    1 基础环境 Virtio gpu双heads 4 9 0内核 xserver1 9 3 modesettings0 5 0驱动 2 问题描述 终端中打开大量文字内容 不停上下滑动 或cat大量内容的文件 操作过程中用户界面卡死 如下 3
  • 吴恩达深度学习笔记——改善深层神经网络:超参数调整,正则化,最优化(Hyperparameter Tuning)

    深度学习笔记导航 前言 传送门 改善深层神经网络 超参数调整 正则化 最优化 Improving Deep Neural Networks Hyperparameter Tuning Regularization and Optimizat