在上周小 Mi 给大家的介绍中,咱们谈到了怎么应用反向流传算法计算代价函数的导数。明天,小 Mi 将持续带大家理解神经网络的实现过程,废话不多说,赶快跟小 Mi 一起学起来吧~
4 实现留神:开展参数
首先,有一个细节的实现过程值得关注一下,就是如何把参数从矩阵开展成向量,以便咱们在高级最优化步骤中应用。
具体来说,小 Mi 执行了代价函数,输出的参数是 theta,函数返回代价值以及导数值,而后就能够将返回值传递给高级最优化算法 fminunc,顺便须要说一下的是,fminunc 并不是惟一的算法,当然也能够应用别的优化算法,但它们的性能都属取出这些输出值,比方 @costFunction 以及 theta 值的一些初始值,并且这些程序都假设 theta 和这些 theta 初始值都是参数向量(兴许是 n 维或者 n + 1 维),但它们都是向量。同时假设代价函数第二个返回值,也就是梯度值也是 n 维或者 n + 1 维,所以这也是一个向量,这部分在逻辑回归的应用过程中是没有任何问题的,但当初咱们用神经网络时,咱们的参数不再是向量了,而是矩阵。因而对于一个残缺的神经网络,咱们的参数矩阵为,代码编写过程中能够设为 matrices(Theta1,Theta2,Theta3),同样地,这些梯度项也是须要失去的返回值,之前小 Mi 也带大家学习了如何计算这些梯度矩阵,别离是,程序中能够间接编写为 matrices(D1,D2,D3)。那么如何取出这些矩阵并且将它们开展以便最终成为失当的格局,从而能够传入上述的 Theta 中并失去梯度返回值呢?
更进一步来说,假如咱们有一个这样的神经网络,其输出层有 10 个输出单元,暗藏层也有 10 个单元,最初的输入层只有一个输入单元,因而等于第一层的单元数,等于第二层的单元数,等于第三层的单元个数。在这种状况下,矩阵和矩阵 D 的维度(实际上这里多进去一个和 D 矩阵)将由表达式决定。比如说,是一个 10*11 的矩阵,以此类推,如果你想在矩阵和向量之间来回转化,那么须要做的就是取出 Theta1,Theta2,Theta3,而后应用上面局部的代码,从而取出三个矩阵中的所有元素,而后把它们全副开展称为一个很长的向量,也就是 thetaVec;同样地,下图中的第二句代码将取出 D 矩阵中的所有元素,而后开展成一个长向量,叫做 DVec。
最初的话,如果想从向量表白返回到矩阵表达式的话,比方要想得到 Theta1,那么取 thetaVec,抽出前 110 个元素,Theta1 就有 110 个元素,因为它是一个 10*11 的矩阵,所以抽出前 110 个元素,而后你就能应用命令 reshape 来扭转矩阵大小失去 Theta1,同样,要重新得到 Theta2,就须要抽出下一组 110 个元素并且重新组合,而后对于 Theta3,也须要抽出最初 110 个元素,而后执行 reshape 命令失去 Theta3。
构建三个独立的矩阵 Theta1,Theta2,Theta3,最初把所有这些矩阵变成一个向量,当初 thetaVec 就变成了一个很长的向量,含有 231 个元素,包含三个矩阵的所有元素。
那如果想重新得到原来的矩阵,能够对 thetaVec 应用 reshape 命令,抽出前 110 个元素,并将它们重组为一个 10*11 的矩阵,这样咱们又再次失去了 Theta1 的矩阵,同理,获取 Theta2,Theta3 也是如此。
为了使这个过程更具体,咱们能够看下如何将这一办法利用于学习算法中。假如咱们有一些初始参数值,。咱们要做的是取这些参数,而后将它们开展为一个长向量,能够称之为初始的 Theta 值。而后作为 Theta 参数的初始设置传入优化函数 fminunc,而要做的另一件事就是实现代价函数。代价函数的实现算法如下:
代价函数会失去输出函数 thetaVec,其蕴含了所有的参数向量,所有的参数都开展成一个向量的模式。因而咱们要做的第一件事是应用 thetaVec 和重组函数 reshape,抽出 thetaVec 中的元素,而后重组以失去我的初始参数矩阵,这些就是咱们须要失去的矩阵,这样就有了一个应用这些矩阵的更为不便的模式,从而执行前向流传和反向流传来计算出导数以及代价函数。最初的话,能够取出这些导数值而后开展它们,让它们放弃和开展的值同样的程序,开展 D1,D2,D3 来失去 gradientVec,这个值又可由代价函数返回,以一个向量的模式返回这些导数值。
当初大家是不是对参数的矩阵表达式与向量表达式之间的来回转换有了一个更清晰的意识呢?应用矩阵表达式的益处就是,当你的参数以矩阵的模式存储的话,进行正向流传和反向流传时会更加便捷;而将参数存储为矩阵时,也会更容易充分利用向量化实现。还有一点须要留神的是,假如遇到 thetaVec 或者 DVec 这样的矩阵时,应用一些高级的优化算法,而这些算法会通常要求把所有的参数都开展成一个长向量的模式,心愿通过本节的学习大家能够更加灵便地在两种模式之间来回切换~
5 梯度测验
之前咱们曾经探讨过如何在神经网路中应用前向流传和反向流传来计算导数,然而反向流传算法含有很多细节,因而实现起来比拟艰难,同时它还有一个不好的个性,当咱们对一个较为简单的模型(例如神经网络)应用梯度降落算法时,可能会存在一些不容易觉察的谬误,看起来它的确能失常运行,并且代价函数在每次梯度降落的迭代过程中也在一直减小,只管运行状况看起来的确不错,但最终的后果其误差可能会比无 bug 的状况下高出一个量级,并且你很可能不晓得你失去的后果是由 bug 导致的。那么面对这种状况,咱们应该如何解决呢?
为了防止这样的问题,咱们采取一种叫做梯度的数值测验(Numerical Gradient Checking)办法,它能解决简直所有这种问题。如果在神经网络或者其余算法中实现反向流传或者相似梯度降落算法时,能够都进行一下梯度测验,从而能够齐全保障前向流传以及后向流传都是百分之百正确的。而这种问题之所以会呈现,是因为绝大多数都和反向流传的谬误实现无关。之前咱们提到的对于的计算公式,以及对于 d 的,等等,这些的确都能够计算出代价函数的梯度。而当咱们去实现梯度测验的时候,能够本人去验证本人的代码是否可能正确计算出代价函数的导数。
当初小 Mi 就带大家具体来说明一下梯度测验啦~ 大家能够看一下下面的图例,假如有一个代价函数,有一个值(在这里假如是实数),如果咱们想预计函数在这一点上的导数,那么该点的导数就是图像在该点切线的斜率。当初咱们要从数值上来迫近它的导数,或者说这是一种从数值上来求近似导数的办法。首先计算出,在的左边一点点,而后再计算出,也就是在的右边一点点,当初要做的就是把这两个值对应的点用直线连起来,而后所得红线的斜率(即蓝色切线的斜率)就是所求该点导数的近似值,数学上来讲的话,该斜率等于该段的垂直高度除以该段的程度宽度,即(是一个很小的值)。实际上只有足够小,该点真正的导数就成了函数在这一点上实在的斜率。当然,须要留神的是,过分小的值会引发很多数值问题,所以通常会给取左右的值。可能当前咱们还会遇到单侧差分这样的式子,而咱们计算的是双侧差分。
能够执行以下代码实现,计算出 gradApprox(该点导数的近似值):
gradApprox = (J(theta + eps) – J(theta – eps)) / (2*eps)
上述小 Mi 的所有解说都是针对是实数而言,更广泛的状况也就是当为向量参数的时候,假如是一个 n 维向量(可能是神经网络中参数的展开式),同理,所有的偏导数项的近似值也能够间接求出,比方代价函数对于第一个参数的偏导数,对于第二个参数的偏导数等等。
代码实现:
对神经网络中代价函数所有参数的偏导数的计算,而后与咱们在反向流传中失去的梯度进行比拟,DVec 是从反向流传中失去的导数,而反向流传是计算代价函数对于所有参数的导数或者偏导数的一种无效办法,接下来要做的就是验证计算出的导数 gradApprox 是否靠近于用反向流传所计算出的导数 DVec,如果两者十分靠近,只有几位小数的差距,那么就能够阐明反向流传的实现是正确的。从而向量 DVec 用于梯度降落或者其余高级优化算法中时,就能够确信计算的导数是正确的,那么代码也会失常运行,并能够很好地优化。
总结下,如何实现数值上梯度测验的步骤:
1. 通过反向流传来计算 DVec(DVec 可能是矩阵开展的模式);
2. 实现数值上的梯度测验,计算出 gradApprox
3. 确认 DVec 和 gradApprox 是否类似,只有几位小数的差距。
4. 在训练网络之前,敞开梯度测验,不要再去用导数计算公式来计算 gradApprox 了(因为梯度测验计算量十分大的,速度比较慢),绝对地,反向流传算法是一个高性能的计算方法,一旦咱们通过测验确定反向流传的实现是正确的,就应该关掉梯度测验,不要再去应用了。
6 随机初始化
后面小 Mi 的介绍曾经包含了神经网络中所有须要实现和训练的内容,不过随机初始化的思维也是须要学习的。当咱们执行一个算法,比方梯度降落法或者高级优化算法时,咱们须要为变量选取一些初始值。对于高级优化算法,它会默认你会为变量提供一些初始值。对于梯度降落算法,同样咱们也须要对进行初始化。初始化结束之后,就能够一步一步通过梯度降落来最小化代价函数 J。那么又应该如何对设置初始值呢?有一种想法是将的初始值全副设为 0,这样的初始办法对于逻辑回归来说是可行的,但实际上在训练网络时将所有的初始值都设为 0 起不到任何作用。
以这个神经网络的训练为例,假如咱们将所有的参数都初始化为 0,这样的话就意味着暗藏单元和都是以同一输出函数来计算的。而对于神经网络中的所有训练样本最初总能失去,即便梯度降落进行了迭代,但暗藏单元仍然以雷同的函数输出,计算雷同的特色,这是一种高度冗余的景象,最终只会失去一个特色,这就阻止了神经网络去学习别的更多的货色。
为了解决这个问题,对参数进行初始化时,要采纳随机初始化的思维,具体来说,随机初始化就是解决对称权重的问题(所有的权重都一样)。咱们将其初始化为一个范畴在的随机值。(和之前梯度测验中的没有任何关系)
代码实现:
因而,为了训练神经网络,应该首先将权重随机初始化为一个靠近 0 的数,而后进行反向流传,再进行梯度测验,最初应用梯度降落或其余高级优化算法来最小化代价函数 J。
7 总结
在训练一个网络的时候,咱们要做的第一件事就是要抉择一种网络架构(神经元之间的连贯模式):比方上图中第一种蕴含三个输出单元,五个暗藏单元和四个输入单元,第二种则是三个输出单元,两组五个暗藏单元,四个输入单元等等。也就是说咱们须要决定抉择多少层以及决定每层别离有多少个单元。
那么这个时候又该如何抉择呢?
第一层的单元数即咱们训练集的特色数量。
最初一层的单元数是咱们训练集的后果的类的数量。
如果暗藏层数大于 1,确保每个暗藏层的单元个数雷同,通常状况下暗藏层单元的个数越多越好。
因而,咱们真正要决定的是暗藏层的层数和每个暗藏层的单元数,而每个暗藏层所蕴含的单元数量须要与输出 x 的维度特色相匹配,暗藏单元的数目能够和输出特色数目雷同,或者是其二倍、三倍等等。
好了,这下小 Mi 终于能够总结下啦~ 训练神经网络实现步骤:
1. 构建神经网络,而后随机初始化权重
2. 执行前向流传算法计算所有的,也就是输入向量
3. 通过代码计算代价函数
4. 利用反向流传算法计算所有偏导数
5. 利用梯度测验办法测验这些偏导数
6. 应用优化算法来最小化代价函数
8 实例:自主驾驶
其实在咱们生存中,神经网络能使用到的很常见的一个场景就是主动驾驶。在主动驾驶零碎中,车辆会通过摄像头和传感器一直收集周围环境的数据,并领导车辆实现相应动作。车辆的传感器次要实现探测四周物体地位及预测其静止趋势的工作,摄像头则实现对四周物体进行辨认以及对交通标志进行分类的工作。摄像头在对图像分类过程中应用的算法是机器学习中的神经网络算法。
小 Mi 带大家看看 Dean Pomerleau 基于神经网络实现的自主驾驶是什么样儿的。
在下图的左下方是汽车所看到的后方的路况图像。
在图中咱们依稀能看出一条路线,朝左延长了一点,又向右了一点。还能够看到一条程度的菜单栏显示的是驾驶操作人抉择的方向。就是这里的这条白亮的区段显示的就是人类驾驶者抉择的方向。比方:最右边的区段,对应的操作就是向左急转,而最右端则对应向右急转的操作。因而,略微靠左的区段,也就是核心略微向左一点的地位,则示意在这一点上人类驾驶者的操作是缓缓的向左拐。
这幅图的第二局部对应的就是学习算法选出的行驶方向。并且,相似的,这一条白亮的区段显示的就是神经网络在这里抉择的行驶方向,是略微的左转,并且实际上在神经网络开始学习之前,你会看到网络的输入是一条灰色的区段,就像这样的一条灰 段笼罩着整个区域这些均称的灰 域,显示出神经网络曾经随机初始化了,并且初始化时,咱们并不知道汽车如何行驶,或者说咱们并不知道所选行驶方向。只有在学习算法运行了足够长的工夫之后,才会有这条红色的区段呈现在整条灰 域之中。显示出一个具体的行驶方向这就示意神经网络算法,在这时候曾经选出了一个明确的行驶方向,不像刚开始的时候,输入一段含糊的浅灰 域,而是输入一条白亮的区段,示意曾经选出了明确的行驶方向。
ALVINN (Autonomous Land Vehicle In a Neural Network)是一个基于神经网络的智能零碎,通过观察人类的驾驶来学习驾驶,ALVINN 可能管制 NavLab,装在一辆改装版军用悍马,这辆悍马装载了传感器、计算机和驱动器用来进行主动驾驶的导航试验。实现 ALVINN 性能的第一步,是对它进行训练,也就是训练一个人驾驶汽车。
而后让 ALVINN 观看,ALVINN 每两秒将后方的路况图生成一张数字化图片,并且记录驾驶者的驾驶方向,失去的训练集图片被压缩为 30×32 像素,并且作为输出提供给 ALVINN 的三层神经网络,通过应用反向流传学习算法,ALVINN 会训练失去一个与人类驾驶员操纵方向根本相近的后果。一开始,咱们的网络抉择出的方向是随机的,大概通过两分钟的训练后,咱们的神经网络便可能精确地模仿人类驾驶者的驾驶方向,对其余路线类型,也反复进行这个训练过程,当网络被训练实现后,操作者就可按下运行按钮,车辆便开始行驶了。
每秒钟 ALVINN 生成 12 次数字化图片,并且将图像传送给神经网络进行训练,多个神经网络同时工作,每一个网络都生成一个行驶方向,以及一个预测自信度的参数,预测自信度最高的那个神经网络失去的行驶方向。比方这里,在这条单行道上训练出的网络将被最终用于管制车辆方向,车辆后方忽然呈现了一个穿插十字路口,当车辆达到这个十字路口时,咱们单行道网络对应的自信度骤减,当它穿过这个十字路口时,后方的双车道将进入其眼帘,双车道网络的自信度便开始回升,当它的自信度上升时,双车道的网络,将被抉择来管制行驶方向,车辆将被平安地疏导进入双车路线。
这就是基于神经网络的主动驾驶技术。当然,咱们还有很多更加先进的试验来实现主动驾驶技术。但很多人都认为,应用这样一个简略的基于反向流传的神经网络,训练出如此弱小的主动驾驶汽车,确实是十分值得称赞的(小 Mi 也竖起了大拇指)。
好啦,对于神经网络的具体介绍就先到这里啦,下周小 Mi 给大家解说如何利用机器学习。咱们,下期再见呦~(挥手十分钟)