一文让你搞懂神经网络的基本原理推导

浅层神经网络

本篇从一个具有一个隐藏层的神经网络开始,初步了解神经网络的基本概念与工作机制,如图1所示。
  这里写图片描述
  下面,我们将对神经网络的各个部分做以说明。
  输入层:对于每一个输入样本,它的维度决定了输入层有几个神经元,使用下标 i i i表示维度值,如 x 1 , x 2 , x 3 , … x_1,x_2,x_3,\dots x1,x2,x3,。同时,由于具有多个样本,我们使用上标 ( i ) (i) (i)表示它是第 i i i个样本。所有的 m m m个特征样本可以记作一个矩阵 X X X X = { x ( 1 ) , x ( 2 ) , … , x ( m ) } X=\{x^{(1)},x^{(2)},\dots,x^{(m)}\} X={x(1),x(2),,x(m)}
  隐藏层:隐藏层包含着神经网络所需要训练的参数 W W W b b b,以及主要的神经网络的结构。每一层神经元的个数以及隐藏层的层数要根据具体的问题进行设计。使用上标 [ i ] [i] [i]表示这是第 i i i个隐藏层,下标 j j j表示是该层的第 j j j个神经元。
  输出层:对于分类问题来说,输出集 y y y是一个由有限的自然数组成的集合, y = { 0 , 1 , 2 , … , k − 1 } y=\{0,1,2,\dots,k-1\} y={0,1,2,,k1}。例如对于垃圾邮件识别,就是一个典型的二元分类问题,可以用0表示垃圾邮件,1表示非垃圾邮件。
  神经网络分为两个过程:前向传播和后向传播。我们以分类问题为例,初步描述神经网络的工作机制。

前向传播过程

对于一个已经训练好参数的神经网络,我们需要根据我们已知的特征集,来对它的类别进行预测。对于每一个单独的神经元与每个样本,它的前向传播过程与逻辑回归算法类似:

z [ 1 ] = W [ 1 ] x + b [ 1 ] z^{[1]}=W^{[1]}x+b^{[1]} z[1]=W[1]x+b[1]
a [ 1 ] = σ ( z [ 1 ] ) a^{[1]}=\sigma{(z^{[1]})} a[1]=σ(z[1])
z [ 2 ] = W [ 2 ] a [ 1 ] + b [ 2 ] z^{[2]}=W^{[2]}a^{[1]}+b^{[2]} z[2]=W[2]a[1]+b[2]
y ^ = a [ 2 ] = σ ( z [ 2 ] ) \hat{y}=a^{[2]}=\sigma(z^{[2]}) y^=a[2]=σ(z[2])

以上过程是在一个训练样本上进行的一次训练。为了尽量加快运算的速度,Python采用了SIMD(单指令多数据)技术,利用向量化方法,将所有的数据一次并行处理。

Z [ 1 ] = W [ 1 ] X + b [ 1 ] Z^{[1]}=W^{[1]}X+b^{[1]} Z[1]=W[1]X+b[1]
A [ 1 ] = σ ( Z [ 1 ] ) A^{[1]}=\sigma(Z^{[1]}) A[1]=σ(Z[1])
Z [ 2 ] = W [ 2 ] A [ 1 ] + b [ 2 ] Z^{[2]}=W^{[2]}A^{[1]}+b^{[2]} Z[2]=W[2]A[1]+b[2]
A [ 2 ] = σ ( Z [ 2 ] ) = Y ^ A^{[2]}=\sigma(Z^{[2]})=\hat{Y} A[2]=σ(Z[2])=Y^

注意,这里的偏置 b [ 1 ] b^{[1]} b[1] b [ 2 ] b^{[2]} b[2]与单样本不同,是一个向量。

后向传播过程

对于初始建立的神经网络,我们使用后向传播过程进行参数的调优。后向传播基于梯度下降法,计算代价函数关于参数的(偏)导数。

