李宏毅ML笔记10: DL小妙招

CNN的两个问题:

1. max pooling架构中用到的max无法微分,那在gradient descent的时候该如何处理?

2. L1 的Regression

DL的3步骤

1. define the function set(network structure)

2. goodness of function(loss function如cross entropy)

3. pick the best function(optimization如gradient descent)

得到一个neural network,接下来要如何改进?

结果表现不好改进方法

1、在training set上准确率不高:

         换激活函数:ReLU、Maxout

         自适应(adaptive)学习率:Adagrad、RMSProp、Momentum、Adam

2、在testing set上准确率不高:Early Stopping、Regularization、Dropout

目录

分析改进方向

检查训练集正确率

提高测试集上的正确率

结论

改善训练集结果

更换激活函数

梯度消失

ReLU

Maxout

自适应学习率

Adagrad

RMSProp

Momentum

Adam

改善测试集结果

早停

正则化

L2 正则化

L1 正则化

Dropout


分析改进方向

训练的流程:

DL三步训练完之后, 检查训练集结果,

训练集表现不好, 则回DL三步调整,

训练集表现好, 则看测试集结果,

测试集表现不好, 则解决过拟合, 解决过拟合过程中使训练集结果变差, 重回DL三步调整,

测试集训练集表现都好, 就成功了.

检查训练集正确率

先检查训练集上的表现是DL独特之处. deep learning虽然参数多,overfitting往往不会是第一个问题. 训练集结果不好时, 需要重新修改之前的步骤.

方法如k-nearest neighbor,decision tree在训练集上正确率100%,不必检查, 但容易overfitting.

提高测试集上的正确率

训练集表现很好后,把模型应用到测试集. 当训练集结果好,测试集结果不好, 为Overfitting.

解决overfitting问题时,可能会使训练集结果变坏, 需要回头检查,如果变坏,从头调整训练过程. 同时得到好结果即可.

不要看到测试集表现不好就认定overfitting

看testing data的图,横坐标是梯度下降更新次数,纵坐标则是error rate(越低说明model表现得越好),黄线表示20层神经网络,红色表示56层的神经网络.

56层网络的error rate高,表现较差,20层的表现较好,56层是overfitting吗?

这个问题要检查训练集表现, 神经网络在训练集结果:

20层本来就比56层表现更好,所以测试集结果不能说明56层overfitting.

神经网络在训练集表现不好的原因很多,如局部极小,鞍点(saddle point),高原点(plateau). 该56层神经网络压根没训练好.

广义上将训练集表现不好称为underfitting,但准确来说underfitting本意为模型复杂度不足,参数不够多,能力不足以解出这个问题;但该56层网络参数是比20层的多,不应该被称为underfitting,就只是没有训练好.

结论

看到DL中用到某种方法, 要思考其解决以下哪个问题:

1. 在训练集表现不够好

2. 在测试集表现不够好

如dropout只用在测试集结果不好时,训练集结果不好时不能用.

下面介绍训练集, 测试集两个问题优化方法.

改善训练集结果

更换激活函数

训练不好的原因可能是设计得不好, 如激活函数不合适,尝试更换.

sigmoid function作为激活函数,更深不一定结果更好. 图为在MNIST手写数字识别上的结果,层数增多, 精度持平,接着精度下降, 此时并非overfitting, 因为这张图就是训练集结果.

梯度消失

上面这个问题的原因不是overfitting,而是Vanishing Gradient(梯度消失):

Backpropagation用sigmoid function时, 当网络过深,靠近input的参数梯度(即对loss function的微分)较小;靠近output处梯度较大. 学习率不变,靠近输入的参数更新慢;靠近输出的参数更新快.

靠近输入的参数还几乎random,找到local minima,然后converge(收敛). 接着参数的loss下降的速度很慢,梯度接近0,基于random的参数收敛,模型参数没有训练充分.

梯度前小后大原因

某一个参数w对总损失l的偏微分,即梯度∂l/∂w,其含义为参数变化对损失值的影响:

$$ \frac{\partial l}{\partial w} \approx \frac{\mathrm{\Delta}l}{\mathrm{\Delta}w} $$

因此可以通过令第一层参数w加Δw,观察对loss(output和target差距)影响:

sigmoid function图像,把负无穷大到正无穷大之间的值都挤压到0~1之间,较大input处的增减对输出影响小.

Δw通过sigmoid function之后,输出变小,影响随层数(被sigmoid压缩次数)的递增而衰减.

