Ch9 是对神经网络模型的进一步深入。Ch8 主要是对神经网络模型的假设函数的阐述,而Ch9 则对神经网络模型的训练进行展开:首先类比logistic回归模型提出了神经网络模型的损失函数,并且叙述了用于求解最佳参数所用的反向传播算法。在训练网络前,首先需要使用梯度检验的方法验证反向传播算法是否正确。在正式训练时,初始化参数矩阵需使用随机初始化方法。最后对Ch8 和Ch9 的神经网络模型做了综合性的总结。
目录
神经网络的训练
损失函数
二分类问题的神经网络的输出层仅需1个神经元($y=0/1$);K分类问题的神经网络的输出层的神经元需要K个($y \in R^K$),用以输出k个不同的one-hot向量以区别K类。
logistic回归带正则项的损失函数为:
$$J(\theta)=\frac{1}{m}\sum_{i-1}^{m}[-y^{(i)}log(h_\theta(x^{(i)}))-(1-y^{(i)})log(1-h_\theta(x^{(i)}))]+\frac{\lambda}{2m}\sum_{j=1}^{n}\theta_j^2$$
不对偏置项做正则惩罚。
一个多分类问题的神经网络架构如下:

图9-1 某多分类神经网络
规定:
- m:输入样本的个数
- K:类别数
- $L$:神经网络中的层数
- $s_l$:第$l$层的单元个数(不包括偏置单元)
- $(h_\Theta(x))_i$:$h_\Theta(x)$的第i个输出
而神经网络带正则项的损失函数为
$$J(\Theta)=\frac{1}{m}\sum_{i-1}^{m}\sum_{k=1}^{K}[-y_k^{(i)}log(h_\Theta(x^{(i)}))k-(1-y_k^{(i)})log(1-(h_\Theta(x^{(i)}))_k)]+\frac{\lambda}{2m}\sum{l=1}^{L-1}\sum_{t=1}^{s_l}\sum_{j=1}^{s_{l+1}}\Theta_{jt}^2$$
双重求和对神经网络的输出层各输出单元求和。
三重求和对神经网络所有的权重因子进行正则项求和。
$t=1->t=s_l$,$j=1->j=s_{l+1}$表示不对各层偏置项做正则惩罚
反向传播Backpropagation
神经网络的目标是$min_\Theta ;J(\Theta)$以得到最好的神经网络参数$\Theta$。
因此我们需要完成计算$J(\Theta)$和$\frac{\partial}{\partial{\Theta_{i,j}}}J(\Theta)$。
反向传播算法:
- 导入m个训练样本${(x^(i),y^{(i)})},; i=1,\cdots,m$
- 对于训练样本t=1->m:
- 对于所有i,j,l,设定$\Delta_{ij}^{(l)}=0$,即$\Delta^{(l)}=0$
- $a^{(1)}=x^{(t)}$
- 前向传播计算所有的$a^{(l)},;l=2,\cdots,L$
- $\delta^{(L)}=a^{(L)}-y^{(t)}$
- $\delta^{(l)}=((\Theta^{(l)})^T\delta^{(l+1)}).g’(z^{(l)})=((\Theta^{(l)})^T\delta^{(l+1)}).*a^{(l)}.(1-a^{(l)}),l=L-1,\cdots,2$
- $\Delta_{ij}^{(l)}:=\Delta_{ij}^{(l)}+a_j^{(l)}\delta_i^{(l+1)}$,即$\Delta^{(l)}:=\Delta^{(l)}+\delta^{(l+1)}(a^{(l)})^T$
- 建立D矩阵:
- $D_{i,j}^{(l)}=\frac{1}{m}(\Delta_{i,j}^{(l)}+\lambda\Theta_{i,j}^{(i)}),;if;j\not=0$
- $D_{i,j}^{(l)}=\frac{1}{m}(\Delta_{i,j}^{(l)},;if ;j=0$
- 得到$\Theta$的偏导数$\frac{\partial}{\partial{\Theta_{i,j}^{(l)}}}J(\Theta)=D_{i,j}^{(l)}$。
- 对于所有i,j,l,用优化算法更新$\Theta_{i,j}^{(l)}$。
l:当前层在第几层
i,j:权重线的索引
.*:对应元素相乘
其中2.6是对以该单元为起点的后层单元误差的反向加权求和,2.7对其求均值,非偏置项加上正则项,一次得到损失函数相对于各参数的偏导数,2.9中可以用梯度下降法等优化方法对参数矩阵进行优化。
反向传播算法直观理解
是图8-4的神经网络的简化:若是仅考虑输出层和最后一层隐藏层,可认为是一个logistc回归函数。
则输出单元的误差可以通过各连接权重的倒数分配给输入单元,由此层层传递,可以一直计算到第一个隐藏层的单元的误差,进而对权重矩阵进行更新。
梯度检验
因为神经网络的训练耗时较长,故我们应先验证自己编写的反向传播算法是否正确,即用数值梯度检验来验证梯度是否一直在下降,再做进一步训练。
将参数矩阵$\Theta$平展为向量$\theta\in R^n$,再分别求损失函数$J(\theta)$相对与$\theta$各分量的偏导数,即$\frac{\partial}{\partial{\theta_{i}}}J(\theta)=\frac{J(\cdots ,\theta_i+\epsilon,\cdots)-J(\cdots ,\theta_i-\epsilon,\cdots)}{2\epsilon},; i=1,\cdots,n$,其中$\epsilon$是一个极小的实数。
在一个样本输入后,计算反向传播计算得到神经网络模型的损失函数关于当前假设函数参数的偏导数矩阵,对其平展;然后使用上述数值计算方法也得到神经网络模型损失函数关于当前假设函数参数的偏导数矩阵。两者进行比较,若两个向量各对应元素数值相差较大,梯度下降算法有误需更正;若两者相近则可以进行关闭梯度检验进行下一步的模型训练。
随机初始化
训练阶段,若将参数矩阵$\Theta$中元素全设为0,此法不可取,原因是:在前向传播的过程中,若是第i->i+1层的权重全为0,则第i+1层所有单元的值均相等(等于0),后面的层的单元值也都为0,反向传播过程,误差对各参数偏导也都相等,无法区分不同参数的权重,难以完成有效的神经网络训练,所以我们需要进行随机初始化。
若要对每个参数限制边界,并对他们进行均匀分布初始化,则可以用以下matlab/octave代码:
1 | %i:箭头右边的单元 |
参数优化
我们前面接触的线性回归和logistic回归均是由梯度下降法进行参数优化,因为其的假设函数是凸函数,且训练步数少。但神经网络的假设函数往往比较复杂,参数多,而梯度下降算法除了不一定能达到全局最优外,还有另一问题是计算时间过长。
因为要在全部训练数据上最小化损失,所以损失函数是在所有训练数据上的损失之和。因此,在每轮迭代都需全部计算数据损失和海量数据情况下,是很耗时的。
一个可行的参数优化算法是视频中提到的,通过将参数矩阵平展得到一个向量,调用matlab/octave中的fminc优化算法来求解最优解后,重新反平展为权重矩阵。
此外,也有其他的优化算法,例如随机梯度下降算法SGD(stochastic gradient descent)。该算法优化的不是在全部训练数据上的损失函数,而是每轮迭代中随机优化的某一些数据上的损失函数(正如在反向传播Backpropagation写的反向传播算法),因此加快了训练速度。而又因其随机局部性,故而可能产生“无法达到局部最优”的问题。我们将在本文最后介绍随机梯度下降算法。
神经网络综合
如果你要训练一个神经网络模型,
- 需要选择一个神经网络结构:
- 输入层单元个数:需要对应一个样本输入的特征维数
- 输出层单元个数:需要对应分类的类别数
- 隐藏层单元个数:一般认为越多越好
- 隐藏层层数:默认有1个,若多个隐藏层,推荐各层的单元格数相同
- 其次训练神经网络:
- 随机初始化权重
- 利用前向传播计算所有输入样本的$h_\Theta(x)$
- 计算$J(\Theta)$
- 反向传播计算$J(\Theta)$关于$\Theta$的偏导数
- 梯度检验上一步得到的偏导数
- 使用优化算法最小化代价函数,得到模型参数$\Theta$
训练时使用到所有的样本,每输入一个样本就要使用一次前向传播和一次反向传播,如下:
1 | for i = 1:m, |