DNN模型与前向传播算法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yyl424525/article/details/89006109

1 初识神经网络

1.1 简介

在机器学习和认知科学领域,人工神经网络(artificial neural network,缩写ANN),简称神经网络(neural network,缩写NN)或类神经网络,是一种模仿生物神经网络(动物的中枢神经系统,特别是大脑)的结构和功能的数学模型或计算模型,用于对函数进行估计或近似。神经网络由大量的人工神经元联结进行计算。大多数情况下人工神经网络能在外界信息的基础上改变内部结构,是一种自适应系统。现代神经网络是一种非线性统计性数据建模工具。典型的神经网络具有以下三个部分:
(1)结构 (Architecture)
结构指定了网络中的变量和它们的拓扑关系。例如,神经网络中的变量可以是神经元连接的权重(weights)和神经元的激励值(activities of the neurons)。
(2)激励函数(Activity Rule) 大部分神经网络模型具有一个短时间尺度的动力学规则,来定义神经元如何根据其他神经元的活动来改变自己的激励值。一般激励函数依赖于网络中的权重(即该网络的参数)。
(3)学习规则(Learning Rule) 学习规则指定了网络中的权重如何随着时间推进而调整。这一般被看做是一种长时间尺度的动力学规则。一般情况下,学习规则依赖于神经元的激励值。它也可能依赖于监督者提供的目标值和当前权重的值。
神经网络就是将实例特征向量传入输入层,经过隐藏层,一系列的计算,最终可以得到输出层的结果。输入层后面的每一层可以通过上一层的加权求和再进行非线性方程转化得到。
这个加权求和是怎么做的呢?我们可以看到前一层与后一层单元之间有一些连线,每一条连线就对应一个权重,将前一层的单元与对应的权重相乘再相加,最后进行非线性方程转化就能得到后一层每个单元的值。每一层的输出是下一层的输入。
因为加权求和之后以后计算的方程是非线性的,所以理论上讲有一个很强大的功能,只要训练集足够大,隐藏层足够多,可以用神经网络模拟出任何方程,故神经网络既可以用来做分类(classification)问题,也可以解决回归(regression)问题。 90年代这个算法被人应用,但是当时大家觉得它的功能并不是很强大,那是因为当时的计算能力不高,一旦神经网络的层数多于3层,训练的时间就会非常长,效果也不好,而且因为互联网不普及数据集也很有限,所以神经网络的这个算法并不是一个很强的算法,当时站在巅峰的是SVM支持向量机。但是今天随着计算能力的大大增强以及数据集增大,神经网络为前身延伸出了的强大的深度学习,深度学习的强大就在于数据集和计算能力大大增强的情况下可以用更多的隐藏层模拟出更多的方程。

2 设计神经网络结构

使用神经网络训练数据之前,必须确定神经网络的层数,以及每层单元的个数。

2.1 输入层设计

(1) 特征向量在被传入输入层时通常被先标准化(normalize)到0和1之间 (为了加速学习过程)
(2)变量的类型既可以是离散型变量,也可以是连续型变量。
比如离散型变量的可以被编码,用几个单元分类别对应一个特征值可能被赋的值。举个例子:
特征值A可能取3个值(a0, a1, a2),可以用三个输入单元来表示A,假如A是a0, 三个单元是1,0,0,A是a1,三个单元是0,1,0。这样进行编码。
所以并不一定说输入层每一个单元对应特征向量的每一个特征值。

2.2 输出层设计

神经网络既可以用来做分类(classification)问题,也可以解决回归(regression)问题。回归问题与分类问题最大的区别就是它要预测的值不是像分类这样的离散值,而是连续型变量。
神经网络主要解决的是还是分类问题,对于分类问题,假如只有两类那么可以用1个输出单元表示,(分别用0,1表示两类),如果大于两类,那么有几类就用几个输出单元就行了。

2.3 隐藏层设计