即使值很大,每经过一个sigmoid function被缩小一次,越深衰减次数越多,对output影响小,也即input对loss的影响小,靠近input的weight对loss的梯度远小于靠近output的梯度.

解决方法

1. RBM,先训练第1层再训练第2层. Backpropagation时,尽管第一个layer没被训练到,但pre-train时已经训练好了.

2.改激活函数

ReLU

激活函数Rectified Linear Unit(整流线性单元函数,又称修正线性单元).

$$ \begin{equation} ReLU(x) = \begin{cases} x & if\ x> 0\\ 0 & if\ x\le 0 \end{cases} \end{equation}  $$

令z为输入,a为输出, 图像为:

ReLU优点:

1.运算比sigmoid function快很多

2. 生物理由(Biological reason)

3. 等同于无穷多个bias不同的sigmoid叠加(Infinite sigmoid with different biases)

4. 可以处理梯度消失

处理梯度消失

ReLU 作用在两个范围. 1. input>0激活函数是线性的;2. input<=0, output=0的神经元没有任何作用可以拿掉.

拿掉后网络变成瘦长的linear network,linear即output=input,不会出现激活函数使input产生的影响逐层递减的问题.

问题1: DL目标是构建non-linear、复杂的function. ReLU后变成linear function网络会变弱吗?

ReLU的network整体还是non-linear,当input改变没有导致神经元operation region改变,可看作linear function;当导致神经元operation region改变,output=0变为output=input,还是non-linear function.

问题2:对loss function梯度下降要求可微,但ReLU分段函数,不可微(在z=0点).

region处于z>0时,微分值(gradient)为1;当region处于z<0时,微分值(gradient)为0;很难出现z为0情况, 可设微分为0然后不用管它.

ReLU变形

1. Leaky ReLU: 当input<0的时候,output=0,此时微分值梯度也为0,无法更新参数,input<0的时候,微分后还应有一点点的值,令a=0.01z

2. Parametric ReLU: z的系数可以不固定,令a=α*z,系数作为网络参数,训练集梯度下降学得,每个neuron都可以有不同的值.

Maxout

ReLU可以看作Maxout的特例. Maxout让network自动学习激活函数(Learnable activation function),由training data决定.

所有方法通用的第一步: 给定input x1, x2,乘上几组不同的weight分别得到5,7,-1,1.

原方法直接输入不同神经元,通过激活函数后输出;

Maxout network将输入分组,比如5,7分一个group,然后在group里选最大值7作为output. 该过程类似Max Pooling,把原来几个神经元的输入组成group,不再加激活函数,直接选取最大值作为输出. 原神经元被合并看做一个新神经元,其input为原来几个“neuron”的input组成的vector,output则取input的最大值.

几个element被分为一个group作为网络中超参数要调.

Maxout -> RELU

Maxout可以模仿ReLU.

1. ReLU

ReLU的neuron输入x乘上weight w,加bias b,得到z, z输入激活函数ReLU,得输出a.

输入: z=wx+b为蓝线. 输出: a=z或a=0为绿线.

2. Maxout z1参数w和b与ReLU的参数一致,z2参数w和b全部设为0,然后做Max Pooling,选取z1 z2的较大值作为a.

神经元的输入为[z1, z2]. z1=wx+b为蓝线, z2=0为红线. 输出为max[z1, z2]绿线.

此时ReLU和Maxout输出相同,为相同激活函数.

Maxout -> More than ReLU

除了ReLU,Maxout还可以实现更多不同的激活函数

当z2参数w和b不是0,而是w' b'.

神经元的输入为[z1, z2]. z1=wx+b为蓝线, z2=w'x+b'为红线. 输出为max[z1, z2]绿线.

此时激活函数(绿线),由network参数决定,为Learnable Activation Function,形状可根据训练集生成

Maxout总结

Maxout为Learnable Activation Function.

可以实现任何piecewise linear convex activation function(分段线性凸激活函数);

其中激活函数分多少段(piece),取决于多少个element z放同一组.  

如何训练Maxout

需要解决Max不能微分的问题.

Maxout中圈出神经元output(即最大值).

此时Max operation为 linear operation,它仅接在group中一个element上,可把没有连接到的element去除,得到细长的linear network.

