OpenCV笔记-神经网络与反向传播

四. 神经网络与误差反向传播

1. 人工神经网络的架构

1.1 什么是神经网络
  • 神经网络:大量(结构简单,功能接近的)神经元节点按一定体系架构连接成的网状结构
  • 神经网络的作用:分类、模式识别、连续值预测,建立输入与输出的映射关系
1.2 人工神经元

如图所示:

image-20220426165218899

每个神经元都是一个结构相似的独立单元,它接受前一层传来的数据,并将这些数据的加权和输入非线性作用函数中,最后将非线性作用函数的输出结果传递给后一层。

非线性函数 f f f,称为激活函数:
y = f ( w t x ) = f ( ∑ i = 1 d w i x i ) y = f(w^tx)=f(\sum_{i=1}^{d}w_ix_i) y=f(wtx)=f(i=1dwixi)

1.3 激活函数

三个常见的激活函数

  1. Sigmoid

σ ( x ) = 1 1 + e − x \sigma(x)=\frac{1}{1+e^-x} σ(x)=1+ex1

image-20220426170012607

  1. Tanh(x)

t a n h ( x ) = e x − e − x e x + e − x = 2 σ ( 2 x ) − 1 tanh(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}}=2\sigma(2x)-1 tanh(x)=ex+exexex=2σ(2x)1

image-20220426170027677

  1. Relu

f ( x ) = m a x ( 0 , x ) f(x)=max(0,x) f(x)=max(0,x)

1.4 简单的求导基础

链式求导:
( f ( g ( x ) ) ) ′ = f ′ ( g ( x ) ) g ′ ( x ) (f(g(x)))'=f'(g(x))g'(x) (f(g(x)))=f(g(x))g(x)
写成另一种形式:
d y d x = d y d z ⋅ d z d x \frac{dy}{dx}=\frac{dy}{dz}\cdot\frac{dz}{dx} dxdy=dzdydxdz
image-20220426170415822

1.5 人工神经网络
  • 基础神经网络
    • 神经元
      • 输入向量 x x x
      • 权重向量 w w w
      • 偏置标量 b b b
      • 激活函数
    • 浅网络
      • 3~5层
  • 梯度下降
  • BP后向传播

image-20220426170757598

1.6 层的理解

层实现了输入控件到输出空间的线性或非线性变换。

我们举个例子,假设输入是碳原子和氧原子,我们输出三个变量。我们可以通过改变权重的值获得若干个不同物质。

image-20220426171103137

image-20220426171111809

右侧的节点数决定了想要获得多少种不同的新物质。

1.7 前向(前馈)神经网络

FNN (Feedforward Neural Networks)

  • 前馈神经网络是人工神经网络的一种,各神经元从输入层开始,接收前一级的输出,并输出到下一级,直至输出层。整个神经网络中无反馈,可用一个有向无环图表示。
  • 前馈神经网络采用一种单项多层结构。其中每一层包含若干个神经元,同一层的神经元之间没有互相连接,层间信息的传送只沿一个方向进行。
  • 第一层为输入层,第二层为隐藏层,最后一层为输出层。其中隐藏层可以是一层也可以是多层。

2. 目标函数与梯度下降

2.1 目标函数

前面介绍了前馈神经网络,那我们的前馈神经网络的目标是什么呢?

  • 对于一系列训练样本 x x x
  • 期望输出 t = ( t 1 , … , t c ) t=(t_1,\dots,t_c) t=(t1,,tc),网络实际输出 z = ( z 1 , … , z c ) z=(z_1,\dots,z_c) z=(z1,,zc)

那此时我们的目标函数就是:
J ( w ) = 1 2 ∣ ∣ t − z ∣ ∣ 2 = 1 2 ∑ k = 1 c ( t k − z k ) 2 J(w)=\frac{1}{2}||t-z||^2=\frac{1}{2}\sum_{k=1}^{c}(t_k-z_k)^2 J(w)=21∣∣tz2=21k=1c(tkzk)2
那我们如何计算目标函数的最小值呢?

2.2 Delta学习规则