对于隐藏层,目前没有一个明确的规则来确定到底有几层,一般是先确定一个层数,根据实验测试和误差,以及准确度来实验,慢慢改进。
在BP神经网络中,输入层和输出层的节点个数都是确定的,而隐含层节点个数不确定,那么应该设置为多少才合适呢?实际上,隐含层节点个数的多少对神经网络的性能是有影响的,有一个经验公式可以确定隐含层节点数目,如下

h = m + n + a h=\sqrt{m+n}+a
其中h为隐含层节点数目,为m输入层节点数目,n为输出层节点数目,a为1~10之间的调节常数。

3 从感知机到神经网络

感知机模型是一个有若干输入和一个输出的模型,可以看做是一个没有隐藏层的神经网络。输出和输入之间学习到一个线性关系,得到中间输出结果:

i = 1 m w i x i + b \sum_{i=1}^m w_ix_i+b

接着是一个神经元激活函数:
s i g n ( x ) = { + 1 , x 0 1 , x < 0 sign(x)=\left\{ \begin{aligned} +1,x \geq 0 \\ -1,x < 0 \\ \end{aligned} \right.
从而得到我们想要的输出结果1或者-1。
   这个模型只能用于二元分类,且无法学习比较复杂的非线性模型,因此在工业界无法使用。而神经网络则在感知机的模型上做了扩展,总结下主要有三点:
1)加入了隐藏层,隐藏层可以有多层,增强模型的表达能力,当然增加了这么多隐藏层模型的复杂度也增加了好多。
2)输出层的神经元也可以不止一个输出,可以有多个输出,这样模型可以灵活的应用于分类回归,以及其他的机器学习领域比如降维和聚类等。
3) 对激活函数做扩展,感知机的激活函数是sign(z),虽然简单但是处理能力有限,因此神经网络中一般使用的其他的激活函数,比如我们在逻辑回归里面使用过的Sigmoid函数,即: f ( x ) = 1 1 + e x f(x)=\frac{1}{1+e^{-x}} ,还有后来出现的tanx, softmax,和ReLU等。通过使用不同的激活函数,神经网络的表达能力进一步增强。对于各种常用的激活函数,我们在后面再专门讲。

4 深度神经网络模型DNN

深度神经网络(Deep Neural Networks, 以下简称DNN)是深度学习的基础,而要理解DNN,首先我们要理解DNN模型。DNN可以理解为有很多隐藏层的神经网络。DNN或者多层神经网络或者多层感知机(Multi-Layer perceptron, MLP)都是一个意思。从DNN按不同层的位置划分,DNN内部的神经网络层可以分为三类,输入层,隐藏层和输出层,如下图示例,一般来说第一层是输入层,最后一层是输出层,而中间的层数都是隐藏层。

层与层之间是全连接的,也就是说,第i层的任意一个神经元一定与第i+1层的任意一个神经元相连。虽然DNN看起来很复杂,但是从小的局部模型来说,还是和感知机一样,即一个线性关系 z = i = 1 m w i x i + b z=\sum_{i=1}^m w_i x_i+b 加上一个激活函数。
那么为什么要进行非线性变换呢?
(1)如果只进行线性变换,那么即使是多层的神经网络,依然只有一层的效果。类似于0.6×(0.2×1+0.3×2)=0.12×1+0.18×2。
(2)进行非线性变化,可以使得神经网络可以拟合任意一个函数,下图是一个四层网络的图。

由于DNN层数多,则我们的线性关系系数w和偏倚b的数量也就是很多了。具体的参数在DNN中定义如下:
w k j l w_{kj}^l 表示第l层的第j个神经元与上一层(l-1)的第k个神经元输出相对应的权重;
z j l z_j^l 表示第l层的第j个神经元的输入;
a j l a_j^l 表示第l层的第j个神经元的输出;
b j l b_j^l 表示第l层的第j个神经元的偏置;
L代表神经网络的层数;
W代表权重矩阵,Z代表输入矩阵,A代表输出矩阵,B代表偏置矩阵。

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

