深度学习(二)——神经网络基础
神经网络的通用分类
人工神经网络模型可以理解为一组基本处理单元,它们紧密地相互连接,对输入进行类似的数学运算后生成期望的输出。基于信息在网络中传播的方式,可以将神经网络分为两个通用类别:
- 前馈神经网络
前馈神经网络中信息的流动只能由前到后,也就是说,一层神经元的输出只能作为后一层神经元的输入。这些网络架构可以被称为有向无环图。典型的模型有多层感知器(MLP)和卷积神经网络(CNN)。 - 反馈神经网络
反馈神经网络具有形成有向循环的连接,也就是说,后一层神经元也可以反过来作为前一层神经元的输入,这就使得神经网络可以处理序列数据。反馈网络还具有记忆能力,可以在其内部存储器中存储信息和序列关系。典型的模型有循环神经网络(RNN)和长短期记忆网络(LSTM)。
神经网络的基本结构
下面以多层感知器为例,介绍神经网络的基本结构。
基础架构
下图给出了MLP网络架构的一个例子:
这是一个五层感知器的例子,每一层分别含有3、4、2、3、3个人工神经元。我们用这个例子来介绍人工神经网络的一些特点:
分层架构:人工神经网络包含层次化的处理级别。每个级别被称为“网络层”,由许多人工神经元组成。网络层也可以细分为三种:
- 第一层为输入层,用于接受数据输入。
- 最后一层为输出层,用于产生输出数据并进行预测。
- 其余层都被称为隐藏层或者隐含层,用于执行各种处理和运算。
人工神经元:每层中的基本处理单元被称为人工神经元。人工神经元存储了各个输入的权重和其特有的激活函数。
密集连接:神经网络中的各个人工神经元是相互连接的,可以相互通信。前一层神经元的输出是后一层神经元的输入,这也是前馈神经网络的基本特征。并且,对于多层感知器,层中的每一个神经元都直接连接到前一个层的所有神经元。
人工神经元
下图给出了人工神经元的基本组成:
对于含有n个输入的人工神经元来说,它会进行如下的计算:
- 对n个输入加权求和,在必要的时候,我们会加入一个常数b作为偏置,这里计算得到的值称为激励值。
- 对于加权求和后的结果,再通过激活函数运算后产生结果,再输出。
综合来说,单个人工神经元的输入是-,输出为,写成向量形式为:
其中。对于单个神经元来说,它的训练目标就是确定最优的和使得输出与真实值的误差最小。
激活函数
激活函数指的是一组非线性函数。它能够将非线性的特性引入神经网络,使得神经网络具备拟合各种非线性分类数据的能力。常用的激活函数主要有以下几个:
Sigmoid函数:
在逻辑回归中,曾经介绍过Sigmoid函数,它的基本数学公式如下:
图像如下:
Tanh函数:
Tanh函数是双曲函数的一种,它和Sigmoid函数具有类似的图像,只不过将值域扩展到了(-1,1)。
图像如下:
ReLU函数:
线性修正单元激活函数(ReLU函数)是一种改进的激活函数,可以解决Sigmoid函数的一些问题,在这篇博文的最后我们将会对其进行讨论。Relu函数的公式如下:
函数图像如下:
模型训练与反向传播算法
和机器学习相同,多层感知器的模型训练基本思想也是首先定义损失函数,然后利用梯度下降法及其变种算法进行迭代训练,直到参数不再变化或变化极小。一般可采用的损失函数有MSE、SVM铰链损失函数、交叉熵等。这里给出最常用的MSE的损失函数形式:
人工神经网络和一般的机器学习模型不同,人工神经网络是多层的,可以认为是很多个机器学习基本模型的连接,因此在求解梯度上存在一定的特殊性。因此,人工神经网络的训练方法被称为反向传播算法,在初始化权重后,反向传播算法分为两个步骤:
- 前向传播
- 反向传播
前向传播
所谓前向传播,实际上也是模型训练完成后的预测过程。数据从输入层输入,然后一层一层地进行运算,直到最后在输出层得到一个最终预测输出。
举一个简单的例子说明这个过程,假设我们有一个含两个隐含层和一个输出层的多层感知器,并且每一层只含有一个神经元,输入层也只有一个神经元(即输入数据只有一维),连接情况及各层的权重如图所示:
接下来依次计算:
- 第一层为输入层,输入输出都为.
- 第二层为隐含层,输入,输出.
- 第三层为隐含层,输入,输出.
- 第四层为输出层,输入,输出.
就这样逐层进行计算,最终的计算结果就是模型的输出,可以用于预测和训练模型。含有多个神经元的网络也是如此。
反向传播
经过权重初始化和前向传播后,我们可以得到网络中的所有参数以及中间运算结果,接下来我们就要根据误差即损失函数的情况,更新模型中的权重,这个步骤被称为反向传播。前向传播和反向传播合起来称为模型的一轮训练过程。
在阐述具体过程前,让我们回顾一下梯度下降算法的参数迭代公式:
这个迭代公式对于单层的感知器和输出层也是适用的。但对于多层的感知器,我们需要从最后一层输出层开始,一层一层向前计算梯度、更新参数,这也是“反向传播”这个名称的由来。
接下来我们用一个简单的例子来推导反向传播算法的参数迭代公式。仍然使用上面用的这个例子:
假设使用MSE作为损失函数,只考虑一个样本(多个样本的情况只是对多个样本进行求和),并且神经元中不加入偏置(偏置实际上只是多一维输入)。损失函数如下:
我们必须要明确的一点是,我们的训练目标是找到最优的,,使得误差最小,我们要更新的模型参数也是这三个,因此,根据梯度下降法的基本思想,我们需要求出损失函数对它们三者的偏导数,忽略输入层,由链式法则,从最后一层开始逐层计算如下:
由上面的公式不难看出,对于和之间存在一些递推关系:
有了上面这个重要结论,我们将它进行推广。考虑一层中含有多个神经元的情况,由于在单个神经元中,我们对多个输入的处理是进行加和,所以在求导时,正确的处理也是进行求和。另外要明确的是,一个神经元应当对应一个。这样我们可以把反向传播算法的递推关系公式推广到普遍情况:
对于第层第个神经元,它的误差信号记作,设它的激活函数为,有个输入记作,权重分别为,它的激励值为。后一层有个神经元,第个神经元具有,对于神经元输入的权重为。它的有着这样的递推关系:
对于一个输入和它对应的权重,一次训练的参数更新公式如下:
其中为赋值符号,称为学习率。完整的学习过程将会包含很多次迭代,直到损失函数达到收敛。
梯度消失和梯度爆炸
反向传播算法成功地应用于各种神经的情况。但由于每一层之间使用链式法则即乘法进行传播,这就意味着每一层的梯度是指数级别增长的。当网络很深时,学习过程时可能会遭受梯度消失和梯度爆炸的问题,这主要取决于激活函数的选择。
当梯度较小时,可能会产生梯度消失问题。以sigmoid函数为例,sigmoid函数的导数最大值约为0.25。考虑一个5层的网络,传递到第一层时,梯度将会衰减为,我们知道,当小数过小超出表示精度时,计算机会将它作为机器零来处理,因此就会导致初始几层的参数基本不会更新。这就是梯度消失问题。
同样的,当梯度较大时,可能会产生梯度爆炸问题。当输出层梯度大于1时,经过多层传递,很可能导致前几层的梯度非常巨大,每一次训练参数变化很大,使得模型训练困难,也很容易“走”出合理的区域。
梯度消失和梯度爆炸问题的一个解决方案是改进激活函数。一种改进的激活函数就是前面介绍的ReLU函数。它的一大特点是未激活时梯度为0,激活后梯度恒为1,由于0和1在指数运算时的不变性,就可以有效地防止梯度消失和梯度爆炸问题。
另外还有一种解决方案是梯度裁剪。简要地说就是设定一个阈值,如果求出来的梯度大于这个阈值,我们就将梯度强行缩减为等于阈值。这样也可以防止梯度爆炸问题。
来源:CSDN
作者:石烨
链接:https://blog.csdn.net/qq_43371810/article/details/104048076