深度神经网络(Deep Neural Networks,DNN)可以理解为有很多隐藏层的神经网络,又被称为深度前馈网络(DFN),多层感知机(Multi-Layer perceptron,MLP)。

1 前向传播算法

1.1 从感知机到神经网络

感知机的模型是一个有若干输入和一个输出的模型,如下图:

输出和输入之间学习到一个线性关系,得到中间输出结果:

接着是一个神经元激活函数,得到输出结果1或者-1。:

这个模型只能用于二元分类,且无法学习比较复杂的非线性模型,因此在工业界无法使用。

而神经网络则在感知机的模型上做了扩展,总结下主要有三点:

  • 1)加入了多层隐藏层,增强模型的表达能力。
  • 2)输出层神经元可以不止一个,可以有多个输出,这样模型可以灵活的应用于分类,回归,降维和聚类等。下图输出层有4个神经元。

  • 3) 对激活函数做扩展。感知机的激活函数是sign(z),虽然简单但是处理能力有限,因此神经网络中一般使用:Sigmoid,tanx, ReLU,softplus,softmax等加入非线性因素,提高模型的表达能力。

1.2 DNN的基本结构

按不同层的位置划分,DNN内部的神经网络层可以分为:输入层,隐藏层和输出层,一般第一层是输入层,最后一层是输出层,而中间的层数都是隐藏层。层与层之间是全连接的,即第i层的任意一个神经元一定与第i+1层的任意一个神经元相连。

虽然DNN看起来很复杂,但是从小的局部模型来说,还是和感知机一样,即一个线性关系加上一个激活函数σ(z)。

由于DNN层数多,参数较多,线性关系系数w和偏倚b的定义需要一定的规则。线性关系系数w的定义:第二层的第4个神经元到第三层的第2个神经元的线性系数定义为。上标3代表线性系数w所在的层数,而下标对应的是输出的第三层索引2和输入的第二层索引4。你也许会问,为什么不是w342, 呢?这主要是为了便于模型用于矩阵表示运算,如果是w342而每次进行矩阵运算是wTx+b,需要进行转置。将输出的索引放在前面的话,则线性运算不用转置,即直接为wx+b。注意,输入层是没有w参数,偏倚参数b。

 偏倚b的定义:第二层的第三个神经元对应的偏倚定义为。其中,上标2代表所在的层数,下标3代表偏倚所在的神经元的索引。

1.3 DNN前向传播算法数学原理

假设选择的激活函数是σ(z),隐藏层和输出层的输出值为a。

1.4 DNN前向传播算法

DNN的前向传播算法是利用若干个权重系数矩阵W,偏倚向量b来和输入值向量x进行一系列线性运算和激活运算,从输入层开始,利用上一层的输出计算下一层的输出,一层层的向后计算,一直到运算到输出层,得到输出结果为值。

2 DNN反向传播算法

使用前向传播计算训练样本的输出,使用损失函数,来度量训练样本计算出的输出和真实的训练样本标签之间的损失。DNN的反向传播算法(Back Propagation,BP)通过对损失函数用梯度下降法进行迭代优化求极小值,找到合适的隐藏层和输出层对应的线性系数矩阵W,偏倚向量b,让所有的训练样本输入计算出的输出尽可能的等于或接近样本标签。

2.1 DNN反向传播算法的基本思路

使用均方差来度量损失进行推导。即对于每个样本,期望最小化下式:

2.2 DNN反向传播算法过程

梯度下降法有批量(Batch),小批量(mini-Batch),随机三个变种,为了简化描述,这里以最基本的批量梯度下降法为例来描述反向传播算法。实际上在业界使用最多的是mini-Batch的梯度下降法。不过区别仅仅在于迭代时训练样本的选择而已。

3 损失函数和激活函数

3.1 均方差损失函数+Sigmoid激活函数的问题

Sigmoid激活函数的表达式和图像:

对于Sigmoid,当z的取值越来越大(或z的取值越来越小时),函数曲线变得越来越平缓,导数σ′(z)也越来越小。仅仅在z取值为0附近时,导数σ′(z)的取值较大。在使用均方差+Sigmoid的反向传播算法中,每一层向前递推都要乘以σ′(z),得到梯度变化值。Sigmoid的这个曲线意味着在大多数时候,梯度变化值很小,导致W,b更新到极值的速度较慢,算法收敛速度较慢。

2. 使用交叉熵损失函数+Sigmoid激活函数改进DNN算法收敛速度

每个样本的交叉熵损失函数的形式:

