本博客是针对李宏毅教授在Youtube上上传的课程视频《ML Lecture 9-1:Tips for Training DNN》的学习笔记。
Recipe of Deep Learning
如下图:了解DL的三步骤;三步做完之后,获得一个NN,接着检查所得到的模型,根据检查的结果执行相应的措施。
对于DL来说,过拟合往往不是你首先会碰到的问题,反而是训练过程就很难得到满意的结果,即可能训练集上的准确率就一直很低。如果你在训练集上准确率很高了,但在测试集上准确率低,那才是过拟合。
所以,不要总是第一时间认为测试集上效果不好是因为过拟合!
生动的例子看下图:光看测试集上的表现,很多人会直觉地认为“哎哟,你看56层效果这么差,估计就是过拟合了,根本用不到那么多参数~~”。
可是,下结论之前,我们再看看这两个模型在训练集上的表现:
结果发现,56层的网络在训练集上表现也是比较差的,那么也就是说,56层的网络本身连训练都没做好,更别谈测试了!!!而造成这种现象的可能原因很多:
- 局部最小(local minima)
- 鞍点(saddle point)
- 停滞(plateau)
- ……
李老师同时也提出,这也不太可能是欠拟合问题,因为欠拟合一般是指模型的参数不够多,所以其能力不能解出这种问题。但是明明参数比56层网络少的20层网络也可以在训练集上达到更好的效果,所以不应该是欠拟合/模型的能力问题。
李老师提醒:读文献时,看到新方法时,要明白它是要解什么样的问题?一般DL要解决的问题就是训练集上的准确率和测试集上的准确率这两个问题,而新提出的方法也一般是针对这两个问题。
比如Dropout手段是用来提升模型在测试集上的准确率的,如果你是在训练集上准确率低,那用dropout就根本就是南辕北辙!所以请注意对症下药!
那么,针对两个典型DL问题,解决方法有哪些呢?见下图:
训练集上效果差?
换激活函数(New activation function)
例子:在MNIST上的网络,如果用sigmoid激活函数,则当层数越多时,效果反而越差!
有可能有人一看,就觉得“啊!9层10层参数太多,过拟合了!”
Naive!其实上图的线就是在训练集上的表现!(李老师随后用keras实际演示了一下)
原因:梯度弥散(Vanishing Gradient Problem):在靠近input的部分梯度较小,在远离input的地方,梯度较大。因此,靠近input的参数更新慢、收敛也慢,远离input的参数更新快、收敛得也很早。
为什么会有这个现象发生呢?
如果我们把BP算法的式子写出来,就会发现:用sigmoid作为激活函数就是会出现这样的问题。
直觉上想也可以理解:某个参数的下降梯度取决于损失函数对参数的偏导,而偏导的含义是:当该参数变化很小一点,对应的损失函数向相应变化的幅度。所以我们假设对第一层的某个参数加上△w,看它对损失函数值的影响。那么,当△w经过一层sigmoid函数激活时,它的影响就会衰减一次。(sigmoid会将负无穷到正无穷的值都压缩到(-1,1)区间)
于是,怎么解决这个问题呢:换一个不会逐层消除掉增量的激活函数,比如ReLU.
而且除了解决梯度弥散问题,ReLU含有其它的好处:
- 计算速度快
- 生物学层面的理由
等同于无穷多层的偏差不同的sigmoid函数叠加的结果
那ReLU具体怎么解决梯度弥散问题呢?
如下图,假设图中网络的激活函数都是ReLU。而网络中必然有一些神经元对应的输出会是0,它们对于网络的贡献也是零,故可以逻辑上直接从网络中删除,这样我们就获得了一个“更瘦长”的线性网络(输出等于输入)。
而之前说梯度递减也是因为sigmoid的衰减效果,而我们现在用ReLU它本身不会对增量进行递减,因为现在凡是在网络中work的神经元,其输出都等于其输入,相当于线性函数y=x。
问题:如果网络都用ReLU了,网络变成了线性的了?那NN的效果不会变得很差吗?这与我们使用深层网络的初衷不是违背了吗?
答:其实使用ReLU的NN整体还是非线性的。当每个神经元的操作域(operation region)是想相同的时,它是线性的。即当你对input只做小小的改变,不改变神经元的操作域,那NN就是线性的;但如果对input做比较大的改变,改变了神经元的操作域,这样NN就是非线性的了。
另外一个问题:ReLU不能微分呀?怎么做梯度下降呀?
答:当x>0时,ReLU微分就是1,当x<0时,ReLU微分就是0。而x的值一般不太可能恰好是0,所以不在意x=0时的微分值也没问题。
ReLU的变形
原本的ReLU在参数小于0时,因为梯度等于0,就停止了更新。为了让参数保持更新,可以适当改变ReLU在负轴的形态。(leaky ReLU, Parametric ReLU)
有没有ReLU以外的好的激活函数形式:Maxout(ReLU是maxout的一种特例)
Maxout如何做到和ReLU一样的效果?
如下:Maxout也可以超越ReLU:Learnable Activation Function
Maxout的激活函数可以是任意分片线性凸函数,分片数量取决于将多少个元素分为一组:
问题:Maxout网络怎么训练?
其实Maxout网络因为是从group里面选取值最大的元素,那么那些未被选中的neuron的贡献就可以看做是0,可以拿掉。那么Maxout也就称为一种类似于线性的激活函数(直接将输入值输出)。所以我们直接训练拿掉了未被选中的neuron后的”瘦长“网络就可以。
另外,不用担心这样会造成那些为被选中的neuron的参数无法被训练到,因为其实你每次输入的训练数据不同时,被选中的neuron也不同,所以终究而言,所有的neuron都是能被训练到的。
自适应学习率(Adaptive Learning Rate)
Adagrad
有会变化的学习率,变化的方式是每次的原本学习率除以过去所有更新所用的梯度的平方和的算术平方根,用公式表达如下: