代价函数
将神经网络的分类定义为两种情况:二类分类和多元分类
二类分类 |
多元分类 |
y=0 or 1 | |
1个输出结点 | k个输出结点 |
代价函数: | 代价函数: |
逻辑回归问题中我们的代价函数为:
神经网络的代价函数:
代价函数第一行大括号内的值为多元分类中的每个代价函数的求和。
正则项的三重循环求和代表了中间隐藏层的所有参数都已经加上了。
反向传播算法
现在,为了使得代价函数最小化求参数的值,我们需要计算代价函数的偏导数,我们需要采用一种反向传播算法,也就是首先计算最后一层的误差,然后再一层一层反向求出各层的误差,直到倒数第二层。 以一个例子来说明反向传播算法:
首先是正向传播的计算:
反向传播为:
解释;我们从最后一层的误差开始计算,误差是激活单元的预测()与实际值( )之间的误差。
我们用来表示误差,则: =
我们利用这个误差值来计算前一层的误差:
其中是S型函数的导数,=。
而则是权重导致的误差的和,下一步是继续计算第二层的误差:
因为第一层是输入变量,不存在误差。我们有了所有的误差的表达式后,便可以计算代价函数的偏导数了,假设 = 0,即我们不做任何正则化处理时有:
重要的是清楚地知道上面式子中上下标的含义:
l 代表目前所计算的是第几层。
j 代表目前计算层中的激活单元的下标,也将是下一层的第j个输入变量的下标。
i 代表下一层中误差单元的下标,是受到权重矩阵中第?行影响的下一层中的误差单元的下标。
如果我们考虑正则化处理,并且我们的训练集是一个特征矩阵而非向量。在上面的特殊情况中,我们需要计算每一层的误差单元来计算代价函数的偏导数。在更为一般的情况中,我们同样需要计算每一层的误差单元,但是我们需要为整个训练集计算误差单元,此时的误差单元也是一个矩阵,我们用 来表示这个误差矩阵。第 l 层的第 i 个激活单元受到第 j个参数的影响而导致的误差。
反向传播的步骤:
梯度检验
当我们对一个较为复杂的模型(例如神经网络)使用梯度下降算法时,可能会存在一些不容易察觉的错误,意味着,虽然代价看上去在不断减小,但最终的结果可能并不是最优解。
为了避免这样的问题,我们采取一种叫做梯度的数值检验(Numerical Gradient Checking)方法。这种方法的思想是通过估计梯度值来检验我们计算的导数值是否真的是我们要求的。
对梯度的估计采用的方法是在代价函数上沿着切线的方向选择离两个非常近的点然后计算两个点的平均值用以估计梯度。即对于某个特定的 ,我们计算出在处和 的代价值(是一个非常小的值,通常去0.001),然后除以他们的距离2,用来估计在的导数。
在我们求该点的斜率的时候,我们不直接使用其导数,而是用
当是一个向量时,我们则需要对偏导数进行检验。因为代价函数的偏导数检验只针对一个参数的改变进行检验,下面是一个只针对进行检验的示例:
最后我们还需要对通过反向传播方法计算出的偏导数进行检验。
最后在使用算法学习的时候关闭梯度检验。因为梯度检验主要是为了让我们知道我们写的程序算法是否存在错误,而不是用来计算导数的,因为这种方法计算导数相比于之前的会非常慢。
总结一下:
- 通过反向传播来计算 DVec,DVec 是每个矩阵打包展开的形式。
- 实现数值上的梯度检测,计算出 gradApprox。
- 比较 是否相等或者约等于。
- 使用算法学习的时候记得要关闭这个梯度检验,梯度检验只在代码测试阶段进行。
随机初始化
在之前的线性回归和逻辑回归中,使用梯度函数,初始值设置为0是没有问题的,但是到了神经网络里面,如果还这么设置,会出现高度冗余现象。
假设我们有这样一个网络,其初始参数都设为0。那么我们会发现其激励 ,且误差 ,且导数 。这就导致了在参数更新的情况下,两个参数是一样的。无论怎么重复计算其两边的激励还是一样的。
上述问题被称为,对称权重问题,也就是所有权重都是一样的。所以随机初始化是解决这个问题的方法。
我们将初始化权值 的范围限定在 。
总结
1. 准备
首先,我们需要确定神经网络有多少输入单元,有多少隐藏层,每一层隐藏层又有多少个单元,还有多少输出单元。那我们怎么去选择呢?
- 输入单元是特征向量 的维度
- 输出单元是分类的个数
- 每个隐藏层的单元数通常是越多越好(必须与计算成本平衡,因为随着更多隐藏单元的增加而增加)
- 默认值:1个隐藏层。如果有多个隐藏层,那么建议您在每个隐藏层中都有相同数量的单元。
输出单元如果是多元分类问题,输出单元需要写成矩阵的形式:
例如有3个分类, 输出单元应该写成
2. 训练
第一步:随机初始化权重。初始化的值是随机的,值很小,接近于零。
第二步:执行前向传播算法,对于每一个 计算出假设函数 。
第三步:计算出代价函数 。
第四步:执行反向传播算法,计算出偏导数 。
具体操作就是使用一个for循环,先将 进行一次前向传播和后向传播的操作,然后再对 进行相同的操作一直到 ,这样就能得到神经网络中每一层中每个单元对应的激励值,和每一层激励的误差 。
第五步:利用梯度检查,对比反向传播算法计算得到的偏导数项是否与梯度检验算法计算出的导数项基本相等。检查完记得删除掉这段检查的代码。
第六步:最后我们利用梯度下降算法或者更高级的算法例如 LBFGS、共轭梯度法等,结合之前算出的偏导数项,最小化代价函数 算出权值的大小 。
理想情况下,只要满足了 ,就能使我们的代价函数最小。但是,代价函数 不是凸的,因此我们最终可以用局部最小值代替全局最小值。