另外,表示预测值与实际值的误差,当误差越大时,梯度就越大,参数w和b的调整就越快,训练的速度也就越快。通常情况下,如果使用了sigmoid激活函数,交叉熵损失函数肯定比均方差损失函数好用。综上:如果输出神经元是线性的,那么二次代价函数就是一种合适的选择,如果输出神经元是S型函数(sigmoid,tanh),那么比较适合用交叉熵代价函数。

3. 使用对数似然损失函数和softmax激活函数进行DNN分类输出

对数似然函数与softmax的组合和交叉熵与sigmoid函数的组合相似,对数似然代价函数在二分类时可以化简为交叉熵代价函数的形式。

将DNN用于分类问题,在输出层用softmax激活函数非常常见。DNN分类模型要求是输出层神经元输出的值在0到1之间,同时所有输出值之和为1。普通DNN是无法满足这个要求。对现有的全连接DNN稍作改良,将输出层的激活函数从Sigmoid之类的函数转变为上式的softmax激活函数,即可用于解决分类问题。在现有的DNN模型中,将输出层第i个神经元的激活函数定义为如下形式:

softmax激活函数在前向传播算法时的使用:假设输出层为三个神经元,而未激活的输出为3,1和-3,求出各自的指数表达式为:20,2.7和0.05,归一化因子即为22.75,则三个类别的概率输出分布为0.88,0.12和0。

4. 梯度爆炸,梯度消失与ReLU激活函数

在反向传播算法中,由于使用了是矩阵求导的链式法则,有一大串连乘,如果连乘的数字在每层都是小于1的,则梯度越往前乘越小,导致梯度消失,而如果连乘的数字在每层都是大于1的,则梯度越往前乘越大,导致梯度爆炸。对于梯度爆炸,则一般可以通过调整DNN模型中的初始化参数得以解决。

反向传播算法中δ的计算:

甚至接近于0,导致梯度几乎消失,进而导致前面隐藏层的W,b参数随着迭代的进行几乎没有大的改变,收敛速度较慢。

一个可能部分解决梯度消失问题的办法是使用ReLU(Rectified Linear Unit)激活函数:σ(z)=max(0,z),ReLU在卷积神经网络CNN中得到了广泛的应用。

5. DNN损失函数和激活函数小结

1)如果使用sigmoid激活函数,则交叉熵损失函数一般肯定比均方差损失函数好。2)如果是DNN用于分类,则一般在输出层使用softmax激活函数和对数似然损失函数。3)ReLU激活函数对梯度消失问题有一定程度的解决,尤其是在CNN模型中。

DNN常用的激活函数:

  • 1)sigmoid:
  • 2)ReLU:σ(z)=max(0,z)
  • 3) tanh:sigmoid的变种,输出区间为[-1,1]表达式为:

tanh激活函数和sigmoid激活函数的关系为:

  • 4) softplus:sigmoid函数的原函数,表达式为:

它的导数就是sigmoid函数。softplus的函数图像和ReLU有些类似。它出现的比ReLU早,可以视为ReLU的鼻祖。

  • 5)PReLU:ReLU的变种,特点是如果未激活值小于0,不是简单粗暴的直接变为0,而是进行一定幅度的缩小。

正则化

1. DNN的L1&L2正则化

L1正则化和L2正则化原理类似,重点讲述DNN的L2正则化。DNN的L2正则化通常只针对与线性系数矩阵W,而不针对偏倚系数b。

假如每个样本的损失函数是均方差损失函数,则所有的m个样本的损失函数为:

则加上了L2正则化后的损失函数是:

其中,λ即正则化超参数,实际使用时需要调参。而w为所有权重矩阵W的所有列向量。

如果使用上式的损失函数,进行反向传播算法时,流程和没有正则化的反向传播算法完全一样,区别仅仅在于进行梯度下降法时,W的更新公式。反向传播算法中,W的梯度下降更新公式为:

加入L2正则化以后,迭代更新公式变成:

注意到上式中的梯度计算中我忽略了,因为α是常数,而除以m也是常数,所以等同于用了新常数α来代替。类似的L2正则化方法可以用于交叉熵损失函数或者其他的DNN损失函数。

2. DNN通过集成学习的思路正则化

除了常见的L1&L2正则化,DNN可以用Bagging的思路来正则化。常用的机器学习Bagging算法中,随机森林是最流行的。它通过随机采样构建若干个相互独立的弱决策树学习器,最后采用加权平均法或者投票法决定集成的输出。在DNN中同样可以使用Bagging的思路。不过和随机森林不同的是,这里不是若干个决策树,而是若干个DNN的网络。

首先对原始的m个训练样本进行有放回随机采样,构建N组m个样本的数据集,然后分别用这N组数据集训练DNN。即采用前向传播算法和反向传播算法得到N个DNN模型的W,b参数组合,最后对N个DNN模型的输出用加权平均法或者投票法决定最终输出。

