深度学习(二)——神经网络基础(多层感知器、反向传播算法)

深度学习(二)——神经网络基础

神经网络的通用分类

人工神经网络模型可以理解为一组基本处理单元,它们紧密地相互连接,对输入进行类似的数学运算后生成期望的输出。基于信息在网络中传播的方式,可以将神经网络分为两个通用类别:

  1. 前馈神经网络
    前馈神经网络中信息的流动只能由前到后,也就是说,一层神经元的输出只能作为后一层神经元的输入。这些网络架构可以被称为有向无环图。典型的模型有多层感知器(MLP)卷积神经网络(CNN)
  2. 反馈神经网络
    反馈神经网络具有形成有向循环的连接,也就是说,后一层神经元也可以反过来作为前一层神经元的输入,这就使得神经网络可以处理序列数据。反馈网络还具有记忆能力,可以在其内部存储器中存储信息和序列关系。典型的模型有循环神经网络(RNN)长短期记忆网络(LSTM)

神经网络的基本结构

下面以多层感知器为例,介绍神经网络的基本结构。

基础架构

下图给出了MLP网络架构的一个例子:
在这里插入图片描述
这是一个五层感知器的例子,每一层分别含有3、4、2、3、3个人工神经元。我们用这个例子来介绍人工神经网络的一些特点:

分层架构:人工神经网络包含层次化的处理级别。每个级别被称为“网络层”,由许多人工神经元组成。网络层也可以细分为三种:

  • 第一层为输入层,用于接受数据输入。
  • 最后一层为输出层,用于产生输出数据并进行预测。
  • 其余层都被称为隐藏层或者隐含层,用于执行各种处理和运算。

人工神经元:每层中的基本处理单元被称为人工神经元。人工神经元存储了各个输入的权重和其特有的激活函数

密集连接:神经网络中的各个人工神经元是相互连接的,可以相互通信。前一层神经元的输出是后一层神经元的输入,这也是前馈神经网络的基本特征。并且,对于多层感知器,层中的每一个神经元都直接连接到前一个层的所有神经元。

人工神经元

下图给出了人工神经元的基本组成:
在这里插入图片描述
对于含有n个输入的人工神经元来说,它会进行如下的计算:

  1. 对n个输入加权求和,在必要的时候,我们会加入一个常数b作为偏置,这里计算得到的值称为激励值
  2. 对于加权求和后的结果,再通过激活函数运算后产生结果,再输出。

综合来说,单个人工神经元的输入是 a 1 a_1 a1- a n a_n an,输出为 f ( ∑ i = 1 n w i ⋅ a i + b ) f(\sum_{i=1}^{n}w_i\cdot a_i+b) f(i=1nwiai+b),写成向量形式为:
O u t p u t = f ( w ⃗ ⋅ a ⃗ ) Output=f(\vec{w}\cdot\vec{a}) Output=f(w a )
其中 w 0 = b , a 0 = 1 w_0=b,a_0=1 w0=b,a0=1。对于单个神经元来说,它的训练目标就是确定最优的 w w w b b b使得输出与真实值的误差最小。

激活函数

激活函数指的是一组非线性函数。它能够将非线性的特性引入神经网络,使得神经网络具备拟合各种非线性分类数据的能力。常用的激活函数主要有以下几个:

Sigmoid函数
逻辑回归中,曾经介绍过Sigmoid函数,它的基本数学公式如下:
f ( x ) = 1 1 + e − x f(x)=\frac{1}{1+e^{-x}} f(x)=1+ex1
图像如下:
在这里插入图片描述
Tanh函数
Tanh函数是双曲函数的一种,它和Sigmoid函数具有类似的图像,只不过将值域扩展到了(-1,1)。
f ( x ) = e x − e − x e x + e − x f(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}} f(x)=ex+exexex
图像如下:
在这里插入图片描述
ReLU函数
线性修正单元激活函数(ReLU函数)是一种改进的激活函数,可以解决Sigmoid函数的一些问题,在这篇博文的最后我们将会对其进行讨论。Relu函数的公式如下:
f ( x ) = { x , x > 0 0 , x ≤ 0 f(x)=\left\{\begin{aligned} x,x>0\\ 0,x\leq0 \end{aligned}\right. f(x)={x,x>00,x0
函数图像如下:
在这里插入图片描述


模型训练与反向传播算法

和机器学习相同,多层感知器的模型训练基本思想也是首先定义损失函数,然后利用梯度下降法及其变种算法进行迭代训练,直到参数不再变化或变化极小。一般可采用的损失函数有MSE、SVM铰链损失函数、交叉熵等。这里给出最常用的MSE的损失函数形式:
M S E : E = 1 2 ∑ n ( y n − y ^ n ) 2 MSE:E=\frac{1}{2}\sum_n(y_n-\hat{y}_n)^2 MSE:E=21n(yny^n)2
人工神经网络和一般的机器学习模型不同,人工神经网络是多层的,可以认为是很多个机器学习基本模型的连接,因此在求解梯度上存在一定的特殊性。因此,人工神经网络的训练方法被称为反向传播算法,在初始化权重后,反向传播算法分为两个步骤:

  1. 前向传播
  2. 反向传播

前向传播

所谓前向传播,实际上也是模型训练完成后的预测过程。数据从输入层输入,然后一层一层地进行运算,直到最后在输出层得到一个最终预测输出 y ^ \hat{y} y^

举一个简单的例子说明这个过程,假设我们有一个含两个隐含层和一个输出层的多层感知器,并且每一层只含有一个神经元,输入层也只有一个神经元(即输入数据只有一维),连接情况及各层的权重如图所示:
在这里插入图片描述
接下来依次计算:

  • 第一层为输入层,输入输出都为 A 0 A_0 A0.
  • 第二层为隐含层,输入 A 0 A_0 A0,输出 A 1 = f ( w 1 A 0 ) A_1=f(w_1A_0) A1=f(w1A0).
  • 第三层为隐含层,输入 A 1 A_1 A1,输出 A 2 = f ( w 2 A 1 ) A_2=f(w_2A_1) A2=f(w2A1).
  • 第四层为输出层,输入 A 2 A_2 A2,输出 A 3 = f ( w 3 A 2 ) A_3=f(w_3A_2) A3=f(w3A2).

就这样逐层进行计算,最终的计算结果 A 3 A_3 A3就是模型的输出 y ^ \hat{y} y^,可以用于预测和训练模型。含有多个神经元的网络也是如此。

反向传播

经过权重初始化和前向传播后,我们可以得到网络中的所有参数以及中间运算结果,接下来我们就要根据误差即损失函数的情况,更新模型中的权重,这个步骤被称为反向传播。前向传播和反向传播合起来称为模型的一轮训练过程。

在阐述具体过程前,让我们回顾一下梯度下降算法的参数迭代公式:
θ n + 1 = θ n − η ∂ L ∂ θ n \theta_{n+1}=\theta_n-\eta\frac{\partial L}{\partial\theta_n} θn+1=θnηθnL
这个迭代公式对于单层的感知器和输出层也是适用的。但对于多层的感知器,我们需要从最后一层输出层开始,一层一层向前计算梯度、更新参数,这也是“反向传播”这个名称的由来。

接下来我们用一个简单的例子来推导反向传播算法的参数迭代公式。仍然使用上面用的这个例子:
在这里插入图片描述
假设使用MSE作为损失函数,只考虑一个样本(多个样本的情况只是对多个样本进行求和),并且神经元中不加入偏置(偏置实际上只是多一维输入)。损失函数如下:
L ( w 1 , w 2 , w 3 ) = 1 2 ( y ^ − y ) 2 L(w_1,w_2,w_3)=\frac{1}{2}(\hat{y}-y)^2 L(w1,w2,w3)=21(y^y)2 ∂ L ∂ y ^ = y ^ − y \frac{\partial L}{\partial\hat{y}}=\hat{y}-y y^L=y^y
我们必须要明确的一点是,我们的训练目标是找到最优的 w 1 w_1 w1, w 2 w_2 w2, w 3 w_3 w3使得误差最小,我们要更新的模型参数也是这三个,因此,根据梯度下降法的基本思想,我们需要求出损失函数对它们三者的偏导数,忽略输入层,由链式法则,从最后一层开始逐层计算如下:
第 三 层 : ∂ L ∂ w 3 = ∂ L ∂ A 3 ∂ A 3 ∂ D 3 ∂ D 3 ∂ w 3 = ( y ^ − y ) f ′ ( D 3 ) A 2 = δ 3 A 2 第 二 层 : ∂ L ∂ w 2 = ∂ L ∂ A 2 ∂ A 2 ∂ D 2 ∂ D 2 ∂ w 2 = δ 3 w 3 ⋅ f ′ ( D 2 ) A 1 = δ 2 A 1 第 一 层 : ∂ L ∂ w 1 = ∂ L ∂ A 1 ∂ A 1 ∂ D 1 ∂ D 1 ∂ w 1 = δ 2 w 2 ⋅ f ′ ( D 1 ) A 0 = δ 1 A 0 \begin{aligned} 第三层:\frac{\partial L}{\partial w_3}=\frac{\partial L}{\partial A_3}\frac{\partial A_3}{\partial D_3}\frac{\partial D_3}{\partial w_3}=(\hat{y}-y)f^{'}(D_3)A_2=\delta_3A_2\\ 第二层:\frac{\partial L}{\partial w_2}=\frac{\partial L}{\partial A_2}\frac{\partial A_2}{\partial D_2}\frac{\partial D_2}{\partial w_2}=\delta_3w_3\cdot f^{'}(D_2)A_1=\delta_2A_1\\ 第一层:\frac{\partial L}{\partial w_1}=\frac{\partial L}{\partial A_1}\frac{\partial A_1}{\partial D_1}\frac{\partial D_1}{\partial w_1}=\delta_2w_2\cdot f^{'}(D_1)A_0=\delta_1A_0 \end{aligned} w3L=A3LD3A3w3D3=(y^y)f(D3)A2=δ3A2w2L=A2LD2A2w2D2=δ3w3f(D2)A1=δ2A1w1L=A1LD1A1w1D1=δ2w2f(D1)A0=δ1A0
由上面的公式不难看出,对于 ∂ L ∂ w i \frac{\partial L}{\partial w_i} wiL δ i \delta_i δi之间存在一些递推关系:
∂ L ∂ w i = δ i A i − 1 δ i = δ i + 1 w i + 1 f ′ ( D i ) \begin{aligned} \frac{\partial L}{\partial w_i}=\delta_iA_{i-1}\\ \delta_i=\delta_{i+1}w_{i+1}f^{'}(D_i)\\ \end{aligned} wiL=δiAi1δi=δi+1wi+1f(Di)
有了上面这个重要结论,我们将它进行推广。考虑一层中含有多个神经元的情况,由于在单个神经元中,我们对多个输入的处理是进行加和,所以在求导时,正确的处理也是进行求和。另外要明确的是,一个神经元应当对应一个 δ \delta δ。这样我们可以把反向传播算法的递推关系公式推广到普遍情况:

对于第 i i i层第 j j j个神经元,它的误差信号记作 δ j i \delta_j^i δji,设它的激活函数为 f ( x ) f(x) f(x),有 m m m个输入记作 x 1 , . . . , x m x_1,...,x_m x1,...,xm,权重分别为 w 1 , . . . , w m w_1,...,w_m w1,...,wm,它的激励值为 a j i = x 1 w 1 + . . . + x m w m a_j^i=x_1w_1+...+x_mw_m aji=x1w1+...+xmwm。后一层有 n n n个神经元,第 k k k个神经元具有 δ k i + 1 \delta^{i+1}_k δki+1,对于 δ j i \delta_j^i δji神经元输入的权重为 w k ′ w^{'}_k wk。它的 δ j i \delta_j^i δji有着这样的递推关系:
δ j i = f ′ ( a j i ) ∑ k = 1 n w k ′ δ k i + 1 \delta_j^i=f^{'}(a_j^i)\sum_{k=1}^{n}w^{'}_k\delta^{i+1}_k δji=f(aji)k=1nwkδki+1
对于一个输入 x k x_k xk和它对应的权重 w k w_k wk,一次训练的参数更新公式如下:
w k : = w k − η δ j i x k w_k:=w_k-\eta\delta_j^ix_k wk:=wkηδjixk
其中 : = := :=为赋值符号, η \eta η称为学习率。完整的学习过程将会包含很多次迭代,直到损失函数达到收敛。


梯度消失和梯度爆炸

反向传播算法成功地应用于各种神经的情况。但由于每一层之间使用链式法则即乘法进行传播,这就意味着每一层的梯度是指数级别增长的。当网络很深时,学习过程时可能会遭受梯度消失梯度爆炸的问题,这主要取决于激活函数的选择

当梯度较小时,可能会产生梯度消失问题。以sigmoid函数为例,sigmoid函数的导数最大值约为0.25。考虑一个5层的网络,传递到第一层时,梯度将会衰减为 ( 0.25 ) 5 = 0.0009 (0.25)^5=0.0009 (0.25)5=0.0009,我们知道,当小数过小超出表示精度时,计算机会将它作为机器零来处理,因此就会导致初始几层的参数基本不会更新。这就是梯度消失问题。

同样的,当梯度较大时,可能会产生梯度爆炸问题。当输出层梯度大于1时,经过多层传递,很可能导致前几层的梯度非常巨大,每一次训练参数变化很大,使得模型训练困难,也很容易“走”出合理的区域。

梯度消失和梯度爆炸问题的一个解决方案是改进激活函数。一种改进的激活函数就是前面介绍的ReLU函数。它的一大特点是未激活时梯度为0,激活后梯度恒为1,由于0和1在指数运算时的不变性,就可以有效地防止梯度消失和梯度爆炸问题。

另外还有一种解决方案是梯度裁剪。简要地说就是设定一个阈值,如果求出来的梯度大于这个阈值,我们就将梯度强行缩减为等于阈值。这样也可以防止梯度爆炸问题。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值