前馈神经网络(FNN)

前馈神经网络(FNN)

期末复习整理资料


神经元模型

人工神经元(Artificial Neuron),简称神经元(Neuron),是构成神经网络 的基本单元,其主要是模拟生物神经元的结构和特性,接收一组输入信号并产生输出.

生物神经元是有多个树突和一个轴突,树突拿来接收信息,轴突发送信息,树突的信息超过一定阈值就会神经元兴奋,将信号传递出去

所以神经元模型就是接受来自其他神经元的输入,然后将这些输入经过带权重的连接进行传递,神经元再和自己的阈值作比较,最后通过激活函数进行输出

MP神经元

最早的神经元是MP神经元:与现在神经元无太多区别,不过MP神经元中的激活函数𝑓为0或1的阶跃函数,而现代神经元中的激活函数通常要求是连续可导的函数

image-20231226142154791

激活函数

假设一个神经元接收𝐷 个输入𝑥1 , 𝑥2 , ⋯ , 𝑥𝐷,令向量𝒙 = [𝑥1 ; 𝑥2 ; ⋯ ; 𝑥𝐷]来 表示这组输入, 净输入也叫净活性值 (Net Activation). 并用净输入(Net Input)𝑧 ∈ ℝ表示一个神经元所获得的输入信 号𝒙的加权和

z=d=1Dωdxd+bz = \sum_{d=1}^{D}\omega_dx_d+b

z=ωTx+bz=\omega^Tx+b

其中ω\omega= [ω1\omega_1 ;ω2\omega_2; ⋯ ; ωD\omega_D] ∈ R𝐷ℝ^𝐷 是是D维的权重向量,𝑏 ∈ ℝ是偏置

净输入𝑧在经过一个非线性函数𝑓(⋅)后,得到神经元的活性值(Activation)a

a=f(z)a = f(z)

其中这个非线性f()f( )函数就是激活函数

激活函数的性质

  1. 连续可导的非线性函数,可导的激活函数 可以直接利用数值优化的方法来学习网络参数
  2. 激活函数及其导函数要尽可能的简单,有利于提高网络计算效率
  3. 激活函数的导函数的值域要在一个合适的区间内,不能太大也不能太 小,否则会影响训练的效率和稳定性

Sigmoid函数

Sigmoid 型函数是指一类 S 型曲线函数,为两端饱和函数.常用的 Sigmoid 型函数有Logistic函数和Tanh函数.

饱和就是,x趋近于无穷时,函数导数近似于0,这就是饱和

Logistic函数

函数定义

σ(x)=11+ex\sigma(x)=\frac{1}{1+e^{-x}}

Logistic 函数可以看成是一个“挤压”函数,把一个实数域的输入“挤压”到 (0, 1).当输入值在0附近时,Sigmoid型函数近似为线性函数;当输入值靠近两端时,对输入进行抑制.输入越小,越接近于 0;输入越大,越接近于 1.这样的特点也和生物神经元类似,对一些输入会产生兴奋(输出为1),对另一些输入产生抑制(输出为0).和感知器使用的阶跃激活函数相比,Logistic函数是连续可导的, 其数学性质更好.

性质:

  1. 其输出直接可以看作概率分布,使得神经网络可以更好地和统计学习模型进行结合
  2. 其可以看作一个软性门(Soft Gate),用来控制其他神经元输出信息的数量.
Tanh函数

函数定义

tanh(x)=exexex+extanh(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}}

Tanh函数可以看成放大版的Logistic函数,其值域是(−1, 1).Tanh 函数的输出是零中心化的(Zero-Centered),而 Logistic 函数的输出恒大于 0.非零中心化的输出会使得其后一层的神经元的输入发生偏置偏移(Bias Shift),并进一步使得梯度下 降的收敛速度变慢

image-20231226004343019

Hard-Logistic函数和Hard-Tanh函数(PPT上无)

其实也就是Logistic函数和Tanh函数的分段函数形式,用分段函数来近似

ReLU函数

ReLU函数是目前深度神经网络中经常使用的激活函数. ReLU实际上是一个斜坡(ramp)函数

函数定义

