300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 吴恩达深度学习笔记——改善深层神经网络:超参数调整 正则化 最优化(Hyperparamet

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

时间:2024-02-05 19:26:34

相关推荐

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

深度学习笔记导航

前言传送门改善深层神经网络:超参数调整,正则化,最优化(Improving Deep Neural Networks: Hyperparameter Tuning, Regularization, and Optimization)深度学习实践(Practical Aspects of Deep Learning)基础数据集分割偏差/方差(bias/variance)基本分析方法正则化(regularization)L2正则化(L2 regularization)L2正则化降低过拟合的理解随机失活(Dropout Regularization)数据增广(data augmentation)提前终止(early stopping)加速归一化/标准化输入(normalizing training sets)梯度消失/爆炸的应对(vanishing/exploding gradient)梯度检验优化算法(Optimization Algorithms)Mini-batch gradient descent稳定波动的算法指数加权平均(exponentially weighted moving average)动量梯度下降(Gradient Descent with Momentum)RMSprop(root mean square prop)综合稳定方法:Adam(Adaptive Momentum Estimation)学习率衰减(learning rate decay)局部最优问题(local optima)超参数调优,批量归一化,框架(Hyperparameter tuning, Batch Normalization, and Programming Frameworks)基础知识超参数重要性直觉参数选点的组织方法(organize your search process)batch-normalization应用到单层上:应用到神经网络中:理解:应用到测试集上:soft-max regression与logistic regression的紧密联系符号约定概要训练过程由sigmoid推广到softmax激活函数深度学习框架

前言

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

这一章讲了关于优化神经网络的一系列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)

基础

数据集分割

训练集 train set

用来训练算法

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

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

测试集 test set

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

数据集划分比例

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

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

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

偏差/方差(bias/variance)

欠拟合/过拟合(under-fitting/over-fitting):

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

错误率(error):

字面意思

偏差(bias):

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

方差(variance):

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

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

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

基本分析方法

解决高偏差

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

解决高方差

regularization:正则化可以减少过拟合,抵消掉更大网络带来的过拟合。more data:最常用的,通常来说,方差大就是不够均匀,那我们只需要获取更多数据,就很容易解决均匀问题NN architecture search:最后的杀招

最终得到一个双低模型。一般来说,采用更多数据和更大网络可以更好的实现trade-off,

正则化(regularization)

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

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

常见范数公式

L2正则化(L2 regularization)

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

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

L2 Regularization

J(w,b)=1m∑i=1mL(y(i)^,y(i))+λ2m∣∣w∣∣2+λ2mb2J(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)=m1​i=1∑m​L(y(i)^​,y(i))+2mλ​∣∣w∣∣2​+2mλ​b2

理论上,b那一项不用写,因为和高维度的w比,b那一项没什么影响。

L1 Regularization

J(w,b)=原有项+λ2m∣∣w∣∣1J(w,b)=原有项+\dfrac{\lambda}{2m}||w||_1 J(w,b)=原有项+2mλ​∣∣w∣∣1​

L1的特点是,最后生成的w中0会多一些,有人说可以压缩模型体积,但是实际上体积没什么明显变化,所以目前主流还是采用L2

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

cost function的变化

J=原有项+λ2m∑i=1L∣∣W[i]∣∣FJ=原有项+\dfrac{\lambda}{2m}\sum_{\mathclap{i=1}}^{L}||W^{[i]}||_F J=原有项+2mλ​i=1∑L​∣∣W[i]∣∣F​

可以理解为加上所有元素的平方和根号

dW的变化

dW[i]=原有项+λmW[i]dW^{[i]}=原有项+\dfrac{\lambda}{m}W^{[i]} dW[i]=原有项+mλ​W[i]

形式上,F范数里是有平方项的,所以求个导把2分母消掉就好说。

W的更新

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

W[i]=W[i]−α[原有项+λmW[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]=(1−mλ​)W[i]−α原有项

从这个角度理解,相当于W在更新之前先进行了缩放,常被称作weight decay。不过吴恩达不喜欢这么叫,或许这么理解没什么用。

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

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

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

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

理解方式1

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

理解方式2

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

随机失活(Dropout Regularization)

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

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

步骤:

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])D[i]=np.random.rand(A[i].shape[0],A[i].shape[1])<keep_probA[i]∗=D[i]A^{[i]}*=D^{[i]}A[i]∗=D[i]A[i]/=A^{[i]}/=A[i]/=keep_prob

