浅层神经网络

浅层神经网络

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

前向传播过程

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

z[1]=W[1]x+b[1]
a[1]=σ(z[1])
z[2]=W[2]a[1]+b[2]
y^=a[2]=σ(z[2])

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

Z[1]=W[1]X+b[1]
A[1]=σ(Z[1])
Z[2]=W[2]A[1]+b[2]
A[2]=σ(Z[2])=Y^

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

后向传播过程

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

dZ[2]=A[2]Y
dW[2]=1mdZ[2](A[1])T
db[2]=1mnp.sum(dZ[2],axis=1,keepdim=True)
dZ[1]=(W[2])TdZ[2]g[1](Z[1])
dW[1]=1mdZ[1]XT
db[1]=1mnp.sum(dZ[1],axis=1,keepdim=True)
W[1]=W[1]α1×dW[1]
b[1]=b[1]α1×db[1]
W[2]=W[2]α2×dW[2]
b[2]=b[2]α2×db[2]

常用**函数及其选择

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

随机初始化参数

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

z[1]=[00] a[1]=σ(a[1])=[1212]

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

W[1]=np.random.randn((2,2))0.01
b[1]=np.zeros((2,1))

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