在上一节,我们已经介绍了DNN各层线性关系系数w,偏倚b的定义。假设我们选择的激活函数是σ(z),隐藏层和输出层的输入值为z,输出值为a,则对于下图的三层DNN,利用和感知机一样的思路,我们可以利用上一层的输出计算下一层的输出,也就是所谓的DNN前向传播算法。
对于第二层的的输出 a 1 2 , a 2 2 , a 3 2 a_1^2,a_2^2,a_3^2 ,我们有:
a 1 2 = σ ( z 1 2 ) = σ ( w 11 2 x 1 + w 12 2 x 2 + w 13 2 x 3 + b 1 2 ) a 2 2 = σ ( z 2 2 ) = σ ( w 21 2 x 1 + w 22 2 x 2 + w 23 2 x 3 + b 2 2 ) a 3 2 = σ ( z 3 2 ) = σ ( w 31 2 x 1 + w 32 2 x 2 + w 33 2 x 3 + b 3 2 ) a_1^2=\sigma(z_1^2)=\sigma(w_{11}^2x_1+w_{12}^2x_2+w_{13}^2x_3+b_1^2) \\ a_2^2=\sigma(z_2^2)=\sigma(w_{21}^2x_1+w_{22}^2x_2+w_{23}^2x_3+b_2^2)\\ a_3^2=\sigma(z_3^2)=\sigma(w_{31}^2x_1+w_{32}^2x_2+w_{33}^2x_3+b_3^2)

对于第三层的的输出` a 1 3 a_1^3 ,我们有:
a 1 3 = σ ( z 1 3 ) = σ ( w 11 3 a 1 2 + w 12 3 a 2 2 + w 13 3 a 3 2 + b 1 3 ) a_1^3=\sigma(z_1^3)=\sigma(w_{11}^3a_1^2+w_{12}^3a_2^2+w_{13}^3a_3^2+b_1^3)

将上面的例子一般化,假设第l−1层共有m个神经元,则对于第l层的第j个神经元的输出 a j l a_j^l ,我们有:

a j l = σ ( z j l ) = σ ( k = 1 m w j k l a k l 1 + b j l ) a_j^l=\sigma(z_j^l)=\sigma(\sum_{k=1}^m w_{jk}^l a_k^{l-1}+b_j^l)

其中,如果l=2,则对于的` a k l a_k^l 即为输入层的xk。

从上面可以看出,使用代数法一个个的表示输出比较复杂,而如果使用矩阵法则比较的简洁。假设第l−1层共有m个神经元,而第l层共有n个神经元,则第l层的线性系数w组成了一个n×m的矩阵 W l W^l ,第l层的偏倚b组成了一个n×1的向量 b l b^l , 第l−1层的的输出a组成了一个m×1的向量 a l 1 a^{l-1} ,第l层的的未激活前线性输出z组成了一个n×1的向量 z l z^l 第l层的的输出a组成了一个n×1的向量 a l a^l `。则用矩阵法表示,第l层的输出为:

a l = σ ( z l ) = σ ( W l a l 1 + b l ) a^l=\sigma(z^l)=\sigma(W^la^{l-1}+b^l)

这个表示方法简洁漂亮,后面我们的讨论都会基于上面的这个矩阵法表示来。

6 DNN前向传播算法

有了上一节的数学推导,DNN的前向传播算法也就不难了。所谓的DNN的前向传播算法也就是利用我们的若干个权重系数矩阵W,偏倚向量b来和输入值向量x进行一系列线性运算和激活运算,从输入层开始,一层层的向后计算,一直到运算到输出层,得到输出结果为值。
输入: 总层数L,所有隐藏层和输出层对应的矩阵W,偏倚向量b,输入值向量x
输出:输出层的输出 a L a^L
1) 初始化 a 1 = x a^1=x
2) for l=2 to L, 计算:
a l = σ ( z l ) = σ ( W l a l 1 + b l ) a^l=\sigma(z^l)=\sigma(W^la^{l-1}+b^l)
最后的结果即为输出 a L a^L :
a L = σ ( z L ) = σ ( W L a L 1 + b L ) a^L=\sigma(z^L)=\sigma(W^La^{L-1}+b^L)

猜你喜欢

转载自blog.csdn.net/yyl424525/article/details/89006109