您的位置:首页 > 理论基础 > 计算机网络

Andrew NG 机器学习 笔记-week5-神经网络的学习(Neural Networks:Learning)

2017-09-30 09:18 375 查看

一、代价函数(Cost Function)

首先引入一些便于稍后讨论的新标记方法:

假设神经网络的训练样本有 m 个,每个包含一组输入 x 和一组输出信号 y

L =神经网络总层数

sl = l 层的神经元(neuron)个数(不包含偏置单元(bias unit))

sL = 最后一层中神经元的个数

K = 输出单元或类的数量

将神经网络的分类定义为两种情况:二类分类和多类分类:

二类分类:sL =1,y=0 or 1 表示是哪一类

k类分类:sL =k,yi=1表示分到了第 i 类(k>2)



我们回顾逻辑回归问题中的代价函数为:

J(θ)=−1m∑i=1m[y(i)log(hθ(x(i)))+(1−y(i))log(1−hθ(x(i)))]+λ2m∑j=1nθ2j

在逻辑回归中,我们只有一个输出变量,又称标量(scalar),也只有一个因变量 y,但是在神经网络中,我们可以有很多输出变量,我们的 hθ(x) 是一个维度为 K 的向量,并且我们训练集中的因变量也是同样维度的一个向量,因此我们的代价函数会比逻辑回归更加复杂一些,为:

J(Θ)=−1m∑i=1m∑k=1K[y(i)klog((hΘ(x(i)))k)+(1−y(i)k)log(1−(hΘ(x(i)))k)]+λ2m∑l=1L−1∑i=1sl∑j=1sl+1(Θ(l)j,i)2

这个看起来复杂很多的代价函数背后的思想还是一样的,我们希望通过代价函数来观察算法预测的结果与真实情况的误差有多大,唯一不同的是,对于每一行特征,我们都会给出K 个预测,基本上我们可以利用循环,对每一行特征都预测 K 个不同结果,然后在利用循环在 K 个预测中选择可能性最高的一个,将其与 y 中的实际数据进行比较。

归一化的那一项只是排除了每一层 θ0 后,每一层的 θ 矩阵的和。最里层的循环 j 循环所有的行(由 sl +1 层的激活单元数决定),循环 i 则循环所有的列,由该层( sl 层)的激活单元数所决定。即:hθ (x)与真实值之间的距离为每个样本-每个类输出的加和,对参数进行 regularization 的 bias 项处理所有参数的平方和。

二、反向传播算法(Backpropagation Algorithm)

目标:计算 minΘJ(Θ)

之前我们在计算神经网络预测结果的时候我们采用了一种正向传播方法,我们从第一层开始正向一层一层进行计算,直到最后一层的 hθ(x)

现在,为了计算代价函数的偏导数 ∂∂Θ(l)i,jJ(Θ) , 我们需要采用一种反向传播算法,也就是首先计算最后一层的误差,然后再一层一层反向求出各层的误差,直到倒数第二层。 以一个例子来说明反向传播算法。



反向传播算法:

一、给出训练数据集:{(x(1),y(1))⋯(x(m),y(m))}

二、对于所有的 (l,i,j) 设置 Δ(l)i,j=0,得到一个全为0的矩阵,成为误差矩阵

第 l 层的第 i 个激活单元受到第 j个参数影响而导致的误差。

三、对于所有训练样例,遍历 i 从 1 到 m :

1、设置 a(1):=x(i)

2、用 前向传播算法 来计算 a(l) , l=2,3,…,L



3、用 y(t) 计算 δ(L)=a(L)−y(t)

我们从最后一层的误差开始计算,误差是激活单元的预测 a(L) 与实际值 y(t) 之间的误差。

从右到左计算前面各层的误差。

4、使用:δ(l)=((Θ(l))Tδ(l+1)) .∗g′(z(l)) , 计算 δ(L−1),δ(L−2),…,δ(2)

其中,g′(z(l)) 是 S 型函数的导数,g′(z(l))= a(l) .∗ (1−a(l))

(Θ(l))Tδ(l+1)) 是权重导致的误差的和。

第一层是输入变量,不存在误差。

5、Δ(l)i,j:=Δ(l)i,j+a(l)jδ(l+1)i,或向量化:Δ(l):=Δ(l)+δ(l+1)(a(l))T

四、更新新的 Δ 矩阵:

D(l)i,j:=1m(Δ(l)i,j+λΘ(l)i,j),if j≠0.

D(l)i,j:=1mΔ(l)i,j

大写Δ矩阵D,作为累加器,来累加值,最后计算偏导数:∂∂Θ(l)ijJ(Θ)=D(l)ij

三、反向传播算法的直观理解(Backpropagation Intuition)

回顾 神经网络的代价函数是:

J(Θ)=−1m∑t=1m∑k=1K[y(t)k log(hΘ(x(t)))k+(1−y(t)k) log(1−hΘ(x(t))k)]+λ2m∑l=1L−1∑i=1sl∑j=1sl+1(Θ(l)j,i)2

如果我们考虑单一的非多分类(k=1),并且 不考虑正则化(λ=0),代价就计算为:

cost(t)=y(t) log(hΘ(x(t)))+(1−y(t)) log(1−hΘ(x(t)))

δ(l)j 是 a(l)j 的误差(l层的j单元)。更确切的说,δ 值实际上是代价函数的导数:

δ(l)j=∂∂z(l)jcost(t)

回忆,导数是代价函数切线的斜率,因此,斜率越陡,我们离正确越远。

考虑下面的神经网络,看我们如何计算 δ(l)j:



在上图中,为了计算 δ(2)2,我们用右侧的 δ 乘以各自的权重 Θ(2)12 和 Θ(2)22:得到:δ(2)2=Θ(2)12δ(3)1+Θ(2)22δ(3)2

为了计算每一个 δ(l)j,我们需要从图的右边开始计算,将 Θij 作为边

四、实现注意:展开参数(Implementation Note:Unrolling Parameters )

在上一段视频中,我们谈到了怎样使用反向传播算法计算代价函数的导数。在这段视频中,我想快速地向你介绍一个细节的实现过程,怎样把你的参数从矩阵展开成向量,以便我们在高级最优化步骤中的使用需要。

当使用matlab中的高级优化函数计算代价函数的最小值时theta是取值时,代价函数传入的 theta 值是一个 向量,返回的导数 gradient 也是一个向量

但是在神经网络中,我们的参数theta1,theta2,theta3,以及通过反向传播算法计算的导数值 D1,D2,D3,将不再是向量,而是矩阵,我们将学习如何将这些矩阵展开成向量,以适用高级优化函数。



假设我们有这样一个神经网络,输入层有10个单元,隐藏层有10个单元,输出层有1个单元

Θ(1)是一个10*11 的矩阵…D(1)是一个10*11 的矩阵…

可以使用下面的公式,将他们组成和一个长向量

如果想还原成矩阵,可以使用reshape()抽取各自的元素,还原成矩阵



下面看如何将这种方法应用到我们的学习算法中:

我们有初始参数Θ(1),Θ(2),Θ(3)

将他们展开成向量得到 initialTheta 传递给 fminunc(@costFunction,initialTheta,options)

另一件事是实现代价函数 costFunction:

costFunction 传入的参数也是将所有参数展开成的向量 thetaVec

从 thetaVec 中使用 reshape 函数还原得到 矩阵 Θ(1),Θ(2),Θ(3)。

使用 前向传播算法和后向传播算法 计算 D(1),D(2),D(3) 和 J(θ)。

将D(1),D(2),D(3)矩阵展开成向量,得到 gradientVec



五、梯度检测(Gradient Checking)

当我们对一个较为复杂的模型(例如神经网络)使用梯度下降算法时,可能会存在一些不容易察觉的错误,意味着,虽然代价看上去在不断减小,但最终的结果可能并不是最优解。

为了避免这样的问题,我们采取一种叫做数值梯度检验(Numerical Gradient Checking)方法。这种方法的思想是通过估计梯度值来检验我们计算的导数值是否真的是我们要求的。

对梯度的估计采用的方法是在代价函数上沿着切线的方向选择两个非常近的点然后计算两个点的平均值用以估计梯度。即对于某个特定的 θ,我们计算出在 θ-ε 处和 θ+ε 的代价值(ε 是一个非常小的值,通常选取 0.0001),然后求两个代价的平均,用以估计在 θ 处的代价值。



∂∂ΘJ(Θ)≈J(Θ+ϵ)−J(Θ−ϵ)2ϵ

当 θ 展开为一个向量时,我们则需要对偏导数进行检验。因为代价函数的偏导数检验只针对一个参数的改变进行检验,下面是一个只针对 θj 进行检验的示例:

∂∂ΘjJ(Θ)≈J(Θ1,…,Θj+ϵ,…,Θn)−J(Θ1,…,Θj−ϵ,…,Θn)2ϵ

j 为从1 到 n

对 Θj 矩阵 进行这样的处理。在 matlab中我们可以这样做:

epsilon = 1e-4;
for i = 1:n,
thetaPlus = theta;
thetaPlus(i) += epsilon;
thetaMinus = theta;
thetaMinus(i) -= epsilon;
gradApprox(i) = (J(thetaPlus) - J(thetaMinus))/(2*epsilon)
end;


之前我们学习了如何计算 deltaVector , 因此我们就可以比较此处得到的 gradApprox 是否约等于 deltaVector 。