Delta学习规则是一种有监督学习算法,该算法根据神经元的实际输出与期望输出差别来调整连接权,其数学表达式如下:
△ W i j = a ∗ ( d i − y i ) x j ( t ) \triangle W_{ij}=a\ast(d_i-y_i)x_j(t) Wij=a(diyi)xj(t)
其中:

  • △ W i j \triangle W_{ij} Wij表示神经元 j j j到神经元 i i i的连接权重增量
  • d j d_j dj是神经元 i i i的期望输出
  • y i y_i yi是神经元 i i i的实际输出
  • x j x_j xj表示神经元 j j j的状态
  • a a a表示学习速度的常数
2.3 梯度下降

大多数机器学习算法和深度学习算法都涉及到的优化,优化是指通过改变 x x x来使某个函数 f ( x ) f(x) f(x)最大化或者最小化,通常以最小化 f ( x ) f(x) f(x)指代大多数问题。

我们把需要最大化或者最小化的函数称为目标函数或准则。当我们要将其最小化时,我们把它称为代价函数,损失函数或误差函数。

我们假设一个损失函数用于举例说明。
J ( θ ) = 1 2 ∑ i = 1 m ( h θ ( x ) − y ) 2 J(\theta)=\frac{1}{2}\sum_{i=1}^m(h_\theta(x)-y)^2 J(θ)=21i=1m(hθ(x)y)2
其中:
h θ ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 + ⋯ + θ n x n h_\theta(x)=\theta_0+\theta_1x_1+\theta_2x_2+\cdots+\theta_nx_n hθ(x)=θ0+θ1x1+θ2x2++θnxn
然后使它最小化。

在高维的情况下,损失函数求导之后等于0,这个方程组太难求解,也有可能不可解,所以一般情况不使用这个方法

我们知道曲面上方向导数的最大值方向就代表了梯度的方向

方向导数:
∂ Z ∂ l ⃗ ∣ ( x 0 , y 0 ) = lim ⁡ t → 0 1 t [ f ( x 0 + t cos ⁡ α , y 0 + t cos ⁡ β ) − f ( x 0 , y 0 ) ] \frac{\partial Z}{\partial\vec{l}}\mid_{(x_0,y_0)}=\lim_{t\to0}\frac{1}{t}[f(x_0+t\cos\alpha,y_0+t\cos\beta)-f(x_0,y_0)] l Z(x0,y0)=t0limt1[f(x0+tcosα,y0+tcosβ)f(x0,y0)]

∂ Z ∂ l ⃗ ∣ ( x 0 , y 0 ) = f x ( x 0 , y 0 ) cos ⁡ α + f y ( x 0 , y 0 ) cos ⁡ β \frac{\partial Z}{\partial\vec{l}}\mid_{(x_0,y_0)}=f_x(x_0,y_0)\cos\alpha+f_y(x_0,y_0)\cos\beta l Z(x0,y0)=fx(x0,y0)cosα+fy(x0,y0)cosβ

那我们应该沿着梯度的反方向进行权重的更新,可以有效地找到全局的最优解, θ i \theta_i θi的更新过程可以描述为:
θ j : = θ j − α ∂ ∂ θ j J ( θ ) \theta_j:=\theta_j-\alpha\frac{\partial}{\partial\theta_j}J(\theta) θj:=θjαθjJ(θ)

∂ ∂ θ j J ( θ ) = ∂ ∂ θ j ⋅ 1 2 ( h θ ( x ) − y ) 2 = ( h θ ( x ) − y ) ⋅ ∂ ∂ θ j ( h θ ( x ) − y ) = ( h θ ( x ) − y ) ⋅ ∂ ∂ θ j ( ∑ i = 1 m θ i x i − y ) = ( h θ ( x ) − y ) x j \begin{aligned} \frac{\partial}{\partial\theta_j}J(\theta)&=\frac{\partial}{\partial\theta_j}\cdot\frac{1}{2}(h_\theta(x)-y)^2\\ &=(h_\theta(x)-y)\cdot\frac{\partial}{\partial\theta_j}(h_\theta(x)-y)\\ &=(h_\theta(x)-y)\cdot\frac{\partial}{\partial\theta_j}(\sum_{i=1}^{m}\theta_ix_i-y)\\ &=(h_\theta(x)-y)x_j \end{aligned} θjJ(θ)=θj21(hθ(x)y)2=(hθ(x)y)θj(hθ(x)y)=(hθ(x)y)θj(i=1mθixiy)=(hθ(x)y)xj

