首先引入以下要使用的新的标记符号:
假设神经网络的训练样本有m个,每个包含一组输入 x 和一组输出信号 y,L 表示神经网络层数,表示每层的神经元个数,代表最后一层中处理单元的个数。k表示输出层的单元数目(即表示这个问题分k类)
回顾逻辑回归中的代价函数为:
在逻辑回归中,只有一个输出变量,又称标量,即只有一个因变量y,但是在神经网络中,我们可以有很多输出变量,是一个维度为 k 的向量,并且训练集中的因变量也是同样维度的一个向量,因此神经网络的代价函数会比逻辑回归更加复杂一些,为:
这个看起来复杂很多的代价函数背后的思想还是一样的,都是希望通过代价函数来观察算法预测的结果与真实情况的误差有多大,唯一不同的是,对于每一行特征,都会给出 k 个预测,基本上可以利用循环,对每一行特征都预测 k 个不同结果,然后再利用循环在 k 个预测中选择可能性最高的一个,将其与 y 中的实际数据进行比较。
正则化的那一项只是每一层的矩阵的和(排除)。最里层的循环 j 循环所有的行(由+1 层的激活单元数决定),循环 i 则循环所有的列,由该层(层)的激活单元数所决定。
反向传播算法:
之前在计算神经网络预测结果的时候我们采用了一种正向传播方法,我们从第一层开始正向一层一层进行计算,直到计算出最后一层的。
现在,为了更简便高效计算代价函数的偏导数,需要采用一种反向传播算法,也就是首先计算最后一层的误差,然后再一层一层反向求出各层的误差,直到倒数第二层。以一个例子来说明反向传播算法。
假设我们的训练集只有一个样本(),假设构建的神经网络是一个四层的神经网络,其中 k=4,=4,L=4;
前向传播算法:
反向传播:
反向传播中的数学原理:(这里为了方便理解,设只有一个训练样本)
定义新的标记:表示第l 层的第j个结点的误差。
这里的误差的计算实际上类似于前向传播:(考虑简单情况,先不考虑正则化项)
从最后一层的误差开始计算,误差表示的是激活单元的预测与实际值之间的误差。(以下图片显示的向量化了)
注:
这里依次反向传播计算到第二层的误差,因为第一层是输入变量,不存在误差。
有了所有的误差的表达式后,便可以计算代价函数的偏导数了,假设,即我们不做任何正则化处理时有:
如果我们考虑正则化处理,并且我们的训练集是一个特征矩阵而非向量。在上面的特殊情况中,我们需要计算每一层的误差单元来计算代价函数的偏导数。在更为一般的情况中,我们同样需要计算每一层的误差单元,但是我们需要为整个训练集计算误差单元,此时的误差单元也是一个矩阵,我们用来表示这个误差矩阵。第 j 层的第 i 个激活单元受到第 j 个参数影响而导致的误差。
首先用正向传播方法计算出每一层的激活单元,利用训练集的结果与神经网络预测的结果求出最后一层的误差,然后利用该误差运用反向传播法计算出直至第二层的所有误差。然后计算出的偏导数:
最后在利用梯度下降等优化算法来最小化代价函数。
梯度检测:--保证前向传播和反向传播基本保证百分百正确
当对一个较为复杂的模型(例如神经网络)使用梯度下降算法时,可能会存在一些不容易察觉的错误,意味着,虽然代价看上去在不断减小,但最终的结果可能并不是最优解。为了避免这样的问题,可以采取一种叫做梯度的数值检验方法。这种方法的思想是通过估计梯度值来检验我们计算的导数值是否真的是我们要求的。
对梯度的估计采用的方法是在代价函数上沿着切线的方向选择离两个非常近的点然后采用数学计算导数的方法用以估计梯度。即对于某个特定的,我们计算出在处和的代价值(是一个非常小的值,通常选取 0.001),然后求两个代价的平均,用以估计在处的代价值。
以上仅是当为实数时,当是一个向量时,代价函数的偏导数检验只针对一个参数的改变进行检验,下面是一个只针对进行检验的示例:(其余计算与之类似)
最后将得到的数值与反向传播得到的偏导数进行比较,看在数值上是否接近,如果非常接近,则认为反向传播的实现是正确的。一旦检验确定反向传播是正确的,就应该立刻关掉梯度检测,因为梯度检测的计算量很大,影响效率。
根据上面的算法,计算出的偏导数存储在矩阵 中。检验时,我们要将该矩阵展开成为向量,同时我们也将 矩阵展开为向量,我们针对每一个 都计算一个近似的梯度值,将这些值存储于一个近似梯度矩阵中,最终将得出的这个矩阵同 进行比较。
随机初始化:
任何优化算法都需要一些初始的参数。到目前为止都是初始所有参数为0,这样的初始方法对于逻辑回归来说是可行的,但是对于神经网络来说是不可行的。如果令所有的初始参数都为0,这将意味着第二层的所有激活单元都会有相同的值。同理,如果我们初始所有的参数都为一个非0的数,结果也是一样的,所以需要随机初始化
训练神经网络过程总结:
小结一下使用神经网络时的步骤:
网络结构:第一件要做的事是选择网络结构,即决定选择多少层以及决定每层分别有多少个单元。
输入层-第一层的单元数即我们训练集的特征数量。输出层-最后一层的单元数是我们训练集的结果的类的数量。隐藏层-如果隐藏层数大于1,确保每个隐藏层的单元个数相同,通常情况下隐藏层单元的个数越多越好。(但要考虑复杂性)
真正要决定的是隐藏层的层数和每个中间层的单元数。
训练神经网络:
1. 随机初始化参数(权重)
2. 利用正向传播方法计算所有的
3. 编写计算代价函数的代码, 计算代价函数
4. 用反向传播方法计算所有偏导数
5. 利用数值检验方法检验这些偏导数
6. 使用优化算法(梯度下降法等)来最小化代价函数