不过用集成学习Bagging的方法有一个问题,就是DNN模型本来就比较复杂,参数很多。现在又变成了N个DNN模型,这样参数又增加了N倍,从而导致训练这样的网络要花更加多的时间和空间。因此一般N的个数不能太多,比如5-10个就可以了。

3. DNN通过dropout 正则化

Dropout指的是在用前向传播算法和反向传播算法训练DNN模型时,一批数据迭代时,随机的从全连接DNN网络中去掉一部分隐藏层的神经元。在对训练集中的一批数据进行训练时,随机去掉一部分隐藏层的神经元,并用去掉隐藏层的神经元的网络来拟合一批训练数据。如下图,去掉了一半的隐藏层神经元:

然后用这个去掉隐藏层的神经元的网络来进行一轮迭代,更新所有的W,b。

dropout并不意味着这些神经元永远的消失了。在下一批数据迭代前,会把DNN模型恢复成最初的全连接模型,然后再用随机的方法去掉部分隐藏层的神经元,接着去迭代更新W,b。当然,这次用随机的方法去掉部分隐藏层后的残缺DNN网络和上次的残缺DNN网络并不相同。

总结下dropout的方法: 每轮梯度下降迭代时,它需要将训练数据分成若干批,然后分批进行迭代,每批数据迭代时,需要将原始的DNN模型随机去掉部分隐藏层的神经元,用残缺的DNN模型来迭代更新W,b。每批数据迭代更新完毕后,要将残缺的DNN模型恢复成原始的DNN模型。

dropout和Bagging的正则化思路不同,dropout模型中的W,b是共享的,所有的残缺DNN迭代时,更新的是同一组W,b;而Bagging正则化时每个DNN模型有自己独有的一套W,b参数,相互之间是独立的。相同点是:每次使用基于原始数据集得到的分批的数据集来训练模型。

使用基于dropout的正则化比基于bagging的正则化简单,当然天下没有免费的午餐,由于dropout会将原始数据分批迭代,因此原始数据集最好较大,否则模型可能会欠拟合。

4. DNN通过增强数据集正则化

增强模型泛化能力最好的办法是有更多的训练数据,但是在实际应用中,更多的训练数据往往很难得到。有时候我们不得不去自己想办法无中生有,来增加训练数据集,进而得到让模型泛化能力更强的目的。


从感知机到神经网络

感知机是二分类的线性模型,假设训练数据集是线性可分的,感知机学习的目标是求得一个能够将训练数据集正负样本点正确分开的超平面使误分类的样本点到超平面的距离之和最小。这个模型只能用于二元分类,且无法学习比较复杂的非线性模型,因此在工业界无法使用。

将单个神经元的激活函数设为sign可以得到感知机;激活函数设为sigmoid,即可得到二分类的LR;将激活函数设为softmax可以得到多分类的LR,但需要注意的是:它们需要优化的损失函数并不相同,所以LR和感知机的不同体现在两点:激活函数和损失函数。

神经网络在感知机的模型上做了扩展,主要有三点:

  1. 加入了多层隐藏层,特征的“等级”随着网络深度的加深而变高,增强了模型的表达能力。
  2. 输出层神经元可以有多个输出,模型可以灵活的应用于分类,回归,降维和聚类等。
  3. 对激活函数做扩展。感知机的激活函数是sign(z),虽然简单但是处理能力有限,因此神经网络中一般使用:Sigmoid,Softmax,tanx, ReLU,softplus等激活函数,加入非线性因素,提高模型的表达能力。

深度神经网络(Deep Neural Networks,DNN)的基本结构

DNN可以分为:输入层,隐藏层和输出层,一般第一层是输入层,最后一层是输出层,而中间的层数都是隐藏层。层与层之间是全连接的,即第i层的任意一个神经元一定与第i+1层的任意一个神经元相连。

DNN前向传播算法

从输入层开始,利用输入向量x,若干个权重系数矩阵W和偏置向量b,进行一系列线性运算和激活运算,利用上一层的输出计算下一层的输出,一层层的向后计算,一直到运算到输出层得到输出结果

DNN反向传播算法(Back Propagation,BP)

反向传播算法的学习过程由正向传播和反向传播组成。在正向传播过程中,输入信息通过输入层,经隐藏层逐层处理并传向输出层。如果在输出层得不到期望的输出值,则取输出结果与样本标签误差的平方和作为目标函数,转入反向传播,通过对损失函数用梯度下降法进行迭代优化求极小值,找到合适的输出层和隐藏层对应的线性系数矩阵W,偏置向量b,网络的学习在权值修改过程中完成,误差达到所期望值时,网络学习结束。