换一个角度来想,损失函数中一般有两种参数,一种是控制输入信号量的权重 w w w,另一种是调整函数与真实值距离的偏差 b b b,那我们要做的就是通过梯度下降的方法,不断地调整 w w w b b b,使得损失函数值越来越小。

通过计算梯度我们可以知道 w w w的移动方向,那我们接下来就要知道应该前进多少,这里我们用到学习率(Learning Rate)这个概念,通过学习率可以计算前进的距离。

我们用 w i w_i wi表示初始权重, w i + 1 w_{i+1} wi+1表示更新后的权重, α \alpha α表示学习率。
w i + 1 = w i − α ⋅ d L d w i w_{i+1}=w_i-\alpha\cdot\frac{dL}{dw_i} wi+1=wiαdwidL
梯度下降中重复此式,直至损失函数收敛不变,在这里 α \alpha α值过大,有可能会错过损失函数最小值, α \alpha α过小,会导致迭代次数过多,耗费过多时间。以下是全部过程。

  1. for i=0 → \to 训练数据个数

    1. 计算第i个训练数据的权重 w w w和偏差 b b b相对于损失函数的梯度。在这里得到每一个训练数据的权重和偏差的梯度值。
    2. 计算所有训练数据权重 w w w的梯度总和
    3. 计算所有训练数据偏差 b b b的梯度总和
  2. 上面的计算结束之后

    1. 使用上面2,3的值计算所有样本 w , b w,b w,b的梯度的平均值
    2. 使用下面的式子,更新每个样本的 w w w b b b

    w i + 1 = w i − α × d L d w i b i + 1 = b i − α × d L d b i w_{i+1}=w_i-\alpha\times\frac{dL}{dw_i}\\ b_{i+1}=b_i-\alpha\times\frac{dL}{db_i} wi+1=wiα×dwidLbi+1=biα×dbidL

    1. 重复上面的步骤直至损失函数收敛不变
2.4 梯度下降的衍生
  1. 小批量样本梯度下降(Mini Batch GD)

这个算法在每次梯度下降的过程中,只选取一部分的样本数据进行梯度计算,比如整体样本百分之一的数据。在数据量较大的项目中,可以明显地减少梯度计算的时间。

  1. 随机梯度下降(Stochastic GD)

随机梯度下降算法之随机抽取一个样本进行梯度计算,由于每次梯度下降迭代只计算一个样本的梯度,因此运算时间会比MGD还少很多,但由于训练数据量太小,因此下降路径容易受到训练数据自身噪音的影响。

3. 误差反向传播

我们先来回顾一下梯度下降。

下图是一个表示参数 w w w与目标函数 J ( w ) J(w) J(w)的关系图,红色部分是表示 J ( w ) J(w) J(w)有着比较高的取值,需要能够让 J ( w ) J(w) J(w)的值尽量的低。也就是深蓝色的部分。 w 1 , w 2 w_1,w_2 w1,w2表示 w w w向量的两个维度。

先确定一个初始点,将 w w w按照梯度下降的方向进行调整,这样就会使得 J ( w ) J(w) J(w)向着更低的方向进行变化,如图所示,算法的结束将是在 w w w下降到无法继续下降为止(不一定是无法下降,有时候也会停止在局部最低点或是其他情况)。

根据前面的介绍,式子如下:
w m + 1 = w m + △ w m = w m − α ∂ J ∂ w w_{m+1}=w_m+\triangle w_m=w_m-\alpha\frac{\partial J}{\partial w} wm+1=wm+wm=wmαwJ
image-20220501173445557

3.1 输出层权重改变量