总结:



六、随机初始化(Random Initialization)

任何优化算法都需要一些初始的参数。到目前为止我们都是初始所有参数为 0,这样的初始方法对于逻辑回归来说是可行的,但是对于神经网络来说是不可行的。如果我们令所有的初始参数都为 0(或其他相同的数),这将意味着我们第二层的所有激活单元都会有相同的值。

因此,我们初始化每一个 Θ(l)ij 为 [−ϵ,ϵ] 之间的一个随机值,此处的 ϵ 与 梯度检测中的 ϵ 无关。



If the dimensions of Theta1 is 10x11, Theta2 is 10x11 and Theta3 is 1x11.

Theta1 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
Theta2 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
Theta3 = rand(1,11) * (2 * INIT_EPSILON) - INIT_EPSILON;


rand(x,y) 是matlab中的一个方法,随机产生一个值为 0到1 之间的 x*y 维的矩阵。

七、综合起来(Putting it Together)

小结一下使用神经网络时的步骤:

网络结构:第一件要做的事是选择网络结构,即决定选择多少层以及决定每层分别有多少个单元。

第一层的单元数即我们训练集的特征数量。

最后一层的单元数是我们训练集的结果的类的数量。

如果隐藏层数大于1,确保每个隐藏层的单元个数相同,通常情况下隐藏层单元的个数越多越好。

我们真正要决定的是隐藏层的层数和每个中间层的单元数。

训练神经网络:

1、参数的随机初始化

2、利用正向传播算法计算所有的 hθ(x)

3、编写计算代价函数 J 的代码

4、利用反向传播算法计算所有偏导数

5、利用梯度检测方法检测这些偏导数

关闭梯度检测代码

6、使用优化算法来最小化代价函数

下图给我们了一个直观的感受,当我们在实现神经网络时发生了什么:



我们希望最终 hΘ(x(i))≈y(i),即代价函数最小值点。但是记住,J(θ)函数是非凸的(not convex),所以我们很有可能最后落在了局部最小值点。

八、自主驾驶(Autonomous Driving)

使用神经网络来实现自动驾驶,也就是说使汽车通过学习来自己驾驶。

在看这段视频之前,我会告诉你可视化技术是什么。



在左下方,就是汽车所看到的前方的路况图像。

左上方,一条水平的菜单栏显示的是驾驶操作人选择的方向。就是这里的这条白亮的区段显示的就是人类驾驶者选择的方向。比如:最左边的区段,对应的操作就是向左急转,而最右端则对应向右急转的操作。因此,稍微靠左的区段,也就是中心稍微向左一点的位置,则表示在这一点上人类驾驶者的操作是慢慢的向左拐。

第二部分对应的就是学习算法选出的行驶方向。

在神经网络开始学习之前,你会看到网络的输出是一条均称的灰色区域,显示出神经网络已经随机初始化了。只有在学习算法运行了足够长的时间之后,才会有这条白色的区段出现在整条灰色区域之中。显示出一个具体的行驶方向这就表示神经网络算法,在这时候已经选出了一个明确的行驶方向。

ALVINN (Autonomous Land Vehicle In a Neural Network)是一个基于神经网络的智能系统,通过观察人类的驾驶来学习驾驶,这辆悍马装载了传感器、计算机和驱动器用来进行自动驾驶的导航试验。

ALVINN 每两秒将前方的路况图生成一张数字化图片,并且记录驾驶者的驾驶方向,得到的训练集图片被压缩为 30x32 像素,并且作为输入提供给 ALVINN 的三层神经网络,通过使用反向传播学习算法,ALVINN 会训练得到一个与人类驾驶员操纵方向基本相近的结果。

大约经过两分钟的训练后,我们的神经网络便能够准确地模拟人类驾驶者的驾驶方向,对其他道路类型,也重复进行这个训练过程。

当网络被训练完成后,操作者就可按下运行按钮,车辆便开始行驶了。

每秒钟 ALVINN 生成 12 次数字化图片,并且将图像传送给神经网络进行训练,多个神经网络同时工作,每一个网络都生成一个行驶方向,以及一个预测自信度的参数,预测自信度最高的那个神经网络得到的行驶方向。比如这里,在这条单行道上训练出的网络将被最终用于控制车辆方向,车辆前方突然出现了一个交叉十字路口,当车辆到达这个十字路口时,我们单行道网络对应的自信度骤减,当它穿过这个十字路口时,前方的双车道将进入其视线,双车道网络的自信度便开始上升,当它的自信度上升时 双车道的网络,将被选择来控制行驶方向,车辆将被安全地引导进入双车道路。

使用这样一个简单的基于反向传播的神经网络,训练出如此强大的自动驾驶汽车,的确是一次令人惊讶的成就。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