DNN激活函数

为什么引入非线性激活函数

不用激活函数时,每一层输出都是上层输出的线性函数, 无论神经网络有多少层,输出都是输入的线性组合,与没有隐藏层效果相当,引入激活函数相当于加入非线性因素,可以有效避免多层网络等效于单层线性函数,提高模型表达力,使模型更有区分度。激活函数通常有如下一些性质:非线性(提高模型表达力),可微性(方便求梯度),单调性(损失函数为凸函数)

DNN常用的激活函数

梯度消失与梯度爆炸

在反向传播算法中,由于使用了矩阵求导的链式法则,后层的梯度以连乘方式叠加到前层,当神经网络中的激活函数为S型激活函数时,由于其饱和特性,在输入达到一定值的情况下,输出就不会发生明显变化,其导数逐渐趋近于0。使用梯度进行参数更新时,如果连乘的数字在每层都是小于1的,则梯度越往前乘越小,误差梯度反传到前层时几乎会衰减为0,因此无法对前层的参数进行有效的更新学习,这就会导致梯度消失,而如果连乘的数字在每层都是大于1的,则梯度越往前乘越大,导致梯度爆炸。梯度消失会导致隐层的W,b参数随着迭代的进行几乎没有大的改变,甚至不会收敛,因此无法通过加深网络层次来改善神经网络的预测效果。梯度爆炸会导致网络权重的大幅更新,引起网络不稳定,在极端情况下,权重的值变得非常大,以至于溢出,导致 NaN 值。

ReLU系列相对于Sigmoid和Tanh激活函数的优点是什么?它的缺点以及如何改进?

优点

  1. 从计算的角度上,Sigmoid和Tanh激活函数均需要计算指数,复杂度高,而ReLU只需要一个阈值即可得到激活值。
  2. 深层网络中,S型激活函数反向传播时容易出现梯度消失现象,ReLU的非饱和性可以有效地解决梯度消失的问题,提供相对宽的激活边界。
  3. ReLU的单侧抑制会使一部分神经元的输出为 0,提供了网络的稀疏表达能力,并且减少了参数的相互依存关系,可以缓解过拟合。

缺点
使用Relu激活函数在训练过程中Relu会导致神经元不可逆死亡。因为函数会导致负梯度在经过该ReLU单元时被置为0,且在之后也不被任何数据激活,即流经该神经元的梯度永远为0,不对任何数据产生响应。在实际训练中,如果学习率(Learning Rate)设置较大,会导致超过一定比例的神经元不可逆死亡,进而参数梯度无法更新,整个训练过程失败。                              

缺点的改进

为解决练过程中会导致神经元死亡的问题,人们设计了ReLU的变种LReLU( Leaky ReLU),其形式表示为:

LReLU与ReLU的区别在于:当z<=0时,其值不为0,而是一个斜率为a的线性函数,一般a为一个很小的正常数,这样既实现了单侧抑制,又保留了部分负梯度信息以致不完全丢失。但a值的选择增加了问题难度,需要较强的先验知识或多次重复训练以确定合适的参数值。

DNN损失函数

常用的损失函数有:平方误差损失函数,交叉熵损失函数,对数似然损失函数

对数似然损失是对预测概率的似然估计,其最小化的本质是利用样本中的已知分布,求解导致这种分布的最佳模型参数,使这种分布出现概率最大。它衡量的是预测概率分布和真实概率分布的差异性,取值越小越好。其标准形式为:

对数似然损失函数在二分类时可以化简为交叉熵损失函数。交叉熵表示两个概率分布之间的距离,交叉熵越大,两个概率分布距离越远,概率分布越相异;交叉熵越小,两个概率分布距离越近,概率分布越相似,通过交叉熵可以判断哪个预测结果与标准答案更接近。

交叉熵损失函数的计算公式为:

对数损失在多分类问题中的计算公式为:

平方误差损失函数和交叉熵损失函数分别适合什么场景?

一般来说,平方误差损失函数更适合输出为连续,并且最后一层不含Sigmoid或Softmax激活函数的神经网络;如果是使用Sigmoid或Softmax激活函数进行二分类或多分类的神经网络,使用交叉熵损失或对数似然损失会有更快的收敛速度。