理解:

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

数据增广(data augmentation)

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

提前终止(early stopping)

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

优点:简单快速。

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

加速

归一化/标准化输入(normalizing training sets)

归一化均值

μn×1=1m∑i=1mX(i)\mu_{n\times 1} = \dfrac{1}{m}\sum_{\mathclap{i=1}}^mX^{(i)} μn×1​=m1​i=1∑m​X(i)

X−=μX-=\mu X−=μ

归一化方差

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

X/=σ2X/=\sqrt{\sigma^2} X/=σ2​

注意,通过训练集计算出的μ\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[i−1]就是大约标准化的,经过权重为1的W矩阵处理,Z[i]Z^{[i]}Z[i]仍然保持近似标准化的。

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

首先,假设var(W)=1nvar(W)=\dfrac{1}{n}var(W)=n1​

然后:

W[i]=np.random.randn(W[i].shape)∗np.sqrt(1ni−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(ni−11​)

方差选择

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

梯度检验

偏导的近似求法:

应该使用双边误差,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):

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

注意:

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

优化算法(Optimization Algorithms)

Mini-batch gradient descent

方法:

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

理解:

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

稳定波动的算法

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

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

在趋势预测中,我们要得出拟合线,拟合线的计算公式为:

vt=βvt−1+(1−β)θtv_t=\beta v_{t-1}+(1-\beta)\theta_t vt​=βvt−1​+(1−β)θt​

其中,v代表拟合值,θ\thetaθ代表样本值

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

我们可以这样理解:

可以很明显看出来这个公式具有记忆效应,对越近的样本记忆效应越强(权重大),越远的样本,就会被越多的β\betaβ作用,权重不断减少可以得出结论,β\betaβ越趋近于1,平均的样本就越多,曲线受当天的影响就越小,优点就是抗噪声,缺点就是呈现一种延迟(latency),对样本的适应性下降。从更数学的角度理解,我们把公式写完整了,会发现所有θ\thetaθ的系数之和为下式,整体是逼近1的,所以有类似加权过往所有样本的效果。

(1−β)∑i=0m−1βi=1−βm(1-\beta)\sum_{\mathclap{i=0}}^{m-1}\beta^i=1-\beta^m (1−β)i=0∑m−1​βi=1−βm从效果上说,实际上vtv_tvt​是大致相当于11−β\dfrac{1}{1-\beta}1−β1​,已知(1−ϵ)1ϵ=1e≈0.35(1-\epsilon)^{\dfrac{1}{\epsilon}}=\dfrac{1}{e}\approx 0.35(1−ϵ)ϵ1​=e1​≈0.35,也就是11−β\dfrac{1}{1-\beta}1−β1​个距离前的样本的效果只有不到当前样本的35%,所以可以认为均值主要由这几个样本贡献。

偏差修正:

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

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

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

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

具体执行:

我们使用vdW[i]v_{dW^{[i]}}vdW[i]​和vdB[i]v_{dB^{[i]}}vdB[i]​代替dW和dBdW和dBdW和dB,计算过程同指数加权平均。vdW=βvdW+(1−β)dWv_{dW}=\beta v_{dW}+(1-\beta)dWvdW​=βvdW​+(1−β)dW , vdB=βvdB+(1−β)dBv_{dB}=\beta v_{dB}+(1-\beta)dBvdB​=βvdB​+(1−β)dB

理解公式:

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

RMSprop(root mean square prop)

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

对每一次更新:

SdW=βSdW+(1−β)dW2;SdB=βSdB+(1−β)dB2S_{dW}=\beta S_{dW}+(1-\beta)dW^2 ; S_{dB}=\beta S_{dB}+(1-\beta)dB^2SdW​=βSdW​+(1−β)dW2;SdB​=βSdB​+(1−β)dB2W=W−αdWSdWW=W-\alpha\dfrac{dW}{\sqrt{S_{dW}}}W=W−αSdW​​dW​ ; B=B−αdBSdBB=B-\alpha\dfrac{dB}{\sqrt{S_{dB}}}B=B−αSdB​​dB​

理解:

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

偏差修正:

可能碰到的意外就是分母太小,所以可以选择W=W−αdWSdW+ϵW=W-\alpha\dfrac{dW}{\sqrt{S_{dW}}+\epsilon}W=W−αSdW​​+ϵdW​,ϵ\epsilonϵ的数量级可以在10−810^{-8}10−8,防止分母过小的情况。

综合稳定方法:Adam(Adaptive Momentum Estimation)

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

对t次mini-batch:

分别计算Momentum的v和RMSProp的s

vdW=β1vdW+(1−β1)dW,vdB=β1vdB+(1−β1)dBv_{dW}=\beta_1v_{dW}+(1-\beta_1)dW,v_{dB}=\beta_1v_{dB}+(1-\beta_1)dB vdW​=β1​vdW​+(1−β1​)dW,vdB​=β1​vdB​+(1−β1​)dB

sdW=β2sdW+(1−β2)dW2,sdB=β2sdB+(1−β2)dB2s_{dW}=\beta_2s_{dW}+(1-\beta_2)dW^2,s_{dB}=\beta_2s_{dB}+(1-\beta_2)dB^2 sdW​=β2​sdW​+(1−β2​)dW2,sdB​=β2​sdB​+(1−β2​)dB2分别修正v和s的偏差(可选)

vdWcorrect=vdW1−β1t,vdBcorrect=vdB1−β1tv_{dW}^{correct}=\dfrac{v_{dW}}{1-\beta_1^t},v_{dB}^{correct}=\dfrac{v_{dB}}{1-\beta_1^t} vdWcorrect​=1−β1t​vdW​​,vdBcorrect​=1−β1t​vdB​​

sdWcorrect=sdW1−β2t,sdBcorrect=sdB1−β2ts_{dW}^{correct}=\dfrac{s_{dW}}{1-\beta_2^t},s_{dB}^{correct}=\dfrac{s_{dB}}{1-\beta_2^t} sdWcorrect​=1−β2t​sdW​​,sdBcorrect​=1−β2t​sdB​​综合更新,修正0分母问题

W=W−αvdWcorrectsdWcorrect+ϵW=W-\alpha\dfrac{v_{dW}^{correct}}{\sqrt{s_{dW}^{correct}}+\epsilon} W=W−αsdWcorrect​​+ϵvdWcorrect​​

B=B−αvdBcorrectsdBcorrect+ϵB=B-\alpha\dfrac{v_{dB}^{correct}}{\sqrt{s_{dB}^{correct}}+\epsilon} B=B−αsdBcorrect​​+ϵvdBcorrect​​

可调节超参数:

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

学习率衰减(learning rate decay)

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

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

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

α=11+Decay−rate×Epoch−num×α0\alpha=\dfrac{1}{1+Decay-rate\times Epoch-num}\times \alpha_0α=1+Decay−rate×Epoch−num1​×α0​

此方法需要调节的超参数为α0,Decay−rate\alpha_0,Decay-rateα0​,Decay−rate

指数衰减(exponentially decay)

α=baseepoch−num×α0\alpha=base^{epoch-num}\times \alpha_0α=baseepoch−num×α0​

此方法需要调节的超参数为base,α0base,\alpha_0base,α0​

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

α=kepoch−num×α0\alpha=\dfrac{k}{\sqrt{epoch-num}}\times \alpha_0α=epoch−num​k​×α0​

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

α=discrete−staircase\alpha=discrete-staircaseα=discrete−staircase,使用一个离散的分段函数来搞定。

还有手动调节方法:

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

局部最优问题(local optima)

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

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

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

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

基础知识

超参数重要性直觉

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

第一梯队:

学习率α\alphaα

第二梯队:

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

第三梯队:

隐层数量 layers学习率衰减 learning rate decayAdam中的β1,beta2,ϵ\beta_1, beta_2, \epsilonβ1​,beta2​,ϵ,但是这个基本不用调

参数选点的组织方法(organize your search process)

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

有以下惯例(common practice):

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

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

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

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

比如:

α[0.0001,1]\alpha [0.0001,1]α[0.0001,1],我们用

[lg10−4,lg1][lg10^{-4},lg1][lg10−4,lg1] 的区间

代码实现就是r=−4∗np.random.rand()r=-4*np.random.rand()r=−4∗np.random.rand() α=10r\alpha=10^rα=10r

又比如:

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

最后,再加几条技巧:

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

batch-normalization

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

应用到单层上:

学术界也在争论是对A还是Z归一化,而实际上常用Z,有一点反直觉,毕竟我们认为A才是输入的。from i=1 to m:

对Z(i)Z^{(i)}Z(i),求均值以及方差具体点击这里查看,然后Znorm(i)=Z(i)−μσ2+ϵZ_{norm}^{(i)}=\dfrac{Z^{(i)}-\mu}{\sqrt{\sigma^2+\epsilon}}Znorm(i)​=σ2+ϵ​Z(i)−μ​,现在Znorm(i)已经是0均值1方差的了Z^{(i)}_{norm}已经是0均值1方差的了Znorm(i)​已经是0均值1方差的了from i=1 to m:

进一步定制化均值和方差,Z~(i)=γ∗Znorm(i)+β\tilde{Z}^{(i)}=\gamma *Z^{(i)}_{norm}+\betaZ~(i)=γ∗Znorm(i)​+β,其中γ是目标标准差,β\gamma是目标标准差,\betaγ是目标标准差,β是目标均值,从目前的观察来看,可以对不同层的不同节点进行定制

应用到神经网络中:

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

修改原有的Z计算步骤。Z[i]=W[i]Z[i]Z^{[i]}=W^{[i]}Z^{[i]}Z[i]=W[i]Z[i],$B^{[i]}可以去掉,因为后面是要重新指定均值的计算Z~[i]\tilde{Z}^{[i]}Z~[i]。使用Batch Norm计算,先计算归一化,再定制均值方差。Z[i]~=γ[i]∗Znorm[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​作用。反向传播。计算出dW,dγ,dβdW,d\gamma,d\betadW,dγ,dβ,可以直接用gradient descent来更新,也可以使用momentum,rms,adam来更新

理解:

就是参数空间变形,把所有参数归一化,可以使整体的参数空间尽量均匀。防止elongated情况出现。对每一层的输出强制性修改为目标方差和均值,起到稳定作用,来提高鲁棒性,适应性。由此,层与层之间的联系会减弱,前一层对后一层的影响下降,呈现一种轻微的独立性,独立学习,就学的更快了????(迷惑)这种隔离性会产生轻微regularization的副作用。但是请注意,我们的本意只是加速!对每一个mini-batch约束均值和方差,都会产生一点噪音。可以通过增大mini-batch size(也就是少弄点组)来减小正则化效果。其实就是这种约束的次数越少,自然噪音就越少。

应用到测试集上:

模型是归一化的,所以测试数据也要归一化,而且归一化的μ,γ\mu, \gammaμ,γ应该和训练集整体相符合,否则训练就没意义了。因为测试集是一个一个数据向量喂进去测试结果,所以不能对测试集求均值和方差,但是又不能对一个数据求,没意义,所以要估算。一般来说,最后的μ[i],γ[i]\mu^{[i]},\gamma^{[i]}μ[i],γ[i]估计值应该为所有mini-batch在该层的指数加权平均,这样也符合我们的第1点。至于为什么不用平均,具体我没有深究,指数加权肯定是比较省事。

soft-max regression

与logistic regression的紧密联系

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

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

符号约定

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

L(y,y^)=−∑j=1Cyilogyi^=−∑j=1CyilogaiL(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=1∑C​yi​logyi​^​=−j=1∑C​yi​logai​成本函数定义,同Logistic Regression,因为我们仅仅在垂直维度推广了,水平维度没有变化。

概要

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

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

训练过程

fp:

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

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

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

A[L]=tnp.sum(t,axis=(0,),keepdims=True)A^{[L]} = \dfrac{t}{np.sum(t,axis=(0,),keepdims=True)}A[L]=np.sum(t,axis=(0,),keepdims=True)t​

bp:

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

dZ[L]=Y^−Y=A[L]−YdZ^{[L]}=\hat{Y}-Y=A^{[L]}-YdZ[L]=Y^−Y=A[L]−Y实际上,如果使用深度学习框架,不需要具体来进行bp,你只需要专注于fp

由sigmoid推广到softmax激活函数

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

输入:

[z1z2=0]\begin{bmatrix} z_1 \\ z_2=0 \\ \end{bmatrix} [z1​z2​=0​]

输出:

[ez1ez1+ez2ez2ez1+ez2]\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​+ez2​ez1​​ez1​+ez2​ez2​​​⎦⎤​

化简得:

[11+e−z11−11+e−z1]=[sigmoid(z1)1−sigmoid(z1)]\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+e−z1​1​1−1+e−z1​1​​⎦⎤​=[sigmoid(z1​)1−sigmoid(z1​)​]

是不是一下就明了了。

深度学习框架

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

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

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

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

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

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。