机器学习 吴恩达 第八章 笔记
八、神经网络的学习(Neural Networks: Learning)
在本节,我们学习一个新的神经网络算法.它能在给定训练集的同时,为神经网络拟合参数.与其他算法一样,我们从代价函数开始.
8.1 代价函数
首先引入一些便于稍后讨论的新标记方法:
假设神经网络的训练样本有4
)代表最后一层中处理单元的个数.
将神经网络的分类定义为两种情况:二类分类和多类分类.
现在来为我们的神经网络定义代价函数.我们回顾逻辑回归问题中我们的代价函数为:
在逻辑回归中,我们只有一个输出变量,又称标量(scalar
),也只有一个因变量.但是在神经网络中,我们可以有很多输出变量,我们的
因为我们比逻辑回归问题多了
这个看起来复杂很多的代价函数背后的思想还是一样的,我们希望通过代价函数来观察算法预测的结果与真实情况的误差有多大,唯一不同的是,对于每一行特征,我们都会给出
正则化的那一项只是排除了每一层regularization
的bias
项处理所有参数的平方和.
同样,这个代价函数就算计入了
8.2 反向传播算法
本节我们讲述如何最小化神经网络的代价函数的方法.
下面是我们的代价函数,我们要做的就是找到参数
计算成本函数只需要上面的公式,所以本节注重偏导数计算.
我们从样本集中只有一个样本的情况开始说起:
而神经网络是一个四层的神经网络,其中
反向传播算法,直观上来说,就是对每一个结点计算误差j
表示第l
表示第
以下图为例,我们从最后一层的误差开始计算,误差是激活单元的预测(
我们这里补充一下吴老师没讲的定义:
我们利用这个误差值来计算前一层的误差:
其中,
后面的第一层就不用算了,因为第一层是输入变量,不存在误差.我们有了所有的误差的表达式后,便可以计算代价函数的偏导数了.
假设
重要的是清楚地知道上面式子中上下标的含义:
代表目前所计算的是第几层. 代表目前计算层中的激活单元的下标,也将是下一层的第 个输出变量的下标. 代表下一层中误差单元的下标,是受到权重矩阵中第 行影响的下一层中的误差单元的下标.
现在汇总起来考虑,假使我们训练集有
我们首先要做的就是设置
接下来遍历我们的训练集,然后设置
来累计我们计算的偏导数项.请注意,
在求出了
当我们计算出了
理解完全看不懂,这里有两篇详细的推导,建议看:
(1) 基本解释了每一个问题,这个有个问题是它的代价函数是没有计入
(2) 配合上面的看
还有我个人也和(1)同感,认为
8.3 理解反向传播
&esmp; 要理解反向传播,我们必须先理解前向传播:
我们必须理解这些符号,比如
接下来看看代价函数:
上面的代价函数只适用于只有一个输出单元的情况,如果我们有多个输出单元需要在
.这里我们同样忽略正则项,剩下的项相当于
反向传播的关键是
这副图没有计入偏置单元,我们也可以采取其他方法计入,但是请记住偏置单元的输出永远是1
.老师自己的做法是计算偏导没有计入偏置单元.
9.4 实现注意:展开参数
在上一节中,我们谈到了怎样使用反向传播算法计算代价函数的导数.在这段视频中,我想快速地向你介绍一个细节的实现过程,怎样把你的参数从矩阵展开成向量,以便我们在高级最优化步骤中的使用需要.
我们在作业使用的fmin_unc
函数,它的参数和计算梯度的函数返回值都需要是n
维或n+1
维向量,但是我们在一个完整的神经网络中,得到的参数和梯度都是矩阵,这就需要我们将矩阵展开为向量.
用Octave
语言表达就是如下,思想概况一下就是利用切片和reshape
来做到相互转换.
配合代码实现就是,在传参给fmin_unc
函数的时候,我们传的参数Cost
函数或者梯度函数我们需要将一维向量reshape回原来的参数矩阵.同样我们计算梯度函数的时候也需要转成一维返回.
9.5 梯度检测
当我们对一个较为复杂的模型(例如神经网络)使用梯度下降算法时,可能会存在一些不容易察觉的错误,意味着,虽然代价看上去在不断减小,但最终的结果可能并不是最优解.
为了避免这样的问题,我们采取一种叫做梯度的数值检验(Numerical Gradient Checking)方法.这种方法的思想是通过估计梯度值来检验我们计算的导数值是否真的是我们要求的.它是100%正确.
考虑下面这个例子:
上图是0.001
,当它足够小,就变成了真正的导数),在特定点的两边取
这也被称为双侧差分,比单侧差分(分母没有
上面我们只讨论了
用代码实现的情况如下:
我们用此方法检验反向传播的偏导数.计算出的偏导数存储在矩阵
所以步骤就是先用反向传播计算出偏导矩阵,再用梯度估计检验.但是我们不要使用梯度检验的方法计算梯度,因为计算量太大,上一节的方法是一个更为高效的方法.例如,如果我们在梯度下降的迭代或代价函数的内循环里使用了梯度检验,就会拖累程序进度.
9.6 随机初始化
前面我们讲述了所有神经网络要实现的内容,本节讲述最后的一个思想:随机初始化.
任何优化算法都需要一些初始的参数.到目前为止我们都是初始所有参数为0,这样的初始方法对于逻辑回归来说是可行的,但是对于神经网络来说是不可行的.如果我们令所有的初始参数都为0,这将意味着我们第二层的所有激活单元都会有相同的值,再将得到的激活单元代入之前我们计算的
具体证明参考这里:Click,知乎这个公式显示地不行,配合这个看Click
这相当于隐藏层无论每层有多少个结点,实际只有一个结点在起作用.
所以我们需要随机初始化参数,顺带一提
我们通常初始参数为正负ε之间的随机值(0
),假设我们要随机初始一个尺寸为10×11
的参数矩阵,代码如下:
Theta1 = rand(10, 11) * (2*eps) – eps
9.7 综合起来
本节的内容就是将前几节的内容综合.
小结一下使用神经网络时的步骤:
(1) 选择网络架构.即决定选择多少层以及决定每层分别有多少个单元.输入层的单元个数就是特征向量的维数,而输出层的个数(比如多类别问题)就是类的个数(注意输出的y
向量是01
向量,而不是直接等于1,2,3,4...).比较关键的是隐藏层,我们通常默认隐藏层是1
,如果不是1
,通常默认每层都有相同的单元个数.通常隐藏单元越多越好(大多为输入层个数的倍数),但是太多会有计算量太大的问题.
(2) 接下来介绍训练神经网络的步骤.
- 参数的随机初始化(通常是接近0的值)
- 利用正向传播方法计算所有的
- 写计算代价函数
的代码 - 利用反向传播方法计算所有偏导数
对于不熟悉的新手,老师推荐使用for
循环对每一个样本遍历,在for
循环里累加for
循环外(遍历完所有样本后)再计算偏导数.
- 利用数值检验方法检验这些偏导数
- 使用优化算法来最小化代价函数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
2021-01-19 The Settlers of Catan POJ - 2258
2021-01-19 P1414 又是毕业季II
2021-01-19 P2660 zzc 种田
2021-01-19 AcWing 1246. 等差数列
2021-01-19 AcWing 1230. K倍区间