d Z [ 2 ] = A [ 2 ] − Y dZ^{[2]}=A^{[2]}-Y dZ[2]=A[2]Y
d W [ 2 ] = 1 m d Z [ 2 ] ( A [ 1 ] ) T dW^{[2]}=\frac{1}{m}dZ^{[2]}(A^{[1]})^T dW[2]=m1dZ[2](A[1])T
d b [ 2 ] = 1 m n p . s u m ( d Z [ 2 ] , a x i s = 1 , k e e p d i m = T r u e ) db^{[2]}=\frac{1}{m}np.sum(dZ^{[2]},axis=1,keepdim=True) db[2]=m1np.sum(dZ[2],axis=1,keepdim=True)
d Z [ 1 ] = ( W [ 2 ] ) T d Z [ 2 ] ∗ g ′ [ 1 ] ( Z [ 1 ] ) dZ^{[1]}=(W^{[2]})^TdZ^{[2]}*g^{'[1]}(Z^{[1]}) dZ[1]=(W[2])TdZ[2]g[1](Z[1])
d W [ 1 ] = 1 m d Z [ 1 ] X T dW^{[1]}=\frac{1}{m}dZ^{[1]}X^T dW[1]=m1dZ[1]XT
d b [ 1 ] = 1 m n p . s u m ( d Z [ 1 ] , a x i s = 1 , k e e p d i m = T r u e ) db^{[1]}=\frac{1}{m}np.sum(dZ^{[1]},axis=1,keepdim=True) db[1]=m1np.sum(dZ[1],axis=1,keepdim=True)
W [ 1 ] = W [ 1 ] − α 1 × d W [ 1 ] W^{[1]}=W^{[1]}-\alpha_1\times dW^{[1]} W[1]=W[1]α1×dW[1]
b [ 1 ] = b [ 1 ] − α 1 × d b [ 1 ] b^{[1]}=b^{[1]}-\alpha_1\times db^{[1]} b[1]=b[1]α1×db[1]
W [ 2 ] = W [ 2 ] − α 2 × d W [ 2 ] W^{[2]}=W^{[2]}-\alpha_2\times dW^{[2]} W[2]=W[2]α2×dW[2]
b [ 2 ] = b [ 2 ] − α 2 × d b [ 2 ] b^{[2]}=b^{[2]}-\alpha_2\times db^{[2]} b[2]=b[2]α2×db[2]

常用激活函数及其选择

  • sigmoid函数
       a = σ ( z ) = 1 1 + e − z , z ∈ R a = \sigma(z)=\frac{1}{1+e^{-z}},z\in\mathbb{R} a=σ(z)=1+ez1,zR,值域是 ( 0 , 1 ) (0,1) (0,1)。它与它的导数对应的图像如图2:
      这里写图片描述
      其中,蓝色曲线为sigmoid函数,橙色曲线为它的导数。该激活函数主要在早期用于神经网络,现在一般仅用于二分问题的最后一层。它的缺点在于当 z z z的值过大或过小时,导数趋于0,使得梯度下降的速度太慢。
  • tanh函数
       a = tanh ⁡ ( z ) = e z − e − z e z + e − z , z ∈ R a=\tanh(z)=\frac{e^z-e^{-z}}{e^z+e^{-z}},z\in\mathbb{R} a=tanh(z)=ez+ezezez,zR,值域是 ( − 1 , 1 ) (-1,1) (1,1)。它的图像与sigmoid函数图像类似,但是它的值域中心点位于0处,这使得它的性能总是比sigmoid函数要好。但是,它的问题与sigmoid函数相同,在于当 z z z的值过大或过小时,导数趋于0,使得梯度下降的速度太慢,如图3所示。
      这里写图片描述
  • relu与带泄露的relu函数
       a = r e l u ( z ) = max ⁡ { 0 , z } a = relu(z)=\max\{0,z\} a=relu(z)=max{0,z},这是目前神经网络中最常使用的激活函数。它既引入了一定的非线性因素,也避免了 z z z过大或过小时出现的饱和现象,如图4所示。
      这里写图片描述
      relu函数还有一些变种。例如,考虑在 z < 0 z<0 z<0的区域里加入少许的"泄露",使得它不完全等于0。这时 a = r e l u ( z ) = max ⁡ { α z , z } a = relu(z)=\max\{\alpha z,z\} a=relu(z)=max{αz,z},如图5所示。
    这里写图片描述

随机初始化参数

在逻辑回归中,我们也许不需要对初始化值做出特定的约束。而在神经网络中,我们必须随即地初始化这些参数,特别是权重矩阵 W W W,否则,每一个神经元都将会计算出同样的结果。我们以一个简单的例子说明一下,神经网络如下图所示。
这里写图片描述
  现在初始化 W [ 1 ] = [ 0 0 0 0 ] W^{[1]}=\left[\begin{matrix}0 & 0\\ 0 & 0\end{matrix}\right] W[1]=[0000] b [ 1 ] = 0 b^{[1]}=0 b[1]=0。那么:

z [ 1 ] = [ 0 0 ] z^{[1]}=\left[\begin{matrix}0\\0\end{matrix}\right] z[1]=[00] a [ 1 ] = σ ( a [ 1 ] ) = [ 1 2 1 2 ] a^{[1]}=\sigma(a^{[1]})=\left[\begin{matrix}\frac{1}{2}\\\frac{1}{2}\end{matrix}\right] a[1]=σ(a[1])=[2121]

同理,得到的其他对应参数也均相同,即所有的神经元都是对称的,没有起到神经网络的作用。因此,必须对神经网络参数进行随即=机初始化,例如在python中使用高斯随机数:

W [ 1 ] = n p . r a n d o m . r a n d n ( ( 2 , 2 ) ) ∗ 0.01 W^{[1]}=np.random.randn((2,2))*0.01 W[1]=np.random.randn((2,2))0.01
b [ 1 ] = n p . z e r o s ( ( 2 , 1 ) ) b^{[1]}=np.zeros((2,1)) b[1]=np.zeros((2,1))

由于b不会影响对称性,因此可以将b初始化为0。同时,我们希望参数值较小,所以在生成的随机数上缩放一个因子0.01(当然,其他值也可以)。
  这样我们就完成了一个双层神经网络的建立与训练。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值