DNN算法的基本思想
多层感知器在如何获取隐层的权值的问题上遇到了瓶颈。既然我们无法直接得到隐层的权值,能否先通过输出层得到输出结果和期望输出的误差来间接调整隐层的权值呢?BP算法就是采用这样的思想设计出来的算法,它的精髓就是,学习过程由信号的正向传播与误差的反向传播两个过程组成。
正向传播时,输入样本从输入层传入(layer1),经各隐层逐层(layer2)处理后,传向输出层(layer3)。若输出层的实际输出与期望的输出(教师信号)不符,则转入误差的反向传播阶段。
反向传播时,将输出以某种形式通过隐层向输入层逐层反传,并将误差分摊给各层的所有单元,从而获得各层单元的误差信号,此误差信号即作为修正各单元权值的依据。
说明上图各符号代表意思
ωijl表示第l-1层第j个元素与第l层第i个元素的连接参数
Zil第l层第i个元素输入Zil= Σjωijlajl-1+bil
ail=σ(Zil)
值从第一层向后传播做运算直到输出,正向传播就结束了!
计算更新ωijl,目标函数J(W,b,x,y),为了描述方便这里使用最简单的目标函数(一次计算一个样本)
如果觉得矩阵运算费解,还可以这样
结合图形与倒数第二个等式,对ωijL求偏导数,等于对应分量误差对其偏导,更能体现反向传播的意义。
上面求了WL的偏导,下面求J对WL-1的偏导
依次类推可以求出每一层W梯度,更新W与b
均方差损失函数+Sigmoid激活函数的问题
Sigmoid函数当模型运行后,越来越接近目标值,激活函数Sigmoid变的非常平滑,σ'越接近0,导致梯度消失,更新W,b更新到极值的速度较慢,算法收敛速度较慢。
交叉熵损失函数+Sigmoid激活函数改进DNN算法收敛速度,这个也只能消除L层的影响,其余层的还是不能消除
使用对数似然损失函数和softmax激活函数进行DNN分类输出
在前面我们讲的所有DNN相关知识中,我们都假设输出是连续可导的值。但是如果是分类问题,那么输出是一个个的类别,那我们怎么用DNN来解决这个问题呢?
比如假设我们有一个三个类别的分类问题,这样我们的DNN输出层应该有三个神经元,假设第一个神经元对应类别一,第二个对应类别二,第三个对应类别三,这样我们期望的输出应该是(1,0,0),(0,1,0)和(0,0,1)这三种。即样本真实类别对应的神经元输出应该无限接近或者等于1,而非改样本真实输出对应的神经元的输出应该无限接近或者等于0。或者说,我们希望输出层的神经元对应的输出是若干个概率值,这若干个概率值即我们DNN模型对于输入值对于各类别的输出预测,同时为满足概率模型,这若干个概率值之和应该等于1。DNN分类模型要求是输出层神经元输出的值在0到1之间,同时所有输出值之和为1。很明显,现有的普通DNN是无法满足这个要求的。但是我们只需要对现有的全连接DNN稍作改良,即可用于解决分类问题。在现有的DNN模型中,我们可以将输出层第i个神经元的激活函数定义为如下形式:
梯度爆炸梯度消失与ReLU激活函数
对于梯度爆炸(偏导大于1,乘积积累后越来越大),则一般可以通过调整我们DNN模型中的初始化参数得以解决。
对于无法完美解决的梯度消失问题,目前有很多研究,一个可能部分解决梯度消失问题的办法是使用ReLU(Rectified Linear Unit)激活函数,ReLU在卷积神经网络CNN中得到了广泛的应用,在CNN中梯度消失似乎不再是问题。那么它是什么样子呢?其实很简单,比我们前面提到的所有激活函数都简单,表达式为:
σ(z)=max(0,z)
也就是说大于等于0则不变,小于0则激活后为0。就这么一玩意就可以解决梯度消失?至少部分是的。这个函数小于0的部分σ'=0,大于0部分σ'=1