ReLU(x)={xx>=00x<0=max(0,x)ReLU(x)=\begin{cases} x\quad x>=0\\ 0\quad x<0\\ \end{cases} \quad = max(0,x)

优点

采用 ReLU 的神经元只需要进行加、乘和比较的操作,计算上更加高效. ReLU 函数也被认为具有生物学合理性(Biological Plausibility),Sigmoid 型激活函数会导致一个非稀疏的神经网络,而 ReLU 却具有很好的稀疏性,大约50%的神经元会处于激活状态.

相比于Sigmoid型函数的两端饱和,ReLU函数为左饱和函数, 且在 𝑥 > 0 时导数为 1,在一定程度上缓解了神经网络的梯度消失问题,加速梯度下降的收敛速度.

缺点

ReLU 函数的输出是非零中心化的,给后一层的神经网络引入偏置偏移,会影响梯度下降的效率. 此外,ReLU 神经元在训练时比较容易“死亡”.在训练时,如果参数在一次不恰当的更新后,第一个隐藏层中的某个 ReLU 神经元在所有的训练数据上都不能被激活,那么这个神经元自身参数的梯度永远都会是0,在以后的训练过程中永远不能被激活.这种现象称为死亡 ReLU 问题

所以有很多ReLU变式

带泄露的ReLU

带泄露的ReLU(Leaky ReLU)在输入 𝑥 < 0时,保持一个很小的梯度𝛾.这样当神经元非激活时也能有一个非零的梯度可以更新参数,避免永远不能被激活,用于解决ReLU的"死神经元"问题。

函数定义

LeakyReLU={xifx>0γxifx<=0=max(0,x)+γmin(0,x)LeakyReLU=\begin{cases} x\quad if\quad x>0\\ \gamma x\quad if \quad x<=0\\ \end{cases} \quad = max(0,x)+\gamma min(0,x)

γ\gamma是一个很小的常数

带参数的ReLU

带参数的 ReLU(Parametric ReLU,PReLU)引入一个可学习的参数,不同神经元可以有不同的参数 .对于第 𝑖 个神经元,其 PReLU 的 定义为

PReLUi(x)={xifx>0γixifx<=0=max(0,x)+γimin(0,x)PReLU_i(x)=\begin{cases} x \quad if\quad x>0\\ \gamma_ix \quad if x<=0 \end{cases}\quad=max(0,x)+\gamma_imin(0,x)

其中 𝛾𝑖 为 𝑥 ≤ 0 时函数的斜率.因此,PReLU 是非饱和函数.如果 𝛾𝑖 = 0,那么 PReLU就退化为ReLU.如果𝛾𝑖 为一个很小的常数,则PReLU可以看作带泄露的 ReLU.PReLU 可以允许不同神经元具有不同的参数,也可以一组神经元共享一 个参数.

ELU函数

近似的零中心化的非线性函数,其定义为

ELU(x)={xifx>0γexp((x)1)ifx<=0=max(0,x)+γmin(0,ex1)ELU(x)=\begin{cases} x \quad if\quad x>0\\ \gamma exp((x)-1) \quad if x<=0 \end{cases}\quad=max(0,x)+\gamma min(0,e^{x-1})

其中 𝛾 ≥ 0是一个超参数,决定𝑥 ≤ 0时的饱和曲线,并调整输出均值在0附近

Softplus函数

Softplus 函数可以看作 ReLU函数的平滑版本,其 定义为

Softplus(x)=ln(1+ex)\text{Softplus}(x) = \ln(1 + e^x)

Softplus函数其导数刚好是Logistic函数.Softplus函数虽然也具有单侧抑制、宽兴奋边界的特性,却没有稀疏激活性.

image-20231226141028410

Swish函数

Swish函数是一种自门控激活函数,被提出是作为ReLU函数的替代

定义

swish(x)=xσ(βx)swish(x)=x\sigma(\beta x)

其中σ()\sigma ()为 Logistic 函数,β\beta为可学习的参数或一个固定超参数.σ()\sigma () ∈ (0, 1) 可 以看作一种软性的门控机制.当σ(βx)\sigma(\beta x)接近于1时,门处于“开”状态,激活函数的输出近似于𝑥 本身;当σ(βx)\sigma(\beta x)接近于0时,门的状态为“关”,激活函数的输出近似于0

image-20231226141645809

当𝛽 = 0时,Swish函数变成线性函数𝑥/2.当𝛽 = 1时,Swish函数在𝑥 > 0时近似线性,在 𝑥 < 0 时近似饱和,同时具有一定的非单调性.当 𝛽 → +∞ 时,𝜎(𝛽𝑥)趋向于离散的0-1函数,Swish函数近似为ReLU函数.因此,Swish函数可以看作线性函数和ReLU函数之间的非线性插值函数,其程度由参数𝛽 控制

Softmax函数

主要用于处理多分类问题的输出层。它的主要作用是将一个实数向量转换为一个概率分布。

给定一个实数向量 z=[z1,z2,...zk]z=[z_1,z_2,...z_k],其中 zkz_k 是类别的数量,Softmax函数将这个向量转换为一个概率分布,每个元素的值介于0和1之间,并且所有元素的总和为1。Softmax函数对于第 i个元素的计算公式是:

Softmax=ezik=1KezkSoftmax=\frac{e^{z_i}}{\sum_{k=1}^{K}e^{z_k}}

这里,ezie^{z_i}ziz_i的自然指数。分母是所有类别自然指数的总和,确保了输出的归一化。

Softmax函数输出一个概率分布,每个输出值代表输入属于某个类别的概率,易于解释

在训练过程中,Softmax函数通常与交叉熵损失(Cross-Entropy Loss)结合使用,以有效地计算误差并进行梯度下降

image-20231226145656774


多层感知机

感知机

感知器是随着神经元模型(MCP)提出之后,有人基于这个模型提出了感知器。

它能先自动学习最优的权重系数,再乘以输入特征。继而做出神经元是否触发的决策。在监督学习和分类的场景下,可以用来预测新数据点的类别归属。感知机只有一个神经元

image-20231226150147133

感知机学习规则

  1. 把权重初始化成0或者小的随机数
  2. 分别对每个训练样本x(i)x^{(i)}
    1. 计算输出值y^\hat{y}
    2. 更新权重

输出值就是预先设置好的分类标签,更新权重向量ww的每个值wjw_j,更准确的表达式为:

wj:=wj+Δwjw_j:=wj+\Delta w_j

Δwj\Delta w_j就是权重向量更新的值Δwj\Delta w_j的计算公式为:

Δwj=η(yy^)xi\Delta w_j=\eta(y-\hat{y})x_i

这里面的η\eta被称为学习率,值在(0,1)只有学习率够小时,模型的收敛才能能到保证

yy为第ii个样本正确的分类,y^\hat{y}是预测的分类。

若感知机对训练样例预测正确, 则感知机不发生变化;否则根据错误程度进行权重的调整.

感知机的输出值的公式为

y=f(i=1nwixiθ)y=f(\sum^{n}_{i=1}w_ix_i-\theta)

xix_i是输入,wiw_i是权重参数,θ\theta是模型的阈值,ff通常设为符号函数,yy可以进一步表示为

y=sign(wTxθ)={1,wTxθ>=00,wTxθ<0y=sign(w^Tx-\theta)= \begin{cases} 1,\quad w^Tx-\theta >=0\\ 0,\quad w^Tx-\theta < 0 \end{cases}

可以在n维空间展开为

y=f(wTxθ)=f(w1x1+w2x2+w3x3+...+wnxn+b)y=f(w^Tx-\theta)=f(w_1x_1+w_2x_2+w_3x_3+...+w_nx_n+b)

wTxθw^Tx-\theta可以看作一个超平面,将n维空间划分为wTxθw^Tx-\theta>=0和wTxθw^Tx-\theta<0两个子空间,来实现分类

PPT上用了与或非讲解二分类,用异或讲解三分类问题,引出感知机和多层网络

image-20231226160943124

感知机和多层网络

对于上述提到的问题,老师是这么描述的若两类模式线性可分, 则感知机的学习过程一定会收敛;否感知机的学习过程将会发生震荡,单层感知机的学习能力非常有限, 只能解决线性可分问题,事实上, 与、或、非问题是线性可分的, 因此感知机学习过程能够求得适当的权值向量. 而异或问题不是线性可分的, 感知机学习不能求得合适解。

多层感知机(MLP)

image-20231226161355726

输出层与输入层之间的一层神经元, 被称之为隐层或隐含层, 隐含层和输出层神经元都是具有激活函数的功能神经元。多层感知机也就是包含隐藏层的神经网络,是一种基础的前馈神经网络模型

其特点就是,每层神经元与下一层神经元全互联, 神经元之间不存在同层连接也不存在跨层连接

这里面有些关键概念:

前馈:输入层接受外界输入, 隐含层与输出层神经元对信号进行加工, 最终结果由输出层神经元输出

学习:根据训练数据来调整神经元之间的“连接权”以及每个功能神经元的“阈值”

image-20231226162323591

加速模型学习的技巧就是梯度下降


反向传播算法(BP算法)

前馈神经网络概念

使用神经网络的路线进行模拟人脑的,到目前为止有三种常用的神经网络结构:前馈网络、记忆网络、图网络。

其中,前馈网络中各个神经元按接收信息的先后分为不同的组.每一组可以看作一个神经层.每一层中的神经元接收前一层神经元的输出,并输出到下一层神经元.(与多层感知机的概念对应)整个网络中的信息是朝一个方向传播,没有反向的信息传播,可以用一个有向无环路图表示.前馈网络包括全连接前馈网络和卷积神经网络等.

其他两种暂不介绍

image-20231226163933745

前馈神经网络本质上就是多层感知机,但是多层感知机又不太准确,因为前馈神经网络是由多层的 Logistic 回归模型(连续的非线性函数)组成,而不是由多层的感知器(不连续的非线性函数)组成。

前馈神经网络进行机器学习的过程就是:向前传播->损失计算->反向传播->更新参数

反向传播算法就是反向传播重要的一环

前馈神经网络参数数目计算(感觉肯定要考)

要优化的参数数目为:权重数+偏置数

偏置数为:隐藏层神经元数 + 输出层神经元数

假设第ii层有nin_i个神经元,第i+1i+1层就有ni+1n_{i+1}个神经元

这两层的权重为nini+1n_i*n_{i+1}

反向传播

反向传播是为了更新参数,要进行更新参数就需要计算损失函数关于每个参数的导数,所以方向传播主要内容就是计算导数

计算导数的关键概念就是链式法则

链式法则

假设有两个函数 fg,以及复合函数 h(x)=f(g(x))h(x)=f(g(x))。根据链式法则,复合函数 h 关于 x 的导数可以表示为 f 关于 g 的导数和 g 关于 x 的导数的乘积:

dhdx=dfdgdgdx\frac{dh}{dx}=\frac{df}{dg} * \frac{dg}{dx}

同样的,如果h(x)=f(g(s(u(v(x)))))h(x)=f(g(s(u(v(x)))))也可以使用链式法则展开为:

dhdx=dfdgdgdsdsdududvdvdx\frac{dh}{dx}=\frac{df}{dg} * \frac{dg}{ds}* \frac{ds}{du}* \frac{du}{dv}* \frac{dv}{dx}

对于这类问题,计算机代数已经有很多办法解决,也就被叫做自动微分,这个我们后面提到

计算导数

为了使用梯度下降更新网络的权重 w,要计算损失函数L关于权重w的梯度,根据链式法则

Lw=Lyyw\frac {\partial L}{\partial w}= \frac {\partial L}{\partial y} * \frac {\partial y}{\partial w}

Ly\frac {\partial L}{\partial y}是损失函数关于神经元输出y的导数

yw\frac {\partial y}{\partial w}是神经元输出y关于权重w的导数

此外还要计算偏置项的导数,也就是yb\frac{\partial y}{\partial b}

所以一共要就是要计算这三个导数,至于怎么计算这三个导数,可以自己翻翻书,我就不写了

反向

反向就是可以利用l+1l+1层算出ll层的误差项

贡献度分配问题

此外,因为神经网络的高度复杂,导致不够透明,很确定哪层对这个模型的影响最大,也就出现了贡献度分配问题。

计算Ly\frac {\partial L}{\partial y}得到的导数就能很好的反应当前层对模型的影响,因此这个也被叫做当前层的误差项,这个指标也能解决贡献度分配问题,提高神经网路的可解释性

前馈神经网络优缺点

优点

只需要一个包含足够多神经元的隐层, 多层前馈神经网络就能以任意精度逼近任意复杂度的连续函数

缺点

容易过拟合,而且如何设置隐层神经元的个数仍然是个未决问题

缓解过拟合的措施

早停:在训练过程中, 若训练误差降低, 但验证误差升高, 则停止训练

正则化:在误差目标函数中增加一项描述网络复杂程度的部分, 例如连接权值与阈值的平方和


计算图与自动微分

这个内容就是有关于如何具体实现前馈神经网络的具体技术了

计算图

计算图(computational graph)是一种有向无环图(directed acyclic graph,DAG)。计算图用节点表示变量,用有向边(directed edge)表示计算。有向边的目的节点称为子节点,源节点称为父节点,

前向计算和反向传播

前向计算

计算图从局部出发进行运算,最终获得复杂的结果,这也是就是前向计算

image-20231226202930960

image-20231226202943165

反向传播

因为我们需要使用梯度下降的方法对问题进行优化,所以就需要求解最终输出关于各个变量的导数

以上面为例,我们求yw的求导

image-20231226203138509

image-20231226203309141

动态和静态计算图

静态图(Tensorflow)

是先搭建图,然后再输入数据进行运算。高效,因为静态计算是通过先定义后运行的方式,之后再次运行的时候就不再需要重新构建计算图,所以速度会比动态图更快。

动态图(PyTorch)

是指计算图的运算和搭建同时进行,也就是可以先计算前面的节点的值,再根据这些值搭建后面的计算图。灵活易调节。

PPT上的实例

下面对一个复合函数进行举例,其中x是输入标量,w是权重参数,b是偏置参数

f(x;w,b)=1e(wx+b)+1f(x;w,b)=\frac{1}{e^{-(wx+b)}+1}

计算图

image-20231226205509213

image-20231226205526525

所以f(x;w,b)f(x;w,b)的关于w,bw,b导数可以由路径上的节点相乘得来

f(x;w,b)w=f(x;w,b)h6h6h5h5h4h4h3h3h2h2h1h1w\frac{\partial f(x;w,b)}{\partial w}=\frac{\partial f(x;w,b)}{\partial h_6}\frac{\partial h_6}{\partial h_5}\frac{\partial h_5}{\partial h_4}\frac{\partial h_4}{\partial h_3}\frac{\partial h_3}{\partial h_2}\frac{\partial h_2}{\partial h_1}\frac{\partial h_1}{\partial w}

f(x;w,b)b=f(x;w,b)h6h6h5h5h4h4h3h3h2h2h1h1b\frac{\partial f(x;w,b)}{\partial b}=\frac{\partial f(x;w,b)}{\partial h_6}\frac{\partial h_6}{\partial h_5}\frac{\partial h_5}{\partial h_4}\frac{\partial h_4}{\partial h_3}\frac{\partial h_3}{\partial h_2}\frac{\partial h_2}{\partial h_1}\frac{\partial h_1}{\partial b}

当我们知道x,w,bx,w,b就可以算出偏导,也就是梯度了

按照公式从h1w\frac{\partial h_1}{\partial w}开始就是前向计算,反向传播就是从f(x;w,b)h6\frac{\partial f(x;w,b)}{\partial h_6}开始算

自动微分

自动微分的基本原理是所有的数值计算可以分解为一些基本操作,包含 +, −, ×, / 和一些初等函数 exp, log,sin, cos 等,然后利用链式法则来自动计算一个复合函数的梯度.

自动微分和符号微分

符号微分和自动微分都利用计算图和链式法则来自动求解导数.符号微分在编译阶段先构造一个复合函数的计算图,通过符号计算得到导数的表达式,还可以对导数表达式进行优化,在程序运行阶段才代入变量的具体数值来计算导数.而自动微分则无须事先编译,在程序运行阶段边计算边记录计算图,计算图上的局部梯度都直接代入数值进行计算,然后用前向或反向模式来计算最终的梯度.

image-20231226211827254


优化问题

思维导图没有写这个类别。

非凸优化问题

深度学习中,许多优化问题本质上是非凸的。但非凸函数有很多局部最大值最小值,很难确定找到的解是否是全局最优解。

梯度消失问题

误差从输出层反向传播时,在每一层都要乘以该层的激活函数的导数

由于 Sigmoid 型函数的饱和性,饱和区的导数更是接近于 0.这样,误差经过每一层传递都会不断衰减.当网络层数很深时,梯度就会不停衰减,甚至消失,使得整个网络很难训练.这就是梯度消失问题,简单有效的解决办法是使用导数较大的函数比如ReLU


结束

感觉难点是在于理解神经网络和前馈、反向这些概念上面