输出层的权重改变量其实就是一个偏导数的表达:
∂ J ∂ w k j = ∂ J ∂ n e t k ⋅ ∂ n e t k ∂ w k j \frac{\partial J}{\partial w_{kj}}=\frac{\partial J}{\partial net_k}\cdot\frac{\partial net_k}{\partial w_{kj}} wkjJ=netkJwkjnetk
那么这里的 ∂ J ∂ w k j \frac{\partial J}{\partial w_{kj}} wkjJ如何理解呢?

w k j w_{kj} wkj是隐藏层到输出层的权重,那么目标函数对 w k j w_{kj} wkj的偏导也就是隐藏层权重的改变量,这里先不考虑学习率也就是步长,就先直接将这个偏导数当作改变量。

这里:
J ( w ) = 1 2 ∣ ∣ t − z ∣ ∣ 2 = 1 2 ∑ k = 1 c ( t k − z k ) 2 J(w)=\frac{1}{2}||t-z||^2=\frac{1}{2}\sum_{k=1}^c(t_k-z_k)^2 J(w)=21∣∣tz2=21k=1c(tkzk)2
w k j w_{kj} wkj在这里表示的并不是很明显,那我们就考虑通过一个中间函数使用链式求导法则将其关联起来。隐藏层与输出层的图示如下:

image-20220501175306798

其中输出层的总输入为 n e t k net_k netk
n e t k = ∑ j = 1 n H w k j y j net_k = \sum_{j=1}^{n_H}w_{kj}y_j netk=j=1nHwkjyj
那么:
∂ n e t k ∂ w k j = y j \frac{\partial net_k}{\partial w_{kj}}=y_j wkjnetk=yj
我们知道了其中的一部分,那我们继续来看另外一部分,目标函数对 n e t k net_k netk求偏导,关系还不是很直观,我们再使用输出将其链接起来。输出层的输入为 n e t k net_k netk,输出为 z k z_k zk,他们两个的关系就是一个激活函数,所以通过输出层的输出可以很好的将目标函数与输出层的输入链接起来。
∂ J ∂ n e t k = ∂ J ∂ z k ⋅ ∂ z k ∂ n e t k = − ( t k − z k ) ⋅ f ′ ( n e t k ) \frac{\partial J}{\partial net_k}=\frac{\partial J}{\partial z_k}\cdot\frac{\partial z_k}{\partial net_k}=-(t_k-z_k)\cdot f'(net_k) netkJ=zkJnetkzk=(tkzk)f(netk)
令: δ k = ( t k − z k ) f ′ ( n e t k ) \delta_k=(t_k-z_k)f'(net_k) δk=(tkzk)f(netk)
∂ J ∂ w k j = − ( t k − z k ) ⋅ f ′ ( n e t k ) ⋅ y j = − δ k y j \frac{\partial J}{\partial w_{kj}}=-(t_k-z_k)\cdot f'(net_k)\cdot y_j=-\delta_ky_j wkjJ=(tkzk)f(netk)yj=δkyj
在这里 δ k \delta_k δk就是输出层产生的残差。

3.2 隐藏层权重改变量

image-20220501180830624

隐藏层的权重改变量自然就是目标函数对于隐藏层的输入的偏导了。
∂ J ∂ w j i = ∂ J ∂ y j ⋅ ∂ y j ∂ n e t j ⋅ ∂ n e t j ∂ w j i \frac{\partial J}{\partial w_{ji}}=\frac{\partial J}{\partial y_j}\cdot\frac{\partial y_j}{\partial net_j}\cdot\frac{\partial net_j}{\partial w_{ji}} wjiJ=yjJnetjyjwjinetj
其中 y j y_j yj为隐藏层单元输出, n e t j net_j netj为隐藏层单元总输入。
n e t j = ∑ m = 1 d w j m x m net_j=\sum_{m=1}^d w_{jm}x_m netj=m=1dwjmxm
那隐藏层单元输出与隐藏层单元总输入之间的关系其实就是加上了一层激活函数,如下:
∂ y j ∂ n e t j = f ′ ( n e t j ) \frac{\partial y_j}{\partial net_j}=f'(net_j) netjyj=f(netj)
最后一项隐藏层单元总输入与权重的关系可以在表达式中很明显地表达出来,如下:
∂ n e t j ∂ w j i = ∂ ∂ w j i ( ∑ m = 1 d w j m x m ) = x i \frac{\partial net_j}{\partial w_{ji}}=\frac{\partial}{\partial w_{ji}}(\sum_{m=1}^{d}w_{jm}x_m)=x_i wjinetj=wji(m=1dwjmxm)=xi
因为第一项目标函数与隐藏层单元输出的关系比较复杂所以放到最后来计算。
n e t k = ∑ j = 1 n H w k j y j net_k=\sum_{j=1}^{n_H}w_{kj}y_j netk=j=1nHwkjyj