推导平方误差损失函数相对于输出层的导数:其中最后一项σ′(z)为激活函数的导数。反向传播算法中,每一层向前递推都要乘以σ′(z),得到梯度变化值,当激活函数为S型函数时,如果z 的绝对值较大,函数会趋于饱和,即σ′(z)的绝对值非常小,导致W,b更新到极值的速度较慢,算法收敛速度较慢。当使用交叉熵损失函数时,相对于输出层的导数为:(也可以认为是残差),此时的导数是线性的,因此不会存在学习速度过慢的问题,而且其表示预测值与实际值的误差,误差越大时,梯度越大,参数w和b的调整就越快,训练的速度也就越快

将输出层的激活函数从Sigmoid之类的函数转变为Softmax激活函数可以使输出层神经元输出的值在0到1之间,同时所有输出值之和为1,可用于解决多分类问题。

DNN激活函数和损失函数小结:

  1. 如果神经元的输出是线性的,平方损失函数是一种合适的选择,如果输出神经元是S型激活函数,则交叉熵损失函数会有更快的收敛速度。
  2. softmax激活函数与对数似然损失的组合和sigmoid函数与交叉熵的组合相似,所以一般使用sigmoid激活函数与交叉熵进行二分类输出;使用softmax激活函数与对数似然损失进行DNN多分类输出。

正则化(L1&L2,Bagging,Dropout,数据扩充)

1. DNN的L1&L2正则化

假如每个样本的损失函数是均方差损失函数,则加上了L2正则化后的损失函数是(L1正则化类似):

其中,λ即正则化超参数,实际使用时需要调参。

2. DNN通过Bagging正则化

首先对原始的m个训练样本进行有放回随机采样,构建N组m个样本的数据集,然后分别用这N组数据集训练DNN。即采用前向传播算法和反向传播算法得到N个DNN模型的W,b参数组合,最后对N个DNN模型的输出用加权平均法或者投票法决定最终输出。

需要注意的是:DNN模型本来就比较复杂,参数很多。N个DNN模型集成,参数增加了N倍,导致训练网络要花更加多的时间和空间。N的取值一般为:5-10个。

3. DNN通过Dropout 正则化

Dropout(随机失活)是指在深度网络的训练中,将训练数据分成若干批,使用一批数据进行梯度下降迭代时,以一定的概率随机地 “临时丢弃”一部分神经元节点,然后用这个去掉隐藏层神经元的网络来拟合一批训练数据,并更新所有的权重和偏置(W,b)。在下一批数据迭代前,会把DNN模型恢复成最初的全连接模型,然后再用随机去掉部分隐藏层的神经元,迭代更新权重和偏置。

由于其随机丢弃部分神经元的机制,每次dropout都相当于训练了原始网络的子网络,它们共享部分权值,并且具有相同的网络层数,而模型整体的参数数目不变,这就大大简化了运算,而且这个过程会减弱神经元之间的依赖关系,减少过拟合,增强模型的泛化能力。(避免神经元相互连接,参数过多,将结果记住)

Bagging集成算法是多个模型的同时训练与测试评估,当网络与参数规模庞大时,需要消耗大量的运算时间与空间。Dropout在小批量数据集上进行操作,最后的结果相当于很多子网络的组合,这可以看做是bagging集成的近似,如果每次训练的子网络之间有一定的独立性,最后融合会降低模型的方差,增强模型的泛化能力。

Dropout和Bagging的正则化的异同

  • 不同点:dropout模型中的W,b是一套共享的,所有的残缺DNN迭代时,更新的是同一组W,b;而Bagging正则化时每个DNN模型有自己独有的一套W,b参数,相互之间是独立的。
  • 相同点:二者都是使用基于原始数据集分批得到的数据集来训练模型。

Dropout和 L1,L2的正则化的异同

二者的目的都是用来减少 overfitting(过拟合)。但 L1,L2正则化是针对损失函数进行优化,Dropout是改变神经网络本身的结构。

4. DNN通过扩充数据集正则化

减少模型过拟合,增强模型泛化能力最好的办法是有更多的训练数据。如:计算机视觉中可以使用图像数据增强技术。

深度学习输入数据归一化的原因(使数据处于同一数量级,具有相同的数据分布)

  1. 神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;
  2. 数据归一化可以在反向传播的过程中,加快网络中每一层权重参数的收敛速度。如果每批训练数据的分布各不相同,那么网络就要在每次迭代都去学习适应不同的数据分布,这样将会大大降低网络的训练速度

什么样的数据集不适合用深度学习?

  1. 数据集太小,深度学习容易产生过拟合。
  2. 数据集没有局部相关特性,目前深度学习表现比较好的领域主要是图像/语音/自然语言处理等领域,这些领域的一个共性是局部相关性。图像中像素组成物体,语音信号中音位组合成单词,文本数据中单词组合成句子,这些特征元素的组合一旦被打乱,表示的含义同时也被改变
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