深度学习几乎就等于神经网络算法,该算法主要由两个模块构成:前向传播(Forward Propagation)、后向传播(Backward Propagation)。
前向传播来计算预测值y^,而后向传播则根据预测值与实际值的差别计算成本方程(Cost Function),并根据该值改进神经网络各节点的权重值。经过多次迭代,逐渐收敛。
Forward Propagation#
前向传播又有两个模块:线性模块、激发模块。
线性模块#
线性模块是本层神经节点根据输入X={X(1),X(2),...,X(m)}来计算输出:
Z=WX+b这里W是本层神经节点的权重。有m个样本的情况下,假设每个样本有nx个参数,即样本X的维度为(nx,m)。假设本层共有n[l]个神经节点,则W的维度为(n[l],nx)。进而,b的维度为(n[l],1)。
激发模块#
由于神经网络的输出值域等问题,由线性模块计算得到的输出不能直接作为整个模型的输出,而需要经过激发模块的处理。假设激发函数(Activation Function)为g(∙),则最终本层神经节点的输出为:
A=g(Z)常用的激发函数有几种:
sigmoid函数#
该函数的表达式为:
σ(x)=1+e−x1该函数的图象为:

从图像上可以看出,该函数的值域介于0,1之间,当处理分类问题(Classification)时,该函数能较好的进行最后的输出预测。
若a=σ(z),则该函数的导数为:σ′(z)=a(1−a)
tanh函数#
该函数的表达式为:
tanh(x)=ex+e−xex−e−x函数图象为:

该函数图像与Sigmoid函数类似,唯一不同的是Sigmoid函数图像介于0,1之间,而tanh函数图像则介于-1,1之间。从实践来看,tanh函数作为激发函数表现总是要比sigmoid函数好。
若a=tanh(x),则该函数的导数tanh′(x)=1−a2。
但是,两函数都存在同一个问题:当自变量的值过大或过小时,如x=−1000,此时,从图像上可以看出,函数的图像会变得十分扁平,意味着其导数会十分小,进而梯度下降法(Gradient Descent)对权重W的改变会十分的有限。进而,该神经网络的训练可能会十分的漫长。
ReLU函数#
该函数就为改变上面两个函数的缺点诞生的,其表达式十分简单:
f(x)={x, 0,x>0else其函数图象为:

进而其导数也不存在上面两个函数的缺点,进而实践中,该函数的表现总是比以上两个函数都好。
前向传播总结#
用A[l−1]表示第l层神经网络的输入值,即第l−1层神经网络的激发值,其维度为(n[l−1],m),其中n[l]表示该层神经网络的节点个数;用W[l]表示第l层神经网络的权重,其维度为(n[l],n[l−1]),则
Z[l]=W[l]A[l−1]+b[l]A[l]=g(Z[l])其中,Z[l]和A[l]的维度均为(n[l],m)
损失函数(Loss Function)和成本函数(Cost Function)#
在正向传播和逆向传播之间还要先计算正向传播的损失(与实际值),再利用这个损失来进行逆向传播从而对权重进行修正。
损失函数是对于整体X中的某一样本X(i)而言的,即有:
L(X(i))=(y^(i)−y)2而成本函数则是对整个整体X而言的,即有:
J(X)=2m1i=1∑mL(X(i))可用如下的代码计算
1/2/m*np.sum(np.square(yhat-y))
Backward Propagation#
反向传播的基础是成本函数,下面用逻辑回归(Logistical Regression)做例子说明。
一个例子:逻辑回归#
逻辑回归下,一个常用的损失函数是:
L(y^,y)=−(ylny^+(1−y)ln(1−y^))当该神经网络一共有L层时,该损失函数对A[L]的导数即为:
dA[L]dL=−A[L]y+1−A[L]1−y已知dA[L]/dZ[L]=A[L](1−A[L]),则
dZ[L]dL =dA[L]dLdZ[L]dA[L]=A[L]−Y又由于Z[L]=W[L]A[L−1]+b[L],则
dW[L]dZ[L]=A[L−1]T那么,根据链式求导法则有:
dW[L]dL =dZ[L]dLdW[L]dZ[L]=(A[L]−Y)A[L−1]T进而对第L层神经网络有
dW[L]dJ=m1(A[L]−Y)A[L−1]Tdb[L]dJ=m1∑(A[L]−Y)对任意第l层神经网络有
dZ[l]dJ =dZ[l+1]dJdZ[l]dZ[l+1]=dZ[l+1]dJdA[l]dZ[l+1]dZ[l]dA[l]=W[l]TdZ[l+1]dJ×g′(Z[l])进而,有
dW[l]dJ =dZ[l]dJdW[l]dZ[l]=m1dZ[l]dJA[l−1]Tdb[l]dJ =dZ[l]dJdb[l]dZ[l]=m1∑dZ[l]dJ反向传播总结#
反向传播的关键是计算dZ[l]dJ,当用d(∙)表示d(∙)dJ时,可表示为:
dZ[l] dW[l] db[l]=W[l]TdZ[l+1]×g′(Z[l])=m1dZ[l]A[l−1]T=m1∑dZ[l]更新变量#
运用梯度下降法计算时,还要更新变量。一般而言,为了保证算法的收敛,需要设定一个学习速率(Learning Rate)来控制神经网络的更新。学习速率(用α来表示)作为一个超参数(Hyperparameter)需要我们不断进行测试来确定其最佳值。前文需要确定的神经网络层数L也是一个需要不断调整确定最佳值的超参数。
W[l] b[l]=W[l]−αdW[l]=b[l]−αdb[l]
神经网络的训练#
经过上述从正向传播到计算成本函数,到进行反向传播后的一个完整循环成为一个epoch。一般而言,随着完成的epoch次数的增加,成本函数(在训练集上)一直呈下降趋势,并最终收敛于一个稳定值(但此时并非一定达到了全局最优解,有可能是局部最优解):若与此同时,在测试集上的误差也较低,则神经网络训练较好;若训练集上误差很小,但是测试集上的误差较大,此时神经网络有较大的方差(Variance),或称为过拟合(Overfitting);若训练集上的误差也很大,此时神经网络有较大的偏差(Bias),或称为欠拟合(underfitting)。
一般而言,欠拟合的解决方法是:
- 调整超参数
- 训练更深的神经网络(即增加神经网络层数)
而过拟合的解决方法是:
- 收集更多的数据来进行训练
- 正则化(Regularization)
- 标准化(Normalization)