∂ J ∂ y j = ∂ ∂ y j [ 1 2 ∑ k = 1 c ( t k − z k ) 2 ] = − ∑ k = 1 c ( t k − z k ) ∂ z k ∂ y j = − ∑ k = 1 c ( t k − z k ) ⋅ ∂ z k ∂ n e t k ⋅ ∂ n e t k ∂ y j = − ∑ k = 1 c ( t k − z k ) f ′ ( n e t k ) w k j \begin{aligned} \frac{\partial J}{\partial y_j}&=\frac{\partial}{\partial y_j}[\frac{1}{2}\sum_{k=1}^{c}(t_k-z_k)^2]\\ &=-\sum_{k=1}^{c}(t_k-z_k)\frac{\partial z_k}{\partial y_j}\\ &=-\sum_{k=1}^{c}(t_k-z_k)\cdot\frac{\partial z_k}{\partial net_k}\cdot\frac{\partial net_k}{\partial y_j}\\ &=-\sum_{k=1}^{c}(t_k-z_k)f'(net_k)w_{kj} \end{aligned} yjJ=yj[21k=1c(tkzk)2]=k=1c(tkzk)yjzk=k=1c(tkzk)netkzkyjnetk=k=1c(tkzk)f(netk)wkj

那么:
∂ J ∂ w j i = − [ ∑ k = 1 c ( t k − z k ) f ′ ( n e t k ) w k j ] f ′ ( n e t j ) x i \frac{\partial J}{\partial w_{ji}}=-[\sum_{k=1}^{c}(t_k-z_k)f'(net_k)w_{kj}]f'(net_j)x_i wjiJ=[k=1c(tkzk)f(netk)wkj]f(netj)xi
这里我们令:
δ j = f ′ ( n e t j ) ∑ k = 1 c δ k w k j \delta_j=f'(net_j)\sum_{k=1}^{c}\delta_kw_{kj} δj=f(netj)k=1cδkwkj
那么:
∂ J ∂ w j i = − δ j x i \frac{\partial J}{\partial w_{ji}}=-\delta_jx_i wjiJ=δjxi
输出层与隐藏层的误差反向传播总结一下,如下图所示:

输出层:

image-20220501193643419

隐藏层:

image-20220501193654379

3.3 误差传播迭代公式

输出层与隐藏层的误差传播公式可以统一为:

  1. 权重增量 = -1 × \times ×学习步长 × \times ×目标函数对权重的偏导
  2. 目标函数对权重的偏导数 = -1 × \times ×残差 × \times ×当前层的输入
  3. 残差=当前层激活函数的导数 × \times ×上层反传来的误差
  4. 上层反传来的误差= 上层残差的加权和

隐藏层的误差反向传播总结一下,如下图所示:

输出层:

[外链图片转存中…(img-oPPeWMR2-1665628829586)]

隐藏层:

[外链图片转存中…(img-4cxYHaj0-1665628829586)]

3.3 误差传播迭代公式

输出层与隐藏层的误差传播公式可以统一为:

  1. 权重增量 = -1 × \times ×学习步长 × \times ×目标函数对权重的偏导
  2. 目标函数对权重的偏导数 = -1 × \times ×残差 × \times ×当前层的输入
  3. 残差=当前层激活函数的导数 × \times ×上层反传来的误差
  4. 上层反传来的误差= 上层残差的加权和
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CavalierJHC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值