神经网络和多层感知机MLP"/>
神经网络和多层感知机MLP
神经网络和多层感知机MLP
文章内容和代码可由此处查看或下载:
参考:
.html
1. 感知机到神经网络,神经网络的基本结构
1.1 感知机
感知机模型是将若干输入加权求和并通过激活函数后输出的模型:
感知机可以表示为线性变换+非线性激活函数:
z = ∑ i = 1 m w i x i + b z=∑_{i=1}^{m}w_ix_i+b z=∑i=1mwixi+b
上述模型是一个二分类器,由于其过于简单,无法拟合复杂的非线性任务。
1.2 神经网络及其基本结构
神经网络则是基于这样的简单模型,将多个神经元逐层堆叠,由此形成我们的深度模型:
上图是一个最简单的神经网络,它包含神经网络的最基本结构:
输入层:对应输入向量的大小
输出层:对应模型任务,可以是二分类,多分类,也可以是回归任务等等
隐层:由多个感知机,即神经元组成,每个神经元对上层的所有输入做线性变换与非线性激活。
1.3 神经网络参数的定义
神经网络的隐层可以不止一层,宽度也可以很宽,一般来说,我们计算网络层数时不考虑输入层,所以下图是一个4层的神经网络,由于每层神经元连接到上层的所有输入,这个网络也叫做全连接网络,或多层感知机:
由于网络中每层都有参数 w w w和 b b b,所以我们需要特定的方式进行定义:以下图一个三层的DNN为例,第二层的第4个神经元到第三层的第2个神经元的线性系数定义为 w 24 3 w^3_{24} w243。上标3代表线性系数 w w w所在的层数,而下标对应的是输出的第三层索引2和输入的第二层索引4。这样定义,每层进行的矩阵运算都可以表示为 w T x + b w^Tx+b wTx+b。
类似的偏置 b b b,第二层的第三个神经元对应的偏倚定义为 b 3 2 b^2_3 b32。
2. 前向传播
2.1 前向传播原理
上面讲到网络每层从输入到输出都可以表示为线性变换 z = w T x + b z=w^Tx+b z=wTx+b与激活函数 σ ( z ) \sigma(z) σ(z),前向传播顾名思义就是从输入层开始,逐层计算输出,最终得到输出层的输出后结束。
例如第二层的输出 a 1 2 , a 2 2 , a 3 2 a^2_1,a^2_2,a^2_3 a12,a22,a32,我们有:
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_1=σ(z^2_1)=σ(w^2_{11}x^1+w^2_{12}x^2+w^2_{13}x^3+b^2_1) a12=σ(z12)=σ(w112x1+w122x2+w132x3+b12)
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^2_2=σ(z^2_2)=σ(w^2_{21}x^1+w^2_{22}x^2+w^2_{23}x^3+b^2_2) a22=σ(z22)=σ(w212x1+w222x2+w232x3+b22)
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^2_3=σ(z^2_3)=σ(w^2_{31}x^1+w^2_{32}x^2+w^2_{33}x^3+b^2_3) a32=σ(z32)=σ(w312x1+w322x2+w332x3+b32)
对于第三层的的输出 a 1 3 a^3_1 a13,我们有:
a 1 3 = σ ( z 1 3 ) = σ ( w 11 3 x 1 + w 12 3 x 2 + w 13 3 x 3 + b 1 3 ) a^3_1=σ(z^3_1)=σ(w^3_{11}x^1+w^3_{12}x^2+w^3_{13}x^3+b^3_1) a13=σ(z13)=σ(w113x1+w123x2+w133x3+b13)
将上面的例子一般化,假设第 l − 1 l−1 l−1层共有m个神经元,则对于第 l l l层的第j个神经元的输出 a j l a^l_j ajl,我们有:
a j l = σ ( z j l ) = σ ( ∑ k = 1 m w l j k a k l − 1 + b j l ) a^l_j=σ(z^l_j)=σ(∑_{k=1}^mwl_{jk}a^{l−1}_k+b^l_j) ajl=σ(zjl)=σ(∑k=1mwljkakl−1+bjl)
为了简化表示,假设 l − 1 l-1 l−1层共有m个神经元, l l l层共有n个神经元,第 l l l层的 w w w组成了一个 n × m n\times m n×m的矩阵 W l W^l Wl,那么第l层的输出可以表示为:
a l = σ ( z l ) = σ ( W l a l − 1 + b l ) a^l=σ(z^l)=σ(W^la^{l−1}+b^l) al=σ(zl)=σ(Wlal−1+bl)
2.2 前向传播算法
前向传播算法也就是利用若干个权重系数矩阵 W W W,偏倚向量 b b b来和输入值向量 x x x进行一系列线性运算和激活运算,从输入层开始,一层层的向后计算,一直到运算到输出层,得到输出结果为值。
输入: 总层数L,所有隐藏层和输出层对应的矩阵 W W W,偏倚向量 b b b,输入值向量 x x x
输出:输出层的输出 a L a^L aL
1) 初始化 a 1 = x a^1=x a1=x
2) for l = 2 l=2 l=2 to L L L, 计算:
a l = σ ( z l ) = σ ( W l a l − 1 + b l ) a^l=σ(z^l)=σ(W^la^{l−1}+b^l) al=σ(zl)=σ(Wlal−1+bl)
3. 反向传播
我们在定义了模型的结构后,神经网络的所有参数 W , b W, b W,b都是随机的初始化状态,要想解决实际任务,我们必须令模型拟合我们的数据,也就是网络的训练过程。我们知道梯度下降法,它的意义是令参数向损失函数最大梯度的负方向移动,最终得到损失函数的局部最小,以此来拟合数据,而反向传播算法就是基于梯度下降,因为损失函数由最后一层的输出计算得到,所以梯度需要从最深层向最浅层传播,逐层计算梯度,以此来更新每层的参数。
3.1 反向传播基本概念
反向传播的第一步是正向传播,计算出网络每层的输出: a l = σ ( z l ) = σ ( W l a l − 1 + b l ) a^l=σ(z^l)=σ(W^la^{l−1}+b^l) al=σ(zl)=σ(Wlal−1+bl),得到最后一层输出 a L a^L aL后,计算损失函数 J J J,常用的损失函数有平方损失,交叉熵损失等
为了方便讲解,我们使用平方损失,对于每个样本,最小化下式:
J ( W , b , x , y ) = 1 2 ∣ ∣ a L − y ∣ ∣ 2 J(W,b,x,y)=\frac{1}{2}||a^L−y||^2 J(W,b,x,y)=21∣∣aL−y∣∣2
对于输出层 a L = σ ( z L ) = σ ( W L a L − 1 + b L ) a^L=σ(z^L)=σ(W^La^{L−1}+b^L) aL=σ(zL)=σ(WLaL−1+bL),损失函数为 J ( W , b , x , y ) = 1 2 ∣ ∣ a L − y ∣ ∣ 2 = 1 2 ∣ ∣ σ ( W L a L − 1 + b L ) − y ∣ ∣ 2 J(W,b,x,y)=\frac{1}{2}||a^L−y||^2=\frac{1}{2}||σ(W^La^{L−1}+b^L)−y||^2 J(W,b,x,y)=21∣∣aL−y∣∣2=21∣∣σ(WLaL−1+bL)−y∣∣2
那么损失函数对于 W W W和 b b b的梯度可以按下式计算:
∂ J ( W , b , x , y ) ∂ W L = [ ( a L − y ) ⊙ σ ′ ( z L ) ] ( a L − 1 ) T \frac{∂J(W,b,x,y)}{∂W^L}=[(a^L−y)⊙σ′(z^L)](a^{L−1})^T ∂WL∂J(W,b,x,y)=[(aL−y)⊙σ′(zL)](aL−1)T
∂ J ( W , b , x , y ) ∂ b L = ( a L − y ) ⊙ σ ′ ( z L ) \frac{∂J(W,b,x,y)}{∂b^L}=(a^L−y)⊙σ′(z^L) ∂bL∂J(W,b,x,y)=(aL−y)⊙σ′(zL)
⊙ ⊙ ⊙代表Hadamard积对于两个维度相同的向量 A ( a 1 , a 2 , . . . a n ) T A(a1,a2,...an)^T A(a1,a2,...an)T和 B ( b 1 , b 2 , . . . b n ) T B(b1,b2,...bn)^T B(b1,b2,...bn)T,则 A ⊙ B = ( a 1 b 1 , a 2 b 2 , . . . a n b n ) T A⊙B=(a1b1,a2b2,...anbn)^T A⊙B=(a1b1,a2b2,...anbn)T。
W , b W,b W,b梯度的公共部分,也就是损失对 z L z^L zL的梯度记为:
δ L = ∂ J ( W , b , x , y ) ∂ z L = ( a L − y ) ⊙ σ ′ ( z L ) δ^L=\frac {∂J(W,b,x,y)}{∂z^L}=(a^L−y)⊙σ′(z^L) δL=∂zL∂J(W,b,x,y)=(aL−y)⊙σ′(zL)
得到了第L层的梯度后,继续计算 L − 1 L-1 L−1层及之前层的梯度,根据链式法则,前面任意一层 z l z^l zl的梯度可以表示为:
δ l = ∂ J ( W , b , x , y ) ∂ z l = ( ∂ z L ∂ z L − 1 ∂ z L − 1 ∂ z L − 2 . . . ∂ z l + 1 ∂ z l ) T ∂ J ( W , b , x , y ) ∂ z L δ^l=\frac{∂J(W,b,x,y)}{∂z^l}=(\frac{∂z^L}{∂z^{L−1}}\frac{∂z^{L−1}}{∂z^{L−2}}...\frac{∂z^{l+1}}{∂z^l})^T\frac{∂J(W,b,x,y)}{∂z^L} δl=∂zl∂J(W,b,x,y)=(∂zL−1∂zL∂zL−2∂zL−1...∂zl∂zl+1)T∂zL∂J(W,b,x,y)
当得到了深 l l l层 z L z^L zL的梯度后,很容易可以求得 l − 1 l-1 l−1层 W , b W, b W,b的梯度:
∂ J ( W , b , x , y ) ∂ W l = δ l ( a l − 1 ) T \frac{∂J(W,b,x,y)}{∂W^l}=δ^l(a^{l−1})^T ∂Wl∂J(W,b,x,y)=δl(al−1)T
∂ J ( W , b , x , y ) ∂ b l = δ l \frac{∂J(W,b,x,y)}{∂b^l}=δ^l ∂bl∂J(W,b,x,y)=δl
假设 δ L + 1 δ^{L+1} δL+1已经得到,现在求取 δ L δ^{L} δL:
δ l = ∂ J ( W , b , x , y ) ∂ z l = ( ∂ z l + 1 ∂ z l ) T ∂ J ( W , b , x , y ) ∂ z l + 1 = ( ∂ z l + 1 ∂ z l ) T δ l + 1 δl=\frac{∂J(W,b,x,y)}{∂z^l}=(\frac{∂z^{l+1}}{∂z^l})^T\frac{∂J(W,b,x,y)}{∂z^{l+1}}=(\frac{∂z^{l+1}}{∂z^l})^Tδ^{l+1} δl=∂zl∂J(W,b,x,y)=(∂zl∂zl+1)T∂zl+1∂J(W,b,x,y)=(∂zl∂zl+1)Tδl+1
因为:
z l + 1 = W l + 1 a l + b l + 1 = W l + 1 σ ( z l ) + b l + 1 z^{l+1}=W^{l+1}a^l+b^{l+1}=W^{l+1}σ(z^l)+b^{l+1} zl+1=Wl+1al+bl+1=Wl+1σ(zl)+bl+1
得到:
∂ z l + 1 ∂ z l = W l + 1 d i a g ( σ ′ ( z l ) ) \frac {∂z^{l+1}}{∂z^l}=W^{l+1} diag(σ′(z^l)) ∂zl∂zl+1=Wl+1diag(σ′(zl))
代入得:
δ l = ( ∂ z l + 1 ∂ z l ) T δ l + 1 = d i a g ( σ ′ ( z l ) ) ( W l + 1 ) T δ l + 1 = ( W l + 1 ) T δ l + 1 ⊙ σ ′ ( z l ) δl=(\frac{∂z^{l+1}}{∂z^l})^Tδ^{l+1}=diag(σ′(z^l))(W^{l+1})^Tδ^{l+1}=(W^{l+1})^Tδ^{l+1}⊙σ′(z^l) δl=(∂zl∂zl+1)Tδl+1=diag(σ′(zl))(Wl+1)Tδl+1=(Wl+1)Tδl+1⊙σ′(zl)
3.2 反向传播算法
输入: 总层数 L L L,以及各隐藏层与输出层的神经元个数,损失函数,学习率α,epoch数MAX,输入的m个训练样本 ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) {(x1,y1),(x2,y2),...,(xm,ym)}{(x1,y1),(x2,y2),...,(xm,ym)} (x1,y1),(x2,y2),...,(xm,ym)(x1,y1),(x2,y2),...,(xm,ym)
1) 初始化各隐藏层与输出层的线性关系系数矩阵 W W W和偏倚向量 b b b的值为一个随机值。
2)for iter to 1 to MAX:
2-1) for i =1 to m:
a) 将DNN输入 a 1 a^1 a1设置为 x i x^i xi
b) for l = 2 l=2 l=2 to L L L,进行前向传播算法计算 a i , l = σ ( z i , l ) = σ ( W l a i , l − 1 + b l ) a i , l = σ ( z i , l ) = σ ( W l a i , l − 1 + b l ) a^{i,l}=σ(z^i,l)=σ(W^la^{i,l−1}+b^l)a^i,l=σ(z^i,l)=σ(W^la^{i,l−1}+b^l) ai,l=σ(zi,l)=σ(Wlai,l−1+bl)ai,l=σ(zi,l)=σ(Wlai,l−1+bl)
c) 通过损失函数计算输出层的 δ i , L δ^{i,L} δi,L
d) for $ l= L-1$ to 2, 进行反向传播算法计算 δ i , l = ( W l + 1 ) T δ i , l + 1 ⊙ σ ′ ( z i , l ) δ^{i,l}=(W^{l+1})^Tδ^{i,l+1}⊙σ′(z^{i,l}) δi,l=(Wl+1)Tδi,l+1⊙σ′(zi,l)
2-2) for l = 2 l = 2 l=2 to L L L,更新第 l l l层的 W l , b l W^l, b^l Wl,bl:
W l = W l − α ∑ i = 1 m δ i , l ( a i , l − 1 ) T W^l=W^l−α∑_{i=1}^{m}δ^{i,l}(a^{i,l−1})^T Wl=Wl−α∑i=1mδi,l(ai,l−1)T
b l = b l − α ∑ i = 1 m δ i , l b^l=b^l−α∑_{i=1}^{m}δ^{i,l} bl=bl−α∑i=1mδi,l
4. 激活函数
如果神经网络没有非线性的激活函数,那么网络中就只存在线性变换,网络就无法拟合复杂的非线性问题。
4.1 Sigmoid
Sigmoid函数:
σ ( z ) = 1 1 + e − z \sigma(z)=\frac{1}{1+e^{-z}} σ(z)=1+e−z1
Sigmoid函数的导数:
σ ′ ( z ) = ( 1 − σ ( z ) ) σ ( z ) \sigma'(z)=(1-\sigma(z))\sigma(z) σ′(z)=(1−σ(z))σ(z)
函数图像:
优点:输出在01之间,适应于特定任务,也可以将数值很大的输入进行缩放;平滑,任意处可导。
缺点:
1. 在深度神经网络中梯度反向传递时导致梯度爆炸和梯度消失,其中梯度爆炸发生的概率非常小,而梯度消失发生的概率比较大,如下图导数图像,当输入很大或很小时,梯度趋近于0:
2. 输出不是0均值,这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入,随着网络的加深,会改变数据的原始分布。
3. 计算量大。
4.2 tanh
tanh函数:
t a n h ( x ) = e x − e − x e x + e − x tanh(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}} tanh(x)=ex+e−xex−e−x
tanh导数:
t a n h ′ ( x ) = 2 1 + e − 2 x − 1 tanh'(x)=\frac{2}{1+e^{-2x}}-1 tanh′(x)=1+e−2x2−1
函数曲线:
导数曲线:
优点:
1. 范围在-1,1之间,解决了非0均值的问题;
缺点:
1. 计算量大;
2. 梯度消失、梯度爆炸。
4.3 ReLU
ReLU函数:
R e L U ( x ) = m a x ( 0 , x ) ReLU(x) = max(0,x) ReLU(x)=max(0,x)
函数曲线:
导数曲线:
优点:
1. 正区间内导数都为1,缓解了梯度消失的问题;
2. 计算速度快;
3. 加快网络收敛。
缺点:
1. 不是0均值;
2. Dead ReLU Problem:某些神经元可能永远不会被激活,导致相应的参数永远不能被更新。
更多推荐
神经网络和多层感知机MLP
发布评论