代价函数
L:神经网络的总层数。
Sl:第 l 层的单元(神经元)数,不包括偏置单元。
K:输出向量的维度数,对于二分类 K = 1,对于其他类别 K = 分类类别个数。
代价函数:
由于神经网络输出的是k维分类结果,所以计算的偏差是k个结果之和。
对于正则化项,在逻辑回归和神经网络中都是相同的,把所有的正则化项的参数全部累加;但偏置参数并不需要参与正则化,所以我们并没有将其加入到正则化中。
反向传播算法
反向传播算法的实质就是最小化代价函数。
前向传播:
a(l):第 l 层的激活值,在第一层为输入值,最后一层为输出值 。
反向传播算法:
aj(l):第 l 层的第 j 个结点的激活值。
δj(l):第 l 层的第 j 个结点的误差,δj(l)在某种程度上就捕捉到了我们在这个神经节点的激活值的误差。(第一层无误差)
g‘(z(l))= a(l).*(1 - a(l))
反向传播算法实现步骤:
(1)选择训练集
(2)初始化Δ = 0(用于计算偏导数)( ?)(请理解的大佬们给我说一下,这个循环到底是在计算什么;计算导数?)
(3)遍历训练集
①输入第 i 个样本的输入值
②利用前向传播计算各层的激活值 a(l)
③计算输出层的误差
④利用反向传播计算前面的误差
⑤更新?
理解反向传播
前向传播:
反向传播:
计算偏差:输出层的偏差为输出与实际的差。
那么输出层的偏差是如何来的呢?
输出层各维度的值与前一层相关联的结点和权值有关,那么前一层的偏差与其相关联的后一层的偏差和权值有关;所以把之后的偏差乘以对于权值再进行累加就等于之前的偏差。
使用注意:展开参数
执行 costFunction() :返回的是代价值以及导数值。
将返回值传递给高级最优化算法 fminunc()(也可使用其他优化算法) 。
将矩阵展开成长向量。
将长向量用于优化算法,再将返回的值化为矩阵。
梯度检测
梯度检测的方法用于检测一些程序的bug,比如虽然训练完成得到一个较好的效果,但是比无bug的误差高出一个量级。
导数近似值:双侧差分(结果更准确),单侧差分。
ε 通常取 10-4,太小会引起其他的数值问题。
多维度的梯度检测:
在Octave中的实现:
将用梯度检测得到的导数与在反向传播得到的梯度相比较,如是数值上大约相等,那么反向传播的实现是正确的。
在训练模型时记得关闭梯度检测(在验证反向传播实现是正确的),因为梯度检测是一个计算量非常大,非常慢的计算导数的程序。
随机初始化
在一些算法中,我们需要给θ初始化。
例如梯度下降算法。
对称权重问题:
在一些算法中,不能初始化参数为全零(但是初始化权重都相等会不会产生对称权问题呢?)。
例如神经网络:
在神经网络中,如果初始化所有的参数(也就是权重)相同,那么所有输入都相同,神经网络就失去了它的作用了,也就是对称权重问题。所以我们需要随机初始化。
随机初始化解决对称权重。
在Octave中的随机初始化:
组合到一起
当我们在训练一个神经网络的时候:
首先选择网络的大体框架,确定几个输入(特征量),几个隐藏层每个隐藏层(通常相同)几个单元,几个输出(分类类别)。
我们通常使用一个隐藏层;如果不使用一个隐藏层,也可选择多个隐藏层也是一样的(每个隐藏层通常单元相同),隐藏层(或者说隐藏单元)越多越好,但是计算量会变大;隐藏层的单元数一般是输入单元的 2~4 倍,只要大于输入层的单元数,一般都是可以接受的。
训练神经网络步骤:
①随机初始化权重
②前向传播,计算出hθ(x),也就是每一个x对应输出的y的向量
③用代码实现代价函数(cost function)J(θ)
④反向传播,算出J(θ)对于参数(权重)θ 的偏微分
⑤梯度检测;把反向传播计算得到的偏导值和利用双侧差分方法计算得到的估计值对比,确保二者大约相等。梯度检测是为了验证我们反向传播算法正确的;验证完成后,关闭梯度检查。
⑥使用梯度下降或者更高级的优化算法与反向传播算法相结合,最小化代价函数J(θ)。
通常情况下,代价函数会有多个局部最小值,例如下图(梯度下降和其他高级优化算法的基本原理):
使用梯度下降算法或者其他的一些高级优化算法,可能会使J(θ)处于局部最小值。但总体还是会使预测值和真实值尽可能的接近。(如果效果不好,也许可以多次重新训练,可能会得到一个较好的结果)