深度学习的诀窍

1、简述

深度学习模型训练分成三部分:

  • Step1: define a set of function
  • goodness of function
  • pick the best function
    在这里插入图片描述

经过上面三步就可以得到一个训练好的neural network,测试训练好的模型在训练数据上的效果,因为深度学习不容易过拟合,所以在训练数据上一般很难达到100%的准确率。

如果训练好的neural network在训练数据上的效果不好,需要返回前面三部分进行分析,做什么样的修改能够使训练数据得到好的正确率。

如果在训练数据上的效果比较好,把模型放到测试数据上进行预测,查看预测结果。如果在训练数据上模型的性能比较好,但是在测试数据上性能比较差,说明模型过拟合,这时候需要返回前面三部分进行模型修改,然后重新对训练数据和测试数据进行模型性能验证。

2、当模型在测试数据上性能较差时不要总以为是过拟合

在这里插入图片描述

如图是模型在测试数据上的预测结果,横坐标是迭代次数,纵坐标是测试数据错误率,错误率越低越好。现在比较20层的network和56层的network,56层的模型的效果更差,而56层模型的参数更多,这是不是过拟合呢?我们需要比较模型在训练数据集上的效果。

从图中可以看到模型在训练数据上的错误率,20层模型的效果比56层的效果更好,这说明56层的模型在训练的时候就没有训练好。

那么可不可以理解为56层的模型是欠拟合呢?李宏毅老师觉得这不是欠拟合,李宏毅老师认为欠拟合是因为模型的参数不够多,模型的能力不足以解决问题。但是对于56层的neural network来说,虽然其模型性能较差,但是其参数比20层的neural network的参数更多,理论上来说,20层模型能做的事情56层的模型也能做,所以56层模型的性能比20层的模型性能差不是因为56层模型的能力差,所以这不是欠拟合,只是单纯地没有训练好。

3、深度学习提出的方法是应用在哪一方面的?

在深度学习文献中,当读到一个方法,要知道这个方法是要解决什么问题,因为在深度学习中有两个问题,一个是模型在训练数据集上效果比较差,另一个是模型在测试数据集上效果比较差,提出的方法往往是针对其中一个提出的。

举个例子,Dropout,Dropout是当测试数据不好时使用的,如果模型在训练数据上效果不好,在训练数据上使用dropout会导致越训练模型性能越差。

在这里插入图片描述

3.1 模型在训练数据上效果不好

3.1.1 更换激活函数——ReLU

如果模型在训练数据上效果不好,需要看看模型架构的设计是否不好,比如激活函数选择不对,选择更好的激活函数是否可以得到更好的结果。

以前比较常用的激活函数是sigmoid函数,通过实验可以知道,模型深度越深,模型的性能不一定越好。
在这里插入图片描述
如图为手写数字识别模型在训练集上的结果,当层数越来越多时,模型的性能逐渐下降。

导致模型性能下降的一个原因是梯度消失问题,当模型的层数叠地很深时,靠近输入的参数的梯度微分值很小,而靠近输出的参数的梯度微分值很大,当设定同样的学习率的时候,因为靠近输入的参数的梯度很小,所以更新值比较小,而靠近输出的参数的梯度比较大,所以对应位置的参数更新值比较大。这就可能导致当靠近输入端的参数基本没有得到优化,而靠近输出端的参数基本迭代到局部最优。
在这里插入图片描述
当迭代到一定程度,模型的loss会比较小,这时候我们会认为模型基本训练好了,但是靠近输入端的参数实际上还是基本没有优化。

这时候得到的模型效果是比较差的,因为靠近输入端的参数基本是随机的,所以输入数据乘于各种参数得到的输出基本也是随机的,所以最后的结果也是比较差的。我们可以从sigmoid的原理和BP知道为什么会发生梯度消失。

现在从直觉上理解为什么会发生梯度消失,怎么从直觉上知道一个参数的梯度是多少呢?假如想知道一个参数w对损失Cost的偏微分梯度 C w \frac{\partial C}{\partial w} ,直觉上理解,当当前参数做细微的变化 Δ w \Delta w 的时候,它对损失Cost的影响 Δ C o s t \Delta Cost 有多大,以此来知道该参数对损失Cost的影响。

在这里插入图片描述
如果参数w的变化 Δ w \Delta w 很大,通过sigmoid时输出会变小,从图中可以看出,输入的变化很大,输入的变化是比输入小的,是衰减的。每通过一次sigmoid就会衰减一次,所以当神经网络越深,衰减就越多,直到最后,参数w的变化 Δ w \Delta w 对输出的影响是非常小的。
在这里插入图片描述
那怎么解决这个问题呢?有一种想法是换一种激活函数可能就能解决这个问题。现在常用的激活函数是RELU(Rectified Linear Unit)。
在这里插入图片描述
选择这样的激活函数有几个好处,第一个好处是计算比较快,和sigmoid相比速度更快,第二个理由是ReLU是有生物上的性质的,第三个原因是ReLU等同是无穷多个sigmoid叠加的结果,第四个元素是ReLU可以解决梯度消失问题。

为什么ReLU可以解决梯度消失问题呢?下图是一个ReLU的神经网络,每一个神经元的激活函数都是ReLu的激活函数。
在这里插入图片描述
当输入大于0的时候,ReLU的输出等于输入;当输入小于0时,ReLU的输出等于0。所以现在ReLU函数作用在两个不同的区域。一个区域是神经元的输出为0,一个区域是神经元的输出等于输入,这时候激活函数相当于线性的。输出为0的神经元对整个神经网络是没有影响的,这时候可以把这些输出为0的神经元从网络中去除。
在这里插入图片描述
当把所有输出为零的神经元拿掉,剩下的神经元都是输入等于输出的神经元,整个网络就相当于瘦长的线性网络。sigmoid激活函数存在梯度消失是因为会把比较大的输入变为比较小的输出,这里是输出等于输入,所以不会有梯度消失问题。

这里有一个问题,当使用ReLU的时候,整个网络都是线性的,但是我们要的不是一个线性的网络,我们使用深度学习就是希望激活函数不是线性的,当我们使用ReLU的时候,神经网络不就变成一个线性网络了吗?这样子得到的神经网络没有问题吗?

首先我们需要先知道什么是线性网络,如果把线性网络看成一个大的矩阵M。那么输入样本A和B,则会经过同样的线性变换MA,MB(这里A和B经历的线性变换矩阵M是一样的)。

的确对于单一的样本A,经过由relu激活函数所构成神经网络,其过程确实可以等价是经过了一个线性变换M1,但是对于样本B,在经过同样的网络时,由于每个神经元是否激活(0或者Wx+b)与样本A经过时情形不同了(不同样本),因此B所经历的线性变换M2并不等于M1。因此,relu构成的神经网络虽然对每个样本都是线性变换,但是不同样本之间经历的线性变换M并不一样,所以整个样本空间在经过relu构成的网络时其实是经历了非线性变换的。

还有一种解释就是,不同样本的同一个feature,在通过relu构成的神经网络时,流经的路径不一样(relu激活值为0,则堵塞;激活值为本身,则通过),因此最终的输出空间其实是输入空间的非线性变换得来的。

也就是说对于每一个数据,对应的ReLU神经元的输出为0还是等于输入是不同的,这就增加了输入的非线性。

ReLU变种
ReLU在输入小于零的时候,输出等于0,这时候微分为零,没办法更新参数,可以让输入小于0的时候,输出不是零,而是一个较小的值,比如下图中的Leaky ReLU。
在这里插入图片描述

那为什么选择0.01呢,为什么不可以选择其它的值呢?所以又有人提出了Parqametric ReLU, α \alpha 是一个可训练参数。

除了ReLU这种形式的激活函数,能不能有其它类型的呢?所以又有人提出了Maxout,Maxout是让神经网络自动学习激活函数。因为激活函数是自动学习出来的,所以ReLU是Maxout的一种特例。Maxout可以学出ReLU,也可以学习到其它形式的激活函数。

假设现在有输入 [ x 1 , x 2 ] [x_1,x_2] ,通过神经网络得到四个输出值,传统情况下会对这四个神经元使用sigmoid或者ReLU激活函数,但是在Maxout中会将其group,然后输出同一个组中的最大值。
在这里插入图片描述

这个和CNN中的池化层效果感觉差不多,group的个数是通过训练得到的。Maxout是有办法做到和ReLU一样的事情,如下图所示。右图为Maxout,Maxout是选择两个直线中的较大值作为输出值,这样得到的函数和ReLU功能是一样的。
在这里插入图片描述
除了能够实现ReLu之外,Maxout能够实现更多类型的激活函数,比如下图所示:
在这里插入图片描述

3.1.2 自适应参数学习率

参数学习率对模型训练的结果好坏有很大的影响,如果学习率太大可能导致模型没办法收敛;如果学习率太小,则会导致模型需要更多的时间去训练。

在做深度学习的时候,很多时候会卡在局部最小,但名人曾经说过不用太担心局部最小的问题,在损失函数模型上不会有太多的局部最小,因为如果是局部最小,需要在每个参数上都是极小点,因为神经网络有非常多的参数,假设有1000个参数,每个参数都是局部最小值,假设每个参数都是局部最小值的概率为p,则所有参数都是局部最小的概率为 P 1000 P^{1000} 。神经网络越大,参数越多,局部极小出现的概率就越低。

对于模型的每个参数给定自适应学习率的方法有很多,现在常用的是Adam方法:
在这里插入图片描述

3.2 模型在测试数据上效果不好

有三种方法处理模型在测试数据上效果不好:

  1. 早停;
  2. 正则化;
  3. Dropout;

3.2.1 早停

在这里插入图片描述
如果学习率比较好,在训练数据集上的损失通常会越来越小。但是训练数据和测试数据的数据分布通常是不一样的,所以可能当训练数据的损失逐渐减小的时候,测试数据集的损失却会上升。

所以如果知道测试数据的损失变化,则应该在测试数据损失最小时停止训练:
在这里插入图片描述
但是现在我们没办法知道测试数据集的损失函数情况,所以我们需要用到验证集来确定什么时候停止训练。
在这里插入图片描述

3.2.2 正则化

L2正则化如下图所示:
在这里插入图片描述
在做正则化的时候一般是不考虑偏置项的,因为正则化的目的是模型更平滑,而bias偏置和模型的平滑程度是没有关系的,所以正则化的时候通常是不会考虑偏置项。

L2正则化的偏微分如下所示:
在这里插入图片描述

在深度学习中,正则化虽然有用,但是其重要性和传统方法比起来没有那么高,因为正则化和早停的效果差不多,目的都是使参数不会太极端。

3.2.3 Dropout

在训练的时候随机丢弃一些神经元,丢弃的概率为P,每一次训练忽略的神经元都是不同的。在测试的时候不使用Dropout,同时每个参数需要乘于(1-P)。
在这里插入图片描述