神经网络学习

Posted by jjx on December 5, 2016

代价函数
首先引入一些便于稍后讨论的新标记方法: 假设神经网络的训练样本有 m 个,每个包含一组输入 x 和一组输出信号 y,L 表示神经 网络层数,$S_l$ 表示每层的 neuron 个数($SL$ 表示输出层神经元个数),$S_L$ 代表最后一层中处理 单元的个数。

将神经网络的分类定义为两种情况:二类分类和多类分类, 二类分类:$S_L$=1, y=0 or 1 表示哪一类;
K 类分类:$S_L$=K, $y_i$ = 1 表示分到第 i 类;(K>2)

在逻辑回归中,我们只有一个输出变量,又称标量(scalar),也只有一个因变量 y,但 是在神经网络中,我们可以有很多输出变量,我们的 hθ(x)是一个维度为 K 的向量,并且我 们训练集中的因变量也是同样维度的一个向量,因此我们的代价函数会比逻辑回归更加复杂 一些,为:

这个看起来复杂很多的代价函数背后的思想还是一样的,我们希望通过代价函数来观察 算法预测的结果与真实情况的误差有多大,唯一不同的是,对于每一行特征,我们都会给出 K 个预测,基本上我们可以利用循环,对每一行特征都预测 K 个不同结果,然后在利用循环 在 K 个预测中选择可能性最高的一个,将其与 y 中的实际数据进行比较。

归一化的那一项只是排除了每一层 $θ_0$ 后,每一层的 θ 矩阵的和。最里层的循环 j 循环 所有的行(由 $s_l$ +1 层的激活单元数决定),循环 i 则循环所有的列,由该层($s_l$ 层)的激 活单元数所决定。即:hθ(x)与真实值之间的距离为每个样本-每个类输出的加和,对参数进行 regularization 的 bias 项处理所有参数的平方和。

反向传播算法

之前我们在计算神经网络预测结果的时候我们采用了一种正向传播方法,我们从第一层 开始正向一层一层进行计算,直到最后一层的 hθ(x)。
现在,为了计算代价函数的偏导数,我们需要采用一种反向传播算法,也 就是首先计算最后一层的误差,然后再一层一层反向求出各层的误差,直到倒数第二层。 以 一个例子来说明反向传播算法。

假设我们的训练集只有一个实例$(x^{(1)},y^{(1)})$,我们的神经网络是一个四层的神经网络, 其中 K=4,$S_L$=4,L=4:
前向传播算法:

我们从最后一层的误差开始计算,误差是激活单元的预测$a^{(4)}_k$与实际值(yk)之间 的误差,(k=1:K)。 我们用 δ 来表示误差,则: $δ^{(4)}=a^{(4)}-y$

关于反向误差的计算方法可以参见:关于第5周反向传播算法的一些争论与思考
具体数学推导可以参见:反向传播(Backpropagation)算法的数学原理

\[\delta^{(l)}_j=\frac{\sigma}{\sigma(z^{(l)}_j)}J(\theta)\]

重要的是清楚地知道上面式子中上下标的含义:
l 代表目前所计算的是第几层
j 代表目前计算层中的激活单元的下标,也将是下一层的第 j 个输入变量的下标。
i 代表下一层中误差单元的下标,是受到权重矩阵中第 i 行影响的下一层中的误差单元的下标。

如果我们考虑归一化处理,并且我们的训练集是一个特征矩阵而非向量。在上面的特殊 情况中,我们需要计算每一层的误差单元来计算代价函数的偏导数。在更为一般的情况中, 我们同样需要计算每一层的误差单元,但是我们需要为整个训练集计算误差单元,此时的误 差单元也是一个矩阵,我们用$\Delta^{(l)}_{ij}$来表示这个误差矩阵。第 l 层的第 i 个激活单元受到第 j 个参数影响而导致的误差。

我们的算法表示为:

即首先用正向传播方法计算出每一层的激活单元,利用训练集的结果与神经网络预测的 结果求出最后一层的误差,然后利用该误差运用反向传播法计算出直至第二层的所有误差。 在求出了 $\Delta^{(l)}_{ij}$之后,我们便可以计算代价函数的偏导数了,计算方法如下:

实现注意:展开参数
在上一段视频中,我们谈到了怎样使用反向传播算法计算代价函数的导数。在这段视频 中,我想快速地向你介绍一个细节的实现过程,怎样把你的参数从矩阵展开成向量,以便我 们在高级最优化步骤中的使用需要,使用方法见上图。

梯度检验
当我们对一个较为复杂的模型(例如神经网络)使用梯度下降算法时,可能会存在一些 不容易察觉的错误,意味着,虽然代价看上去在不断减小,但最终的结果可能并不是最优解。 为了避免这样的问题,我们采取一种叫做梯度的数值检验(Numerical Gradient Checking) 方法。这种方法的思想是通过估计梯度值来检验我们计算的导数值是否真的是我们要求的。 对梯度的估计采用的方法是在代价函数上沿着切线的方向选择离两个非常近的点然后 计算两个点的平均值用以估计梯度。即对于某个特定的 θ,我们计算出在 θ-ε 处和 θ+ε 的代 价值(ε 是一个非常小的值,通常选取 0.001),然后求两个代价的平均,用以估计在 θ 处 的代价值。


注意
一旦确认参数正确,开始训练样本,就必须关闭梯度检测,因为梯度检测效率低下,比反向传播要慢很多。

随机初始化
任何优化算法都需要一些初始的参数。到目前为止我们都是初始所有参数为 0,这样的 初始方法对于逻辑回归来说是可行的,但是对于神经网络来说是不可行的。如果我们令所有 的初始参数都为 0,这将意味着我们第二层的所有激活单元都会有相同的值。同理,如果我 们初始所有的参数都为一个非 0 的数,结果也是一样的。 我们通常初始参数为正负 ε 之间的随机值,假设我们要随机初始一个尺寸为 10×11 的 参数矩阵,代码如下:
Theta1 = rand(10, 11) * (2*eps) – eps

综合起来

小结一下使用神经网络时的步骤:
网络结构:第一件要做的事是选择网络结构,即决定选择多少层以及决定每层分别有多 少个单元。 第一层的单元数即我们训练集的特征数量。 最后一层的单元数是我们训练集的结果的类的数量。 如果隐藏层数大于 1,确保每个隐藏层的单元个数相同,通常情况下隐藏层单元的个数 越多越好。

我们真正要决定的是隐藏层的层数和每个中间层的单元数。

训练神经网络:

  1. 参数的随机初始化
  2. 利用正向传播方法计算所有的 hθ(x)
  3. 编写计算代价函数 J 的代码
  4. 利用反向传播方法计算所有偏导数
  5. 利用数值检验方法检验这些偏导数
  6. 使用优化算法来最小化代价函数