Machine Learning Chinese NLP :::: Training a Neural Network - Chad Salinas ::: Data Scientist
Life and times of Chad Salinas
Chad Salinas, golf caddy, data scientist, chad rPubs, recovering chess addict, daddy caddy
1284
post-template-default,single,single-post,postid-1284,single-format-standard,qode-listing-1.0.1,qode-social-login-1.0,qode-news-1.0,qode-quick-links-1.0,qode-restaurant-1.0,ajax_fade,page_not_loaded,,qode-title-hidden,qode_grid_1300,qode-theme-ver-12.0.1,qode-theme-bridge,bridge,wpb-js-composer js-comp-ver-5.4.2,vc_responsive

Machine Learning Chinese NLP :::: Training a Neural Network

Training a Neural Network

我们已经用了 
几节视频的内容 
来介绍神经网络算法

在这段视频中 
我想结合我们所讲的 
所有这些内容 
来做一个总体的回顾 
看看这些零散的内容 
相互之间有怎样的联系 
以及神经网络学习算法的 
总体实现过程

当我们在训练一个神经网络时 
我们要做的第一件事 
就是搭建网络的大体框架 
这里我说的框架 意思是 
神经元之间的连接模式 
我们可能会从以下几种结构中选择 
第一种神经网络的结构是 
包含三个输入单元 
五个隐藏单元 
和四个输出单元 
第二种结构是 三个输入单元作为输入层 
两组五个隐藏单元作为隐藏层 四个输出单元的输出层 
然后第三种是3 5 5 5 
其中每个隐藏层包含五个单元 
然后是四个输出单元 
这些就是可能选择的结构 
每一层可以选择 
多少个隐藏单元 
以及可以选择多少个隐藏层 
这些都是你构建时的选择 
那么我们该如何做出选择呢?

首先 我们知道 
我们已经定义了输入单元的数量 
一旦你确定了特征集x 
对应的输入单元数目 
也就确定了 
也就是等于特征x{i}的维度 
输入单元数目将会由此确定 
如果你正在进行 
多类别分类 
那么输出层的单元数目 
将会由你分类问题中 
所要区分的类别个数确定 
值得提醒的是 
如果你的多元分类问题 
y的取值范围

是在1到10之间 
那么你就有10个可能的分类

别忘了把你的y 
重新写成向量的形式 
所以现在我们的y不是一个数了 
我们重新把y写成 
这种形式的向量 
第二个分类我们可以写成这样的向量 
所以 比如说 
如果要表达 
第五个分类 也就是说y等于5 
那么在你的神经网络中 
就不能直接用 
数值5来表达 
因为这里的输出层 
有十个输出单元 
你应该用一个向量 
来表示

这个向量的第五个位置值是1 
其它的都是0 
所以对于输入单元 
和输出单元数目的选择 
还是比较容易理解的

而对于隐藏单元的个数 
单元的个数 
以及隐藏层的数目 
我们有一个默认的规则 
那就是只使用单个隐藏层 
所以最左边所示的 
这种只有一个隐藏层的神经网络 
一般来说是最普遍的

或者如果你使用 
不止一个隐藏层的话 
同样我们也有一个默认规则 
那就是每一个隐藏层 
通常都应有相同的单元数 
所以对于这个结构 
我们有两个隐藏层 
每个隐藏层都有相同的单元数 
都是5个隐藏单元 
这里也是一样 
我们有三个隐藏层 
每个隐藏层有相同的单元数 
都是5个隐藏单元

但实际上通常来说 
左边这个结构是较为合理的默认结构

而对于隐藏单元的个数 
通常情况下 
隐藏单元越多越好 
不过 我们需要注意的是 
如果有大量隐藏单元 
计算量一般会比较大 
当然 一般来说隐藏单元还是越多越好

并且一般来说 每个隐藏层 
所包含的单元数量 
还应该和输入x 
的维度相匹配 
也要和特征的数目匹配 
可能隐藏单元的数目 
和输入特征的数量相同 
或者是它的二倍 或者三倍 四倍 
因此 隐藏单元的数目需要和其他参数相匹配 
一般来说 
隐藏单元的数目取为稍大于 
输入特征数目 
都是可以接受的 
希望这些能够给你 
在选择神经网络结构时 
提供一些有用的建议和选择的参考 
如果你遵循了这些建议 
你一般会得到比较好的模型结构 
但是 
在以后的一系列视频中 
特别是在我谈到 
学习算法的应用时 
我还会更详细地介绍 
如何选择神经网络的结构 
后面的视频中 
我还会着重介绍 
怎样正确地选择隐藏层的个数 
以及隐藏单元的数目 等等