真正训练时网络并不含有max函数,而是一个化简后的linear network;没有开始训练时这个含有max函数无法微分,但只要丢进去了一笔data,形状确定转化为细长 linear network,可以根据这笔训练数据使用反向传播训练被network留下来的参数.

问题: 一次训练只涉及留下的那些参数,剩下被拿掉的参数?

也是理论上的问题,实际操作每个linear network结构由输入数据来决定的,数据不同structure不同,留下参数不同,network的structure不断变换,实际上每一个weight参数都会train到.

自适应学习率

Adaptive learning rate, 可参考之前的一篇笔记:

https://blog.csdn.net/lagoon_lala/article/details/116212939

Adagrad

更新公式:

$$ \left. w^{t + 1}\leftarrow w^{t} - \frac{\eta}{\sqrt{\sum_{i = 0}^{t}\left( g^{i} \right)^{2}}}g^{t} \right. $$

Adagrad将固定的学习率除以所有过去梯度值的平方和开根号:

$$ \sqrt{\sum_{i = 0}^{t}\left( g^{i} \right)^{2}} $$

考虑两个参数,如果给定方向上,平常梯度都比较小,说明比较平坦,给较大学习率;反之, 平常梯度大陡峭的,给较小学习率.

RMSProp

实际问题可能更复杂,线性回归优化(optimization)的对象,即loss function,是凸函数(convex);DL的loss function可以是任何形状.

对convex loss function, 每个方向的平坦或陡峭状态不变,只需要判断该方向整体的平坦陡峭情况. 但复杂情况中,即使是在同一个方向上(如w1方向),loss function一会儿平坦一会儿陡峭,要随时根据梯度快速地调整学习率.

DL用Adagrad不够,需要动态调整学习率, 升级为RMSProp.

RMSProp的做法:

学习率η为定值, 除以变化值σ,σ等于上一个σ和当前梯度g的加权方均根Root Mean Squares(在第一次更新时即为梯度值):

$$ \left. w^{1}\leftarrow w^{0} - \frac{\eta}{\sigma^{0}}g^{0},\sigma^{0} = g^{0} \right.\\ \left. w^{2}\leftarrow w^{1} - \frac{\eta}{\sigma^{1}}g^{1},\sigma^{1} = \sqrt{{\alpha\left( \sigma^{0} \right)}^{2} + \left( {1 - \alpha} \right)\left( g^{1} \right)^{2}} \right.\\ \left. w^{t + 1}\leftarrow w^{t} - \frac{\eta}{\sigma^{t}}g^{t},\sigma^{t} = \sqrt{{\alpha\left( \sigma^{t - 1} \right)}^{2} + \left( {1 - \alpha} \right)\left( g^{t} \right)^{2}} \right. $$

权重α作为超参数可以自由调整的(通常设0.9), RMSProp跟Adagrad不同之处在于,Adagrad的分母是对所有已知梯度取平方和开根号,考虑整个过程平均梯度信息;RMSProp虽然也含有所有梯度,用α调整不同梯度使用程度,α小则更倾向于新的梯度描绘的error surface平滑或陡峭程度,无视旧的梯度信息.

Momentum

解决卡在local minimum、saddle point或plateau问题.

出现local minima时必须在每个维度都是低谷形状,假设低谷出现的概率为p,由于参数较多(假设1000个), 每个参数位于低谷概率为,p^1000. 网络越复杂,参数越多,概率越低.

所以在大型神经网络没那么多的local minima,被卡住很有可能是接近global minima处.

Momentum灵感来自真实世界.

球从左上角滚下来,到plateau、local minima由于惯性会继续往前走一段, 有可能翻过山坡,走到比local minima还要好的地方. 惯性放入梯度下降即为Momentum.

普通的梯度下降是算一个梯度, 挪一次更新:

加上Momentum的更新方向,不只考虑梯度方向,还考虑上一次更新方向,用一个变量v去记录前一个时间点update的方向. 随机选一个初始点θ^0,v记录上次update(初始为0),接下来计算θ^0处的梯度,移动的方向是由上次移动方向v和梯度反方向-L来决定的,即:

$$ v^{1}~ = ~\lambda v^{0} - ~\eta\nabla L\left( \theta^{0} \right) $$

其中λ也是手动调整的参数,表示惯性对前进方向的影响有多大.

走第一步, 根据初始点计算的动量移动到θ1, 并计算θ1点的梯度和动量, 即第二个时间点要走的方向,绿色虚线,代表动量λv (惯性想要继续走的方向);红色虚线,代表负梯度-ηg;蓝色实线为两者矢量和, 即移动方向.

