浅层神经网络
浅层神经网络
本篇从一个具有一个隐藏层的神经网络开始,初步了解神经网络的基本概念与工作机制,如图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^
注意,这里的偏置
后向传播过程
对于初始建立的神经网络,我们使用后向传播过程进行参数的调优。后向传播基于梯度下降法,计算代价函数关于参数的(偏)导数。
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+e−z,z∈R ,值域是(0,1) 。它与它的导数对应的图像如图2:
其中,蓝色曲线为sigmoid函数,橙色曲线为它的导数。该**函数主要在早期用于神经网络,现在一般仅用于二分问题的最后一层。它的缺点在于当z 的值过大或过小时,导数趋于0,使得梯度下降的速度太慢。 - tanh函数
a=tanh(z)=ez−e−zez+e−z,z∈R ,值域是(−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所示。
随机初始化参数
在逻辑回归中,我们也许不需要对初始化值做出特定的约束。而在神经网络中,我们必须随即地初始化这些参数,特别是权重矩阵
现在初始化
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(当然,其他值也可以)。
这样我们就完成了一个双层神经网络的建立与训练。