下面我们就来具体介绍 
如何实现神经网络的 
训练过程 
这里一共有六个步骤 
这页幻灯片中罗列了前四步 
剩下的两步 
放在下一张幻灯片中 
首先 第一步是构建一个 
神经网络 
然后随机初始化权值 
通常我们把权值 
初始化为很小的值 接近于零

然后我们执行前向传播算法 
也就是 对于该神经网络的 
任意一个输入x(i) 
计算出对应的h(x)值 
也就是一个输出值y的向量

接下来我们通过代码 
计算出代价函数J(θ)

然后我们执行 
反向传播算法

来算出这些偏导数 或偏微分项 
也就是 
J(θ)关于参数θ的偏微分 
具体来说 
我们要对所有训练集数据 
使用一个for循环进行遍历

可能有部分同学之前听说过 
一些比较先进的分解方法 
可能不需要像这里一样使用 
for循环来对所有 
m个训练样本进行遍历 
但是 这是你第一次进行反向传播算法 
所以我建议你最好还是 
使用一个for循环来完成程序 
对每一个训练样本进行迭代 
从x(1) y(1)开始 
我们对第一个样本进行 
前向传播运算和反向传播运算 
然后在第二次循环中 
同样地对第二个样本 
执行前向传播和反向传播算法 
以此类推 
直到最后一个样本 
因此 在你第一次做反向传播的时候 
你还是应该用这样的for循环 
来实现这个过程 
其实实际上 
有复杂的方法可以实现 
并不一定要使用for循环 
但我非常不推荐 
在第一次实现反向传播算法的时候 
使用更复杂更高级的方法

所以具体来讲 我们对所有的 
m个训练样本上使用了for循环遍历

在这个for循环里 
我们对每个样本执行 
前向和反向算法

具体来说就是 
我们把x(i) 
传到输入层 
然后执行前向传播和反向传播

这样我们就能得到 
该神经网络中 
每一层中每一个单元对应的 
所有这些激励值a(l) 
和delta项 
接下来 
还是在for循环中 
让我画一个大括号 
来标明这个 
for循环的范围

当然这些是octave的代码 
括号里是for循环的循环体 
我们要计算出这些delta值 
也就是用我们之前给出的公式

加上 delta(l+1)

a(l)的转置矩阵 
最后 外面的部分 
计算出的这些delta值 
这些累加项 
我们将用别的程序 
来计算出 
这些偏导数项 
那么这些偏导数项 
也应该考虑使用 
正则化项lambda值 
这些公式在前面的视频中已经给出

那么 搞定所有这些内容 
现在你就应该已经得到了 
计算这些偏导数项的程序了

下面就是第五步了 
我要做的就是使用梯度检查 
来比较这些 
已经计算得到的偏导数项 
把用反向传播算法 
得到的偏导数值 
与用数值方法得到的

估计值进行比较 
因此 通过进行梯度检查来 
确保两种方法得到基本接近的两个值

通过梯度检查我们能确保 
我们的反向传播算法 
得到的结果是正确的 
但必须要说明的一点是 
我们需要去掉梯度检查的代码 
因为梯度检查的计算非常慢

最后 我们就可以 
使用一个最优化算法 
比如说梯度下降算法 
或者说是更加高级的优化方法 
比如说BFGS算法 共轭梯度法 
或者其他一些已经内置到fminunc函数中的方法 
将所有这些优化方法 
和反向传播算法相结合 
这样我们就能计算出 
这些偏导数项的值

到现在 我们已经知道了 
如何去计算代价函数 
我们知道了如何使用 
反向传播算法来计算偏导数 
那么 我们就能使用某个最优化方法 
来最小化关于theta的函数值 
代价函数J(θ) 
另外顺便提一下 
对于神经网络 代价函数 
J(θ)是一个非凸函数 
就是说不是凸函数 
因此理论上是能够停留在 
局部最小值的位置 
实际上 梯度下降算法 
和其他一些高级优化方法 
理论上都能收敛于局部最小值

