神经网络的提升方法(1)——交叉熵

本文是电子书Neural Networks and Deep Learning的读书笔记,我不能保证自己理解是否有偏误或者忽略了原文的精彩地方,如有请读者指出,另外还是推荐英文阅读能力较强的读者直接去阅读原书,因为写得真的不错。原书地址:http://neuralnetworksanddeeplearning.com/#_motz_

神经网络训练的提升可以由四个方面进行:使用能反馈更大误差信号的交叉熵(cross entropy)作为损失函数、能使网络具备更好泛化能力的四种正则化(L1、L2、DropOut和人工扩充训练数据)以及对超参数的一些启发式选取。本文先介绍交叉熵部分。

 

交叉熵损失函数

在训练过程要使网络更快的收敛,必须要使错误更明显。错误明显就是误差信号越强烈,如此反向传播才会更大限度的对网络参数进行调整。我们传统是使用二次损失函数

在使用sigmoid激活函数的情况下(此处不考虑现在最流行的ReLU激活函数)

因此,

通过sigmoid函数(下图)的形状不难看出,在sigmoid函数输出值接近0或1的区间内梯度比较平缓,out'会很接近于0,如此会大大削弱误差信号的反馈。交叉熵则可以避免sigmoid梯度饱和的问题。

交叉熵损失函数表达形式为:

其中n表示记录数,表示对训练样本的误差汇总再取平均,此处仅考虑一个输出单元。

 

交叉熵损失函数有两个很重要的性质:第一,它是非负的。由于对sigmoid函数输出不能大于1,而对数的底为e,因此ln(out)绝对小于0,而最后乘上-1/n可以保证结果非负;第二,如果输出结果out与期望输出y很接近,那么交叉熵的值会很接近0,这是由ln(1) = 0这个性质得出的。

以权值更新规则来看,W(k) = W(k - 1) + η * ∂L/∂W。

交叉熵对权值W的偏导数:

由于

因此

与二次损失函数对比,交叉熵对权值的偏导数少了out'这个一项,这样即便激活函数是否会饱和对权值训练也没有太大影响。

 

以上我们都是在一个输出单元的基础上进行讨论,但其实也可以很容易推广到多个输出单元的情况:

j表示第j个输出单元,也就是多个输出单元交叉熵需要把多个输出单元的损失值汇总到一起。

 

其实如果单从交叉熵的性质来讨论的话,二次损失函数和交叉熵并没有太大的区别,因为二次损失函数也包含了交叉熵上述的两个性质。但如果使用sigmoid激活函数的情况下,交叉熵可以避免了激活函数饱和而带来的梯度消失问题(当然,如果使用ReLu之类的分段线性函数,这个也不是问题)。

 

接着作者在文中抛出了两个问题,欢迎读者一起讨论:

1.交叉熵的表达式很可能因记不准而被记成

,这一表达式与真正的交叉熵会有什么区别?

2.在分类问题中,上述如果实际输出跟期望输出(0或1)很接近时,损失值会很靠近0,但如果在回归等其他问题中,实际输出可以有无数种(这里主要想表达的是像回归这样的问题不能像分类问题一样如果期望与实际输出靠近时损失值趋向ln(1)),尝试证明在其他问题中,当y=out时损失值依然是最小的。

作为一段小结,就让我们稍微整理一下思路,以及稍微探索一下交叉熵提出的意义:在传统神经网络一般是用sigmoid作为激活函数,而这种激活函数有个很大问题就是存在饱和区间,一旦落在饱和区间内将会对误差反馈信号打了大大的折扣,从而影响网络的训练速度。这个对误差信号打折扣的因素在于out',如果我们能有一个△W项上没有out'的就可以避免这个影响了,这样交叉熵就被提出来了,因为在交叉熵损失函数对W的偏导数不包含这一个项。值得注意的是,假如我们使用的是Pure Line(y = w*x+b)激活函数或ReLU激活函数,同样不存在饱和区间,所以可以说,交叉熵是在使用Sigmoid函数的时候被提出的。

 

Softmax层

通常在每层神经网络都会以W·input + b的方式把所有输入加权汇总,经过激活函数(很经典的做法就是用sigmoid)变换而输出。但在网络输出层,如果我们现在面临一个多分类问题,按传统的做法我们应该把最后一个隐层的输出加权汇总再经过激活产生一个单一的结果,不过我们能如何使用一个激活函数使得输出与期望输出很接近呢?当然我们可以使用pure line,但是我们并不能很好的保证激活函数输出后的值域跟我们期望输出大致相同。

这里引入一个softmax层,它的表达式为:

它是基于一个多输出节点的考虑,分母是一个归一化因子,不难发现如果把所有输出节点加起来结果会是1,分子是e的指数,它又能保证输出值大于0,因此每个输出节点的输出将会表达为该节点对应类别的概率,所以softmax层输出的就是一个概率分布。

原文作者让我们根据softmax的表达式证明两个问题:

1.当j = k 时∂outj/ ∂zk为正,而当j ≠ k时为负

2.在传统的激活函数中例如sigmoid,out = σ(z),输出时跟加权输入z有关系的,而softmax中输出out跟加权输入却为什么并没有关系?

softmax层通常使用的是对数极大似然损失函数:

当P(out|X)越接近期望输出的时候,损失会越小。这样,其实跟交叉熵损失函数是如出一辙的,同样可以避免激活函数的饱和问题,因此softmax输出层+对数极大似然损失跟sigmoid输出层+交叉熵损失作用是很类似的。

softmax和对数似然损失的误差反馈:errj = ∂C / ∂zj ->errj = outj - yj。附上另外一位深度学习爱好者关于softmax求导的博客文章:http://blog.csdn.net/acdreamers/article/details/44663305

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章