理论知识:
一、Perception algorithm感知器算法,英文wiki:
感知机是生物神经细胞的简单抽象。神经细胞结构大致可分为:树突、突触、细胞体及轴突。单个神经细胞可被视为一种只有两种状态的机器——激动时为‘是’,而未激动时为‘否’。神经细胞的状态取决于从其它的神经细胞收到的输入信号量,及突触的强度(抑制或加强)。当信号量总和超过了某个阈值时,细胞体就会激动,产生电脉冲。电脉冲沿着轴突并通过突触传递到其它神经元。为了模拟神经细胞行为,与之对应的感知机基础概念被提出,如权量(突触)、偏置(阈值)及激活函数(细胞体)。
这个结构,被称为perceptron感知机,被视为一种最简单形式的前馈神经网络,是一种二元线性分类器。
感知器使用特征向量来表示的前馈神经网络,它是一种二元分类器,把矩阵上的输入x(实数值向量)映射到输出值f(x)上(一个二元的值)。
perceptron.png
perceptrons.png
像以上这个f(x)的function是最基本的fuction,叫step function,能很明显的看到在零处是不衔接的,如下图:
step_func.png
(那个if x<0是0哦)
所以跟前面的那部分组合,看为一个整体,就如下图所示
整体.png
整体2.png
使用perceptron来表示逻辑运算符and,or,not,xor
-
and
and.png
那么
weight1 = 1
weight2 = 1
bias = -2
即可满足and。
-
or
or.png
那么
weight1 = 1
weight2 = 1
bias = -1
-not
not只关心前一个input,而不关心后一个input是什么值
那么
weight1 = 0
weight2 = -1
bias = 0.5
-
xor
无法用一条线将这些点区分开来,
xor.png
需要组合and or 和not来实现
那么关于如何找出分界的线呢?(Ax -b = 0)
那么看下方法最基本的解释图
comecloser.png
上图可以看出,我们的红点是错分类的点,那么他会呼唤那条随机分类线靠近自己,当然可以直接用分类线的系数去减得错分类点的坐标,得出新的W和B,但是我们不希望分类线大范围的移动,造成不必要的损失,所以,此时引入了learning rate 学习速率,让分类线减去学习速率乘以错分类的点的坐标的值,从而慢慢靠近自己从而减小误差。
closer2.png
跟上面的方式类似,只是将减号变为了加号。
那么实现最基本的二分类感知器具体伪代码要如何来做呢?
举个栗子:
伪代码1.png
这是六个点,我们要用wx+b来分类这些点,
第一、随机一条线w1,w2....wn,b
第二、对于每一个错分类的点points(x1,x2....xn)
如果:
prediction预测分类为负(那么说明点为正)
for i in range(n)
改变wi + axi(a是learning rate)
改变b + a
如果:
prediction预测分类为正(那么说明点为负)
for i in range(n)
改变wi - axi(a是learning rate)
改变b - a
第三、如此循环直到error很小,或者没有error。
二、逻辑函数(Logistic function)激活函数(Activation function)
首先要知道误差函数,error function,误差函数是一种衡量当前答案与正确答案差距的函数。
那么课程中首先提到的log-loss error function,那么引入log-loss error function的理由是什么呢?就是为了引出我们的主题Logistic function。
1、首先我们来看下我们原来的perceptron最后激活函数,step function
是不是很明显,他是不连续的,一个断层的函数,那么如果我们使用梯度下降,在改动了一点点的weight的情况下,可能也只是从负值往零靠近了一点点,但他还是一个零值,并不能确定我们这样做下来是否有效果,这样就引入了log-loss error function,他的希望是将这个不可微的曲线,变换为可微的曲线,这样就能通过求导来找到最值。
那么具体的解释就是说,log-loss测量分类模型的性能,预测是介于0和1之间的概率值,我们的机器学习模型的目标是最小化该值。 完美模型的对数损失为0.对数损失随预测概率偏离实际标签的多少而增加。 因此,当实际观察标签为1时,预测.012的概率将是一个非常不好的值,这样就会导致偏大的logloss。 这里有部分资料进行学习
那么这里最基本的一个激活函数是sigmoid function
sigmoid.png
从图的左侧变为图的右侧的激活函数。
那么我们的perceptron也变为了下图
sigmoid2.png
能看到输出由原来的1,0变为了是1的概率是多少。
目前,从上面的两个激活函数来看,都是针对二分类的数据,那么,如果我们有更多分类呢?
这时就引入了第二个很常见的激活函数softmax function,他跟sigmoid函数很相似,不过他不仅能输出二分类概率,还能生成多分类概率。
softmax function或称归一化指数函数,它能将一个含任意实数的K维向量 z“压缩”到另一个K维实向量a(z)中,使得每一个元素的范围都在(0,1)中间,并且所有元素的和为1。
具体公式如下:
softmax2.png
如果用numpy来实现如下:
>>> import numpy as np
>>> z = [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0]
>>> softmax = np.exp(z)/np.sum(np.exp(z))
>>> softmax
array([0.02364054, 0.06426166, 0.1746813 , 0.474833 , 0.02364054,
0.06426166, 0.1746813 ])
上述这两个function都是典型的Logistic function,具体可以参看wiki的链接。
其他的激活函数,tanh,如下图,可以看出他跟sigmod的区别是他的值实在-1到1之间,并且曲线斜率较缓,更容易求导,导数又不会太小。
tanh.png
relu,如下图,比零小的值都为零,而比零大的值,斜率为1
relu.png
引入这两个激活函数比sigmod好的原因是,sigmod曲线在率大的时候和略小的时候几乎没有斜度比较平缓,这就意味着我们的导数较小,就是我们梯度消失的问题,会导致我们梯度下降步伐很小很难或者很久才能达到最低点。(梯度下降请继续往下看。)
三、独热编码(One-hot encoding)
独热编码,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都有它独立的寄存器位,并且在任意时候,其中只有一位有效。
例如:
自然状态码为:000,001,010,011,100,101
独热编码为:000001,000010,000100,001000,010000,100000
可以这样理解,对于每一个特征,如果它有m个可能值,那么经过独热编码后,就变成了m个二元特征。并且,这些特征互斥,每次只有一个激活。因此,数据会变成稀疏的。
这样做的好处主要有:
1、解决了分类器不好处理属性数据的问题
2、在一定程度上也起到了扩充特征的作用
四、最大似然估计(Maximum likelihood estimation)
原文来自这里
似然与概率
在统计学中,似然函数(likelihood function,通常简写为likelihood,似然)是一个非常重要的内容,在非正式场合似然和概率(Probability)几乎是一对同义词,但是在统计学中似然和概率却是两个不同的概念。概率是在特定环境下某件事情发生的可能性,也就是结果没有产生之前依据环境所对应的参数来预测某件事情发生的可能性,比如抛硬币,抛之前我们不知道最后是哪一面朝上,但是根据硬币的性质我们可以推测任何一面朝上的可能性均为50%,这个概率只有在抛硬币之前才是有意义的,抛完硬币后的结果便是确定的;而似然刚好相反,是在确定的结果下去推测产生这个结果的可能环境(参数),还是抛硬币的例子,假设我们随机抛掷一枚硬币1,000次,结果500次人头朝上,500次数字朝上(实际情况一般不会这么理想,这里只是举个例子),我们很容易判断这是一枚标准的硬币,两面朝上的概率均为50%,这个过程就是我们运用出现的结果来判断这个事情本身的性质(参数),也就是似然。
结果和参数相互对应的时候,似然和概率在数值上是相等的,如果用 θ 表示环境对应的参数,x 表示结果,那么概率可以表示为:
P(x|θ)
p(x|θ) 是条件概率的表示方法,θ 是前置条件,理解为在 θ 的前提下,事件 x 发生的概率,相对应的似然可以表示为:
L(θ|x)
可以理解为已知结果为 x ,参数为 θ (似然函数里 θ 是变量,这里说的参数和变量是相对与概率而言的)对应的概率,即:
L(θ|x)=P(x|θ)
需要说明的是两者在数值上相等,但是意义并不相同,L 是关于 θ 的函数,而 P 则是关于 x 的函数,两者从不同的角度描述一件事情。
那么似然函数的最大值意味着什么?让我们回到概率和似然的定义,概率描述的是在一定条件下某个事件发生的可能性,概率越大说明这件事情越可能会发生;而似然描述的是结果已知的情况下,该事件在不同条件下发生的可能性,似然函数的值越大说明该事件在对应的条件下发生的可能性越大。
通过结果所选出的最接近的最大概率,我们就可以选出最优化模型。
最后那就是很重要的对数化的似然函数
在似然函数的表达式中通常都会出现连乘:
对多项乘积的求导往往非常复杂,但是对于多项求和的求导却要简单的多,对数函数不改变原函数的单调性和极值位置,而且根据对数函数的性质可以将乘积转换为加减式,这可以大大简化求导的过程:
mle7.png
五、交叉熵(Cross-Entropy)
首先我们要说明引入交叉熵的原因,最直白的理由,最大似然假设不好求,毕竟是连乘,那么通过加自然对数,转换成连加取负来求最小的交叉熵,听起来要容易很多。
首先来看下自然对数的图是什么样子的:
很明显能看到,在0到1中间,ln的值为负无穷到零,那么如果求负,就是越接近概率1,值越小越接近零,就是运用了这个特性。
来看下正式的定义,交叉熵有两个概念,一个是信息量,一个是熵:
原文取自
信息量
假设X是一个离散型随机变量,其取值集合为Z,概率分布函数为p(x)=Pr(X=x),x∈Z,我们定义事件X=x0的信息量为:
I(x0)=−log(p(x0)),可以理解为,一个事件发生的概率越大,则它所携带的信息量就越小,而当p(x0)=1时,熵将等于0,也就是说该事件的发生不会导致任何信息量的增加。举个例子,小明平时不爱学习,考试经常不及格,而小王是个勤奋学习的好学生,经常得满分,所以我们可以做如下假设:
事件A:小明考试及格,对应的概率P(xA)=0.1,信息量为I(xA)=−log(0.1)=3.3219
事件B:小王考试及格,对应的概率P(xB)=0.999,信息量为I(xB)=−log(0.999)=0.0014
可以看出,结果非常符合直观:小明及格的可能性很低(十次考试只有一次及格),因此如果某次考试及格了(大家都会说:XXX竟然及格了!),必然会引入较大的信息量,对应的I值也较高。而对于小王而言,考试及格是大概率事件,在事件B发生前,大家普遍认为事件B的发生几乎是确定的,因此当某次考试小王及格这个事件发生时并不会引入太多的信息量,相应的I值也非常的低。
熵
熵其实是信息量的期望值,它是一个随机变量的确定性的度量。熵越大,变量的取值越不确定,反之就越确定。
还是通过上边的例子来说明,假设小明的考试结果是一个0-1分布A只有两个取值{0:不及格,1:及格},在某次考试结果公布前,小明的考试结果有多大的不确定度呢?你肯定会说:十有八九不及格!因为根据先验知识,小明及格的概率仅有0.1,90%的可能都是不及格的。怎么来度量这个不确定度?求期望!不错,我们对所有可能结果带来的额外信息量求取均值(期望),其结果不就能够衡量出小明考试成绩的不确定度了吗。
即:
HA(x)=−[p(xA)log(p(xA))+(1−p(xA))log(1−p(xA))]=0.4690
对应小王的熵:
HB(x)=−[p(xB)log(p(xB))+(1−p(xB))log(1−p(xB))]=0.0114
虽然小明考试结果的不确定性较低,毕竟十次有9次都不及格,但是也比不上小王(1000次考试只有一次才可能不及格,结果相当的确定)
我们再假设一个成绩相对普通的学生小东,他及格的概率是P(xC)=0.5,即及格与否的概率是一样的,对应的熵:
HC(x)=−[p(xC)log(p(xC))+(1−p(xC))log(1−p(xC))]=1
其熵为1,他的不确定性比前边两位同学要高很多,在成绩公布之前,很难准确猜测出他的考试结果。
最后来用课程中的举例来说明cross-entropy,交叉熵公式,二分类情况
cross.png
多分类情况:
cross_multi.png
六、梯度下降(gradient descent)
首先让我们来看下逻辑回归的步骤:
1、随机weights得到逻辑回归线
2、通过每一个点计算error,通过梯度下降减小error
3、如此反复直到error到了最小值
logitstic_regression.png
这是整个逻辑回归的步骤,那现在就是来了解下error。
通过上面的基础知识我们可以知道,缩小error,其实就是缩小cross entropy
换言之就是缩小下面这两个情况的公式(二分类和多分类)
error3.png
那么具体来举例看error是什么样子的呢?
error.png
因为我们的y_hat是wx+b和激活函数算出来的,那么转换成下一个公式,如图:
error2.png
那么减小这个error的方法,就是梯度下降法了。
要了解梯度下降法之前,让我们来点儿数学类基础知识:
1、什么是导数?
一图以蔽之:
能看到么,最基本的形容,曲线在当前点的切线,就是导数。
再用专业点的描述来说:
导数(Derivative)是微积分中的重要基础概念。当函数y=f(x)的自变量x在一点x0上产生一个增量Δx时,函数输出值的增量Δy与自变量增量Δx的比值在Δx趋于0时的极限a如果存在,a即为在x0处的导数,记作f'(x0)或df(x0)/dx。
导数是函数的局部性质。一个函数在某一点的导数描述了这个函数在这一点附近的变化率。如果函数的自变量和取值都是实数的话,函数在某一点的导数就是该函数所代表的曲线在这一点上的切线斜率。导数的本质是通过极限的概念对函数进行局部的线性逼近。例如在运动学中,物体的位移对于时间的导数就是物体的瞬时速度。
2、怎么求导?
套公式
导数3.png
3、链式法则
链式法则是微积分中的求导法则,用于求一个复合函数的导数,是在微积分的求导运算中一种常用的方法。复合函数的导数将是构成复合这有限个函数在相应点的 导数的乘积,就像锁链一样一环套一环,故称链式法则。
chainrule.png
例题:
链式法则2.png
正式进入梯度下降
那么再回过头来看梯度下降,我们求梯度下降,就是求当前情况下error减小最多的值,即求最小值,说到取最小值,那自然会想到对一个函数求导,就是让我们的位置变量,让它沿着导数递减的方向去移动。所以梯度下降就得来了下面的图的流程。
求导原来的wx+b,w和b是权重,是未知数,他的导数的负方向,就是梯度下降的方向。那么w加上这个梯度下降的方向乘以学习率,就是新的w和b了。
那么最后让我们来手推梯度下降公式吧:
梯度下降.jpeg
根据上面的式子,我们的wi和b就出来了
wi = w - a (y_hat - y)xi
b = b - a(y_hat - y)
梯度下降算法和感知机算法的相同与不同
梯度下降的y_hat是概率0~1,而感知机的y_hat是0或1
首先从左右两边公式上来看,是一致的,但是,梯度下降是改变所有点的权重,而感知机是改变错误分类点的权重,这样就导致的更大的区别就是,梯度下降会造成更小的error(毕竟用cross-entropy来算的)
上面都是将errorfunction设定为cross entropy方式来进行推导的,当然如果我们的errorfunction替换了呢?
比如我们使用SSE来进行错误估计
SSE是什么?The sum of the squared errors
因为我们y_hat已知,套入
SSE2.png
同样我们也是通过梯度下降法来找寻error最低点,如图所示:
SSE3.png
同样,梯度下降就是对w求偏导加上原来的权重产生新的权重
G-sse.png
g-sse2.png
y_hat是激活函数对wx+b来激活,那么如下:
g-sse3.png
后面那项求导只会留下xi,因为其他都是常数呀,如图,套入并简化为:
g-sse4.png
g-sse5.png g-sse6.png
同理我们还能用MSE(The mean of the squared errors )
mse.png
这里就不再多说了,整体步骤差不多。
这里多说一句对a-learningrate的建议,如果error线比较陡峭,我们需要大步走,而如果我们的error曲线比较平滑,我们需要小步走,大步小步就是指learningrate的设置范围:
learningrate.png
另外针对初始化权重,一般使用np的随机正太取值。
weights = np.random.normal(scale=1/n_features**.5, size=n_features)
一个比较好的起点是1/(n^0.5),n是输入的单元数。
梯度下降法的三种形式BGD、SGD以及MBGD
首先让我们假设一个损失函数(误差函数)为最小二乘法的形式:
梯度下降0.jpg
下图作为一个二维参数组θ1,θ2对应能量函数的可视化图:
梯度下降1.jpg
1、批量梯度下降法BGD
批量梯度下降法其实就是我们每一次的参数更新都用到了所有的训练数据(比如有m个,就用到了m个),如果训练数据非常多的话,是非常耗时的。
注意是损失函数对每一个点的θ求偏导后,加起来求平均。
下面给出批梯度下降的收敛图:
BGD.jpg
从图中,我们可以得到BGD迭代的次数相对较少。
2、随机梯度下降法SGD
由于批梯度下降每更新一个参数的时候,要用到所有的样本数,所以训练速度会随着样本数量的增加而变得非常缓慢。随机梯度下降正是为了解决这个办法而提出的。它是利用每个样本的损失函数对θ求偏导得到对应的梯度,来更新θ,过程如下:
SGD1.jpg
随机梯度下降是通过每个样本来迭代更新一次,对比上面的批量梯度下降,迭代一次需要用到所有训练样本(往往如今真实问题训练数据都是非常巨大),一次迭代不可能最优,如果迭代10次的话就需要遍历训练样本10次。但是,SGD伴随的一个问题是噪音较BGD要多,使得SGD并不是每次迭代都向着整体最优化方向。
随机梯度下降收敛图如下:
我们可以从图中看出SGD迭代的次数较多,在解空间的搜索过程看起来很盲目。但是大体上是往着最优值方向移动。
3、min-batch 小批量梯度下降法MBGD
我们从上面两种梯度下降法可以看出,其各自均有优缺点,那么能不能在两种方法的性能之间取得一个折衷呢?即,算法的训练过程比较快,而且也要保证最终参数训练的准确率,而这正是小批量梯度下降法(Mini-batch Gradient Descent,简称MBGD)的初衷。
我们假设每次更新参数的时候用到的样本数为10个(不同的任务完全不同,这里举一个例子而已),所以跟上面最大的区别就是,并非所有样本,而是用了一个小的batchsize的样本来进行一次次的训练。
更新伪代码如下:
4、三种梯度下降方法的总结
1.批梯度下降每次更新使用了所有的训练数据,最小化损失函数,如果只有一个极小值,那么批梯度下降是考虑了训练集所有数据,是朝着最小值迭代运动的,但是缺点是如果样本值很大的话,更新速度会很慢。
2.随机梯度下降在每次更新的时候,只考虑了一个样本点,这样会大大加快训练数据,也恰好是批梯度下降的缺点,但是有可能由于训练数据的噪声点较多,那么每一次利用噪声点进行更新的过程中,就不一定是朝着极小值方向更新,但是由于更新多轮,整体方向还是大致朝着极小值方向更新,又提高了速度。
3.小批量梯度下降法是为了解决批梯度下降法的训练速度慢,以及随机梯度下降法的准确性综合而来,但是这里注意,不同问题的batch是不一样的,听师兄跟我说,我们nlp的parser训练部分batch一般就设置为10000,那么为什么是10000呢,我觉得这就和每一个问题中神经网络需要设置多少层,没有一个人能够准确答出,只能通过实验结果来进行超参数的调整。
以上内容参考这里哦
上面是三种方法的比较和介绍,但是上面三种方法都没有解决下面这个问题“
在对神经网络最优化非凸的罚函数时,如何避免目标函数被困在无数的局部最小值中,以导致的未完全优化的情况。那么就引出了下面的方法:
5、动量梯度下降Momentum
参考链接见这里
首先来看一个问题:
可以看出在cost function的图像并不是那么“圆”的情况下,,从某一点开始的梯度下降过程是及其曲折的。并不是直接走向中心点,而是需要浪费很多时间折来折去,这样的速度就会变慢,怎么样解决这个问题呢?
有一个梯度下降法叫做动量梯度下降。直接上图:
动量梯度2.png
这个就是动量梯度下降的参数更新公式。
我们可以看出,在这个公式中,并不是直接减去αdW和αdb,而是计算出了一个vdW和vdb。这又是什么呢?
在此需要引入一个叫做指数加权平均的知识点。也就是上图中的前两行公式。使用这个公式,可以将之前的dW和db都联系起来,不再是每一次梯度都是独立的情况。其中β是可以自行设置的超参数,一般情况下默认为0.9(也可以设置为其他数值)。β代表了现在的vdW和vdb与之前的1 / (1 - β)个vdW和vdb有关。0.9就是现在的vdW和vdb是平均了之前10天的vdW和vdb的结果。
此时的梯度不再只是我现在的数据的梯度,而是有一定权重的之前的梯度,就我个人认为,就像是把原本的梯度压缩一点,并且补上一个之前就已经存在的“动量”。
举个例子,如果你站在一个地方不动,让你立刻向后转齐步走,你可以迅速向后转然后就向相反的方向走了起来,批梯度下降和随机梯度下降就是这样,某一时刻的梯度只与这一时刻有关,改变方向可以做到立刻就变。而如果你正在按照某个速度向前跑,再让你立刻向后转,可以想象得到吧,此时你无法立刻将速度降为0然后改变方向,你由于之前的速度的作用,有可能会慢慢减速然后转一个弯。
动量梯度下降是同理的,每一次梯度下降都会有一个之前的速度的作用,如果我这次的方向与之前相同,则会因为之前的速度继续加速;如果这次的方向与之前相反,则会由于之前存在速度的作用不会产生一个急转弯,而是尽量把路线向一条直线拉过去。这就解决了文中第一个图的那个在普通梯度下降中存在的下降路线折来折去浪费时间的问题。
当然还有很多其他的优化算法,
Adam
Adam (Adaptive Moment Estimation) 使用更复杂的指数衰减,不仅仅会考虑平均值(第一个动量),并且会考虑前几步的方差(第二个动量)。
RMSProp
RMSProp (RMS 表示均方根误差)通过除以按指数衰减的平方梯度均值来减小学习速率。
等等,不再讲解。
七、神经网络结构
用一张图来展示
NeuralNetworkArchitecture.png
能很清晰的看到整体其实也可以理解是一个perceptron,只是输入是由两个”小模型“组成,从线代的角度来说,我们就是得到这两个模型的线性组合,从而得出了非线性模型(非线性模型从线性代数的角度来说,其实是变换了维度后,在当前这个维度所看到的结果)
再来整合一下上面的图:
NeuralNetworkArchitecture1.png
想象一下线代的内积操作(乘法操作,dot)其实就跟这样的图像一样
NeuralNetworkArchitecture2.png
将bias也作为一个节点,来再次简化
NeuralNetworkArchitecture3.png
最后一个节点,就是用sigmoid或者softmax来进行二分类或者多分类了。
比如下面的多分类图,返回的都是概率。
network
八、前向反馈 Feedforward
单层感知机
percepforward.png
多层感知机
Feedforward.png
其实就是我们之前的知识,就是计算的前向反馈,重点是下面的反向传播
九、反向传播(Backpropagation)
反向传播(英语:Backpropagation,缩写为BP)是“误差反向传播”的简称,是一种与最优化方法(如梯度下降法)结合使用的,用来训练人工神经网络的常见方法。该方法对网络中所有权重计算损失函数的梯度。这个梯度会反馈给最优化方法,用来更新权值以最小化损失函数。
这里也推荐一篇博文
backde1.png
backde.png
十、卷积层 convolutional layer
卷积层是指特征映射堆栈
十一、池化层 polling layer
十二、earlystop
一句话,及时止损。
神经网络中具体的做法如下:
- 首先将训练数据划分为训练集和验证集(划分比例为2:1);
- 在训练集上进行训练,并且在验证集上获取测试结果(比如每隔5个epoch测试一下),随着epoch的增加,如果在验证集上发现测试误差上升,则停止训练;
- 将停止之后的权重作为网络的最终参数。
注:Early Stop能够防止过拟合。
十三、正则化
这个在监督学习中有稍微详细点讲过,链接
十四、 dropout
dropout是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃。注意是暂时,对于随机梯度下降来说,由于是随机丢弃,故而每一个mini-batch都在训练不同的网络。
dropout是CNN中防止过拟合提高效果的一个大杀器,但对于其为何有效,却众说纷纭。在下读到两篇代表性的论文,代表两种不同的观点,特此分享给大家。
观点一:
该论文从神经网络的难题出发,一步一步引出dropout为何有效的解释。大规模的神经网络有两个缺点:
- 费时
- 容易过拟合
这两个缺点真是抱在深度学习大腿上的两个大包袱,一左一右,相得益彰,额不,臭气相投。过拟合是很多机器学习的通病,过拟合了,得到的模型基本就废了。而为了解决过拟合问题,一般会采用ensemble方法,即训练多个模型做组合,此时,费时就成为一个大问题,不仅训练起来费时,测试起来多个模型也很费时。总之,几乎形成了一个死锁。
Dropout的出现很好的可以解决这个问题,每次做完dropout,相当于从原始的网络中找到一个更瘦的网络,如下图所示:
dropout1.png
因而,对于一个有N个节点的神经网络,有了dropout后,就可以看做是2^n个模型的集合了,但此时要训练的参数数目却是不变的,这就解脱了费时的问题。
观点二:
虽然直观上看dropout是ensemble在分类性能上的一个近似,然而实际中,dropout毕竟还是在一个神经网络上进行的,只训练出了一套模型参数。那么他到底是因何而有效呢?这就要从动机上进行分析了。论文中作者对dropout的动机做了一个十分精彩的类比:
在自然界中,在中大型动物中,一般是有性繁殖,有性繁殖是指后代的基因从父母两方各继承一半。但是从直观上看,似乎无性繁殖更加合理,因为无性繁殖可以保留大段大段的优秀基因。而有性繁殖则将基因随机拆了又拆,破坏了大段基因的联合适应性。
但是自然选择中毕竟没有选择无性繁殖,而选择了有性繁殖,须知物竞天择,适者生存。我们先做一个假设,那就是基因的力量在于混合的能力而非单个基因的能力。不管是有性繁殖还是无性繁殖都得遵循这个假设。为了证明有性繁殖的强大,我们先看一个概率学小知识。
比如要搞一次恐怖袭击,两种方式:
- 集中50人,让这50个人密切精准分工,搞一次大爆破。
- 将50人分成10组,每组5人,分头行事,去随便什么地方搞点动作,成功一次就算。
哪一个成功的概率比较大? 显然是后者。因为将一个大团队作战变成了游击战。
那么,类比过来,有性繁殖的方式不仅仅可以将优秀的基因传下来,还可以降低基因之间的联合适应性,使得复杂的大段大段基因联合适应性变成比较小的一个一个小段基因的联合适应性。
dropout也能达到同样的效果,它强迫一个神经单元,和随机挑选出来的其他神经单元共同工作,达到好的效果。消除减弱了神经元节点间的联合适应性,增强了泛化能力。
个人补充一点:那就是植物和微生物大多采用无性繁殖,因为他们的生存环境的变化很小,因而不需要太强的适应新环境的能力,所以保留大段大段优秀的基因适应当前环境就足够了。而高等动物却不一样,要准备随时适应新的环境,因而将基因之间的联合适应性变成一个一个小的,更能提高生存的概率。
dropout带来的模型的变化
而为了达到ensemble的特性,有了dropout后,神经网络的训练和预测就会发生一些变化。
-
训练层面
dropout2.png
无可避免的,训练网络的每个单元要添加一道概率流程。
对应的公式变化如下如下:
-- 没有dropout的神经网络
dropout3.png
-- 有dropout的神经网络
dropout4.png -
测试层面
dropout5.png
预测的时候,每一个单元的参数要预乘以p
观点三:
知识点A
在线性空间中,学习一个整个空间的特征集合是足够的,但是当数据分布在非线性不连续的空间中得时候,则学习局部空间的特征集合会比较好。
知识点B
假设有一堆数据,这些数据由M个不同的非连续性簇表示,给定K个数据。那么一个有效的特征表示是将输入的每个簇映射为特征以后,簇之间的重叠度最低。使用A来表示每个簇的特征表示中激活的维度集合。重叠度是指两个不同的簇的Ai和Aj之间的Jaccard相似度最小,那么:
- 当K足够大时,即便A也很大,也可以学习到最小的重叠度
- 当K小M大时,学习到最小的重叠度的方法就是减小A的大小,也就是稀疏性。
上述的解释可能是有点太专业化,比较拗口。主旨意思是这样,我们要把不同的类别区分出来,就要是学习到的特征区分度比较大,在数据量足够的情况下不会发生过拟合的行为,不用担心。但当数据量小的时候,可以通过稀疏性,来增加特征的区分度。
因而有意思的假设来了,使用了dropout后,相当于得到更多的局部簇,同等的数据下,簇变多了,因而为了使区分性变大,就使得稀疏性变大。
为了验证这个数据,论文还做了一个实验,如下图:
dropout6.png
该实验使用了一个模拟数据,即在一个圆上,有15000个点,将这个圆分为若干个弧,在一个弧上的属于同一个类,一共10个类,即不同的弧也可能属于同一个类。改变弧的大小,就可以使属于同一类的弧变多。
实验结论就是当弧长变大时,簇数目变少,稀疏度变低。与假设相符合。
个人观点:该假设不仅仅解释了dropout何以导致稀疏性,还解释了dropout因为使局部簇的更加显露出来,而根据知识点A可得,使局部簇显露出来是dropout能防止过拟合的原因,而稀疏性只是其外在表现。
十五、图片增强
十六、迁移学习
迁移学习是指对提前训练过的神经网络进行调整,以用于新的不同数据集。
取决于以下两个条件:
- 新数据集的大小,以及
- 新数据集与原始数据集的相似程度
使用迁移学习的方法将各不相同。有以下四大主要情形:
- 新数据集很小,新数据与原始数据相似
- 新数据集很小,新数据不同于原始训练数据
- 新数据集很大,新数据与原始训练数据相似
- 新数据集很大,新数据不同于原始训练数据
迁移学习1.png
大型数据集可能具有 100 万张图片。小型数据集可能有 2000 张图片。大型数据集与小型数据集之间的界限比较主观。对小型数据集使用迁移学习需要考虑过拟合现象。
狗的图片和狼的图片可以视为相似的图片;这些图片具有共同的特征。鲜花图片数据集不同于狗类图片数据集。
四个迁移学习情形均具有自己的方法。在下面的几节内容中,我们将分别查看每个情形。
演示网络
为了解释每个情形的工作原理,我们将以一个普通的预先训练过的卷积神经网络开始,并解释如何针对每种情形调整该网络。我们的示例网络包含三个卷积层和三个完全连接层:
迁移学习2.png
下面是卷积神经网络的作用一般概述:
- 第一层级将检测图片中的边缘
- 第二层级将检测形状
- 第三个卷积层将检测更高级的特征
每个迁移学习情形将以不同的方式使用预先训练过的神经网络。
情形 1:小数据集,相似数据
迁移学习3.png
情形 1:具有相似数据的小数据集
如果新数据集很小,并且与原始训练数据相似:
- 删除神经网络的最后层级
- 添加一个新的完全连接层,与新数据集中的类别数量相匹配
- 随机化设置新的完全连接层的权重;冻结预先训练过的网络中的所有权重
- 训练该网络以更新新连接层的权重
为了避免小数据集出现过拟合现象,原始网络的权重将保持不变,而不是重新训练这些权重。
因为数据集比较相似,每个数据集的图片将具有相似的更高级别特征。因此,大部分或所有预先训练过的神经网络层级已经包含关于新数据集的相关信息,应该保持不变。
以下是如何可视化此方法的方式:
迁移学习4.png
情形 2:小型数据集、不同的数据
迁移学习5.png
如果新数据集很小,并且与原始训练数据不同:
- 将靠近网络开头的大部分预先训练过的层级删掉
- 向剩下的预先训练过的层级添加新的完全连接层,并与新数据集的类别数量相匹配
- 随机化设置新的完全连接层的权重;冻结预先训练过的网络中的所有权重
- 训练该网络以更新新连接层的权重
因为数据集很小,因此依然需要注意过拟合问题。要解决过拟合问题,原始神经网络的权重应该保持不变,就像第一种情况那样。
但是原始训练集和新的数据集并不具有相同的更高级特征。在这种情况下,新的网络仅使用包含更低级特征的层级。
以下是如何可视化此方法的方式:
迁移学习6.png
情形 3:大型数据集、相似数据
迁移学习7.png
如果新数据集比较大型,并且与原始训练数据相似:
- 删掉最后的完全连接层,并替换成与新数据集中的类别数量相匹配的层级
- 随机地初始化新的完全连接层的权重
- 使用预先训练过的权重初始化剩下的权重
- 重新训练整个神经网络
训练大型数据集时,过拟合问题不严重;因此,你可以重新训练所有权重。
因为原始训练集和新的数据集具有相同的更高级特征,因此使用整个神经网络。
以下是如何可视化此方法的方式:
迁移学习8.png
情形 4:大型数据集、不同的数据
迁移学习9.png
如果新数据集很大型,并且与原始训练数据不同:
- 删掉最后的完全连接层,并替换成与新数据集中的类别数量相匹配的层级
- 使用随机初始化的权重重新训练网络
- 或者,你可以采用和“大型相似数据”情形的同一策略
虽然数据集与训练数据不同,但是利用预先训练过的网络中的权重进行初始化可能使训练速度更快。因此这种情形与大型相似数据集这一情形完全相同。
如果使用预先训练过的网络作为起点不能生成成功的模型,另一种选择是随机地初始化卷积神经网络权重,并从头训练网络。
以下是如何可视化此方法的方式:
迁移学习10.png
网友评论