但一般来讲 
这个问题其实 
并不是什么要紧的事 
尽管我们不能保证 
这些优化算法一定会得到 
全局最优值 但通常来讲 
像梯度下降这类的算法 
在最小化代价函数 
J(θ)的过程中 
还是表现得很不错的 
通常能够得到一个很小的局部最小值 
尽管这可能不一定是全局最优值 
最后 梯度下降算法 
似乎对于神经网络来说还是比较神秘 
希望下面这幅图 
能让你对梯度下降法在神经网络中的应用 
产生一个更直观的理解

这实际上有点类似 
我们早先时候解释梯度下降时的思路 
我们有某个代价函数 
并且在我们的神经网络中 
有一系列参数值 
这里我只写下了两个参数值 
当然实际上 
在神经网络里 我们可以有很多的参数值 
theta1 theta2 等等 所有的这些都是矩阵 是吧 
因此我们参数的维度就会很高了 
由于绘图所限 我们不能绘出 
更高维度情况的图像 
所以这里我们假设 
这个神经网络中只有两个参数值 
实际上应该有更多参数

那么 代价函数J(θ) 
度量的就是这个神经网络 
对训练数据的拟合情况

所以 如果你取某个参数 
比如说这个 下面这点

在这个点上 J(θ) 
的值是非常小的 
这一点的位置所对应的 
参数theta的情况是 
对于大部分 
的训练集数据

我的假设函数的输出 
会非常接近于y(i) 
那么如果是这样的话 
那么我们的代价函数值就会很小

而反过来 如果我们 
取这个值 
也就是这个点对应的值 
那么对于大部分的训练集样本 
该神经网络的输出 
应该是远离 
y(i)的实际值的 
也就是我们在训练集观测到的输出值 
因此 像这样的点 
右边的这个点 
对应的假设就是 
神经网络的输出值 
在这个训练集上的测试值 
应该是远离y(i)的 
因此这一点对应着对训练集拟合得不好的情况 
而像这些点 
代价函数值很小的点 
对应的J(θ)值 
是很小的 因此对应的是 
神经网络对训练集数据 
拟合得比较好的情况 
我想表达的是 如果是这种情况的话 
那么J(θ)的值应该是比较小的

因此梯度下降算法的原理是 
我们从某个随机的 
初始点开始 比如这一点 
它将会不停的往下下降

那么反向传播算法 
的目的就是算出 
梯度下降的方向 
而梯度下降的过程 
就是沿着这个方向 
一点点的下降 一直到我们希望得到的点 
在这里我们希望找到的就是局部最优点

所以 当你在执行反向传播算法 
并且使用梯度下降 
或者 
更高级的优化方法时 
这幅图片很好地帮你解释了基本的原理 
也就是 试图找到某个最优的参数值 
这个值使得 
我们神经网络的输出值 
与y(i)的实际值 
也就是训练集的输出观测值 
尽可能的接近 
希望这节课的内容能让你对 
这些零散的神经网络知识 
如何有机地结合起来 
能有一个更直观的认识

但可能你即使看了这段视频 
你可能还是觉得 
有许多的细节 
不能完全明白 
为什么这么做 或者说是这些是如何 
联系在一起的 没关系

神经网络和反向传播算法本身就是非常复杂的算法

尽管我已经完全理解了 
反向传播算法背后的数学原理 
尽管我使用反向传播已经很多年了 
我认为 这么多年的使用还算是成功的 
但尽管如此 
到现在我还是觉得 
我自己也并不是总能 
很好地理解反向传播到底在做什么 
以及最优化过程是如何 
使J(θ)值达到最小值的 
因为这本身的确是一个很难的算法 
很难让你感觉到 
自己已经完全理解 
它不像线性回归 
或者逻辑回归那样

数学上和概念上都很简单 
反向传播算法不是那样的直观

如果你也有同感 
那么完全不必担心 
但如果你自己动手 
完成一次反向传播算法 
你一定会发现 
这的确是一个很强大的 
学习算法 如果你 
执行一下这个算法 执行反向传播 
执行其中的优化方法 
你一定会发现 
反向传播算法能够很好的 
让更复杂 维度更大的 非线性的 
函数模型跟你的数据很好地拟合 
因此它的确是一种 
最为高效的学习算法
 

Any programming problem can be solved by adding a level of indirection.

– David J. Wheeler

No Comments

Sorry, the comment form is closed at this time.