每一个时间点移动的步伐,包括大小和方向,是过去所有gradient的加权和.

由于的λ小于1,因此越早的梯度权重就越小.

在加入Momentum以后,每一次移动的方向,就是负梯度加上Momentum方向,Momentum其实就是上一个时间点的movement(移动).

图中,红色实线是负梯度方向,即坡度要走的方向;绿色虚线是Momentum方向,即上一次移动的方向;蓝色实线则是最终真正走的方向.

走到local minimum处梯度为0,红色箭头没有指向,Momentum绿色箭头,指向右侧(即之前是要走向右边),所以参数更新方向继续向右.  

Adam

RMSProp + Momentum=Adam

算法algorithm:

先初始化. m0是Momentum, 前一个时间点的movement. v0就是RMSProp里计算梯度的root mean square的σ. t表示时间点.

先算出梯度g_t.

根据动量和梯度,算出现在要走的方向m_t——Momentum思想

根据动量和梯度平方,算一下放在分母的v_t——RMSProp思想

接下来是RMSProp和Momentum里没有的,偏差修正(bias correction),m_t和v_t都除以一个值得m_t hat, v_t hat,这个值本来比较小,后来会越来越接近于1.

最后更新参数,把修正后的Momentum 乘学习率α,再除掉normalize的RMSProp后建议的学习率分母.

改善测试集结果

主要有三个方法Early Stopping、Regularization和Dropout. Early Stopping和Regularization是经典通用的做法;Dropout是DL特色做法.

早停

当学习率调得很好,随着训练的进行,训练集loss逐渐减小,在测试集上的loss先降后升.

理想上在测试集的loss最小的时候停下来,而不是训练集loss最小;但测试集未知, 用验证集替代.

正则化

regularization重新定义了要最小化的损失函数. 原本的loss增加一项正则项Regularization, “惩罚”复杂度高的模型.

L2 正则化

损失函数:

$$ L^{'}\left( \theta \right) = L\left( \theta \right) + \lambda\frac{1}{2}\left\| \theta \right\|_{2} $$

正则项为参数的L2 norm(L2范数),即参数集里的每一个参数平方和: 

$$ \left\| \theta \right\|_{2} = \left( w_{1} \right)^{2} + \left( w_{2} \right)^{2} + \ldots $$

通常正则项不考虑bias项,因为正则化目的是使function更平滑,bias与平滑程度没有关系.

正则项中的1/2是为了求微分方便而凑,梯度为对损失函数求微分:

$$ \frac{\partial L^{'}}{\partial w} = \frac{\partial L}{\partial w} + \lambda w $$

参数更新公式为:

$$ \begin{aligned}  w_{}^{t + 1} &\rightarrow w_{}^{t} - \eta\frac{\partial L^{'}}{\partial w} \\&= w_{}^{t} - \eta\left( {\frac{\partial L}{\partial w} + \lambda w_{}^{t}} \right) \\&= \left( {1 - \eta\lambda} \right)w_{}^{t} - \eta\frac{\partial L}{\partial w} \end{aligned}  $$

每次更新参数之前,都会乘(1-ηλ),而η和λ通常设为很小值,因此该因子接近于1,比如0.99, 即每次更新先把原参数减小点再说. 随着更新次数增加,即使原梯度(未加正则项)为0, 参数每次会减小一点. 即权重衰减Weight Decay.

问题: 参数会全变0?

不会, 最后微分项会和前面这一项取得平衡.

DL中正则化的重要性没有SVM这类方法高,Early Stopping减少更新次数,可类似地避免参数离0太远. SVM把正则化写在了objective function(目标函数)里面,SVM直接求解凸优化问题,无需迭代,用不上Early Stopping, 而是一步走到最好结果, 只能用正则化.

L1 正则化

L1正则在神经网络不常用,因为很难得到稀疏解而且算起来很复杂.

L1正则项每一个参数的绝对值累加,即:

$$ \left\| \theta \right\|_{1} = \left| w_{1} \right| + \left| w_{2} \right| + \ldots $$

损失函数:

$$ L^{'}\left( \theta \right) = L\left( \theta \right) + \lambda\frac{1}{2}\left\| \theta \right\|_{1} $$

绝对值不能微分怎么处理?

绝对值就是一个V字形的函数,左边微分值-1,右边微分值1,只有0不能微分的,真的0了就胡乱给它一个值,比如0,就好了. (参考广义函数里的弱导数)

w>0,微分为+1,w<0,微分为-1,故微分后可看作sgn function:

$$ \frac{\partial L^{'}}{\partial w} = \frac{\partial L}{\partial w} + \lambda{{sgn}\left( w \right)} $$

L1正则化更新公式:

$$ \begin{aligned} w_{}^{t + 1}&\rightarrow w_{}^{t} - \eta\frac{\partial L^{'}}{\partial w}\\ &= w_{}^{t} - \eta\left( {\frac{\partial L}{\partial w} + \lambda{\mathit{sgn}\left( w^{t} \right)}} \right)\\& = w_{}^{t} - \eta\frac{\partial L}{\partial w} - \eta\lambda{\mathit{sgn}\left( w^{t} \right)}\\& = \left( {1 - \eta\lambda} \right)w_{}^{t} - \eta\frac{\partial L}{\partial w} \end{aligned}  $$

更新参数时将固定减去一部分, 使参数绝对值更接近0.

L1 对比L2, 同样是让参数的绝对值变小,L1每次更新减掉一个值, L2乘上一个小于1的固定值. 当参数w的绝对值比较大的时候,L2让w下降得更快,当参数w的绝对值比较小的时候,L2下降慢. L1训练得参数是比较稀疏(sparse)的,即一些接近0,一些很大.

Dropout

训练

使用dropout方法训练, 每次update参数之前,对神经元(包括输入层不包括输出层)做sampling(抽样) ,每个neuron都有p%的几率被丢掉,跟它相连的weight也都要被丢掉.

sampling后,神经网络变细长了,然后训练该细长网络.

与maxout区别: Maxout是每一笔data对应的一种网络,而Dropout每一次更新的网络结构不同(一个minibatch对应一次update,一个minibatch含多笔data).

使用dropout后在训练集表现变差,在测试集上的结果变好.

如果训练集上表现都不好, 就不适合dropout.

测试

注意:

1. 测试的时候不做抽样,所有的neuron都要被用到.

2. 训练时dropout rate为p%,则所有weight要乘(1-p%)才能被当做测试的weight使用.

训练测试使用参数不一样原因:

假设现在的dropout rate是50%,训练时, 按照每次丢掉一半神经元的情况学习,测试时没有dropout,如果使用同一组weight,则得到输出是真实需要输出的2倍, 造成结果不match.

dropout理解

让一个神经网络里总是有队友会拖后腿dropout,其他神经元就更努力做,才能carry这个队友.

dropout是一种终极的ensemble的方法, ensemble指每次都只从训练集抽一部分数据训练.

bias和variance折衷时提过两种误差:

1. bias大(参数过少)

2. variance大(参数过多)

复杂模型往往是bias比较准,但variance很大. 很多个笨重复杂的model,虽然variance都很大,但最后平均起来,结果往往会很准.

ensemble利用这个特性,抽很多子集,训练很多model,每个结构不一样;测试时的数据通过所有的model,得到一大堆的结果, 把这些结果平均起来当做最后的output.

如果model很复杂,这一招往往有用,如random forest(随机森林)也实践这个精神,决策树很容易overfitting,random forest不会.

dropout与ensemble对比

dropout方法训练时, 每次拿一个minibatch出来就做一次update,对神经元进行sample,每个minibatch训练的network不同. 设神经元有M个,总共可能的网络数量有2^M个;相当于用很多个minibatch分别去训练很多个network(minibatch一般设100笔data),每个network都只用一个minibatch的data来train,可能会让人感到不安,才100笔data,但这些不同的network参数共享,同一个weight在不同的network里被不同的minibatch 训练, 它是拿所有这些network的minibatch合起来一起train的效果.

ensemble测试时,把训练好的一大把network通通拿出来,把所有network的结果平均起来得到输出. 但是在实际操作上,network实在太多了,每一个network都丢一个input运算量太大了. 用一个完整的network,weight由之前那一把network 训练, 对应weight乘(1-p%),测试时输出跟network分开考虑的ensemble输出相似.

如果训练的神经网络如下:

用不同的network structure做ensemble:

用一整个network训练时dropout,把weight乘上一个值而不做ensemble:

只有linear的network,dropout与ensemble等价,非线性不等价但也能改善其表现.

network接近linear时,dropout得到结果更好,如ReLU和Maxout. 所以常配合使用.

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值