神经网络参数的反向传播算法
第七十二课:代价函数
神经网络是当下最强大的学习算法之一,那么在给定训练集时,如何为神经网络拟合参数?
神经网络在分类问题中的应用:
两种分类问题:
第一种是二元分类;这里的y只能是0或1,在这种情况下,我们会有且仅有一个输出单元。K:输出层的单元数目。
第二种是多类别分类问题:即会有K个不同的类,有K个输出单元,假设输出K维向量。
接下来为神经网络单元定义代价函数:
这时我们有K个输出单元,神经网络现在输出了R^K的向量:
第七十二课:反向传播算法
如何让代价函数最小化?反向传播算法!
假设只有一个训练样本时:
首先应用前向传播法来计算在给定输入的时候,假设函数是否会真的输出结果?
接下来,为了计算导数项,采用一种叫做反向传播的算法:
如何实现反向传播算法来计算这些参数的偏导数?
具体如何实现呢??
第七十四课:理解反向传播
反向传播算法在数学上并不是一个简单的算法,所以我们更多的应该关注反向传播的一些固定步骤,使你有一个更直观的感受,理解这些步骤到底在干什么,并向你证明至少是一个合理的方法!
首先尝试理解一下前向传播:
在反向传播中δL可以看作是我们在第I层中第j个单元中得到的激活项的"误差"。准确地说,δ项实际上是代价,函数cost(i)关于z(I)J的偏导数,也就是计算出的z项的加权和,或者说代价函数关于z项的偏导数。
具体来说,这个代价函数是一个关于标签y和神经网络h(x)的输出值的函数。如果分析网络的内部,稍微把z(l)j改一下,就会影响到神经网络中的值,最终改变代价函数的值。
总结:δ项实际上是代价函数关于这些所计算出的中间项的偏导数,它们衡量的是为了影响这些中间值,我们想要改变神经网络中的权重的程度,进而影响整个神经网络的输出h(x),并影响所有的代价函数。
顺带一体,这些δ值都只是关于隐藏单元,并不包括偏置单元,这取决于你对反向传播的定义以及实现算法的方式,你也可以计算包括偏置单元的δ值,偏置单元的输出总是“+1”,所以可以丢掉它们,因为它们不会影响偏导数的计算。
算法的内部原理和过程很难展现出来,但是很多人都已经使用了很多年哦!
第七十五课:使用注意:展开参数
怎么使用反向传播法计算代价函数的导数,这节课讲解怎么样把你的参数从矩阵展开成向量,以便我们在高级最优化步骤中的使用需要。
现在对怎样进行参数的矩阵表达式和向量表达式之间的来回转换有了一个新的认识。使用矩阵表达式的好处是当你的参数以矩阵的形式存储时,你在进行正向传播和反向传播时,你会觉得更加方便,当你把参数存储为矩阵时,也更容易充分利用向量化实现。向量表达式的优点是如果你有像thetaVec或者DVec这样的矩阵,当你使用一些高级优化算法时,这些算法通常要求把所有的参数要展开成一个长向量的形式。
第七十六课:梯度检测
反向传播很容易产生一些微妙的bug,当它与梯度下降或是其他算法一同工作时,看起来它确实能正常运行,并且代价函数J(θ)在每次梯度下降的迭代中也在不端缩小,虽然在反向传播的实现中存在一些bug,但运行情况看起来确实不错。虽然J(θ)在不断变小,但到了最后,你得到的神经网络其误差将会比无bug的情况下高出一个量级。如何应对出现bug的情况呢?
有一种思想叫做梯度检验,它能解决几乎所有这样的问题。所以每次在神经网络或者其他复杂模型中实现反向传播或者类似梯度下降算法时,都要做梯度检验。它将会保证你的前向传播以及后向传播都会是百分之百正确。
双侧差分和单侧差分:
从数值上去估算代价函数J关于任何参数的偏导数:
在神经网络中使用这种方法时,使用了for循环,来完成对神经网络中代价函数的所有参数的偏导数的计算,然后与反向传播中得到的梯度进行比较,以验证反向传播的实现是正确的。
总结:如何实现梯度检验以及为什么要关掉梯度检验:
梯度检验代码是一个计算量非常大的,也是非常慢的计算导数的程序,相对地,我们之前讲的反向传播算法是一个高性能的计算导数的方法,所以一旦你通过梯度检验反向传播的算法是正确的,就应该关掉梯度检验。
重申一下:在运行算法之前,比如多次迭代的梯度下降,或是多次迭代,或训练分类器的高级优化算法,先禁用你的梯度检验代码。具体地,如果你在每次梯度下降迭代或者在每次代价函数的内循环里,都进行一次梯度检验,程序就会变得非常慢,因为梯度检验代码相比于反向传播算法要慢很多。
第七十七课:随机初始化
当你执行一个算法,例如梯度下降法或者高级优化算法时,我们需要为变量θ选取一些初始值。
高级优化算法默认你会给它一个初始值,在梯度下降法中,初始化完毕后,一步一步通过梯度下降来最小化代价函数J,那么应该如何对θ设初始值呢?有一种想法是将θ值全部设为0。
没意义,对于神经网络:
这就意味着这个神经网络计算不出什么有趣的函数!所有的隐藏单元都在计算相同的特征,所有的隐藏单元都以相同的函数作为输出,这是一种高度冗余现象,最后的逻辑回归单元只能得到一个特征。为了避免这种情况的发生,要使用随机初始化的思想!
总而言之,为了训练神经网络,应首先要将权重随机初始化为一个接近0的,范围在-ξ到ξ之间的数,然后进行反向传播,再进行梯度检验,最后使用梯度下降或者其他高级优化算法来最小化代价函数J,这个关于参数θ的函数。
这是一种打破对称性的操作!
第七十八课:组合到一起
神经网络相互之间有怎么样的联系?以及神经网络学习算法的总体实现过程?
训练神经网络时,我们要做的第一件事就是选择一种网络架构(神经元之间的连接模式),输入单元,输出单元,隐藏层!怎么做出选择呢?
首先我们已经定义了输入单元的数量,一旦你确定了特征集x,输入单元的数量就等于特征x^(i)的维度,输入单元个数就确定下来了。
如果你正在进行多类别分类,那么输出层的数目将会由你分类问题中所要区分的类别个数确定,记得把y重新写成向量的形式。
隐藏层常见的是选择一层,即单隐藏层(较为合理的默认结构)。或者如果你使用不止一个隐藏层的话,同样也有一个合理的默认选项,那就是每一个隐藏层通常都应有相同的单元数。通常情况下,隐藏单元越多越好,不过如果有大量的隐藏单元,计算量一般会比较大。并且每个隐藏层所包含的单元数量还应该和输入x的维度相匹配,即和特征的数目匹配。隐藏单元的数目可以和输入特征的数量相同或者是它的二倍或者三四倍。
训练神经网络的步骤:
1.构建一个神经网络,然后随机初始化权重,通常把权重初始化为很小的值,接近于零
2.执行前向传播算法,即对于任意一个输入x(i),计算出对应的hθ(i),也就是一个输出值y的向量
3.通过代码计算代价函数J(θ)
4.通过反向传播算法计算出偏导数项J(θ)对参数θ的偏导数
通常使用一个for循环进行遍历!
5.是用梯度检查来比较这些已经计算出的偏导数项,把用反向传播算法得到的偏导数值与用数值方法得到的估计值进行比较。使用梯度检查确保两种方法得到基本接近的两个值。
停用梯度检查
6.使用一个最优化算法,比如说梯度下降算法或者更高级的优化方法,将这些优化方法和反向传播算法相结合。反向传播计算出这些偏导数项的值,现在可以计算偏导数,可以计算代价函数,就可以使用某个最优化方法来最小化关于θ的代价函数J(θ)。
对于神经网络,J(θ)是一个非凸函数,因此理论上可能停留在局部最小值的位置,实际上,梯度下降法和其他一些高级优化算法理论上都可能收敛于局部最小值,但一般来讲,在实际操作中,这些都不是大问题,尽管我们不能保证一定能得到全局最优值,但一般而言,算法运行的还是不错的,通常能够得到一个很小的局部最小值,尽管这可能不是全局最优值。
神经网络的梯度下降法和之前的线性回归梯度下降法其实原理差不多!
原理:试图找到某个最优的参数值使得神经网络的输出值与训练集观测到的y^(i)的实际值尽可能地接近。
不懂!没关系!如果你实现了反向传播算法,你一定会发现这的确是一个很强大的学习算法,如果你执行以下这个算法,执行反向传播,执行其中的优化算法,你一定会发现,反向传播算法能够让更复杂、强大、非线性的函数模型跟你的数据很好地拟合。
第八十课:无人驾驶
神经网络系统实现无人驾驶!