改进神经网络学习的方式
当一个高尔夫球员第一次学习打高尔夫的时候, 他们通常会把大部分的时间花费在练习基本的挥杆动作上。 慢慢地他们才基于基础的动作学习新的动作: 低飞球、左曲球和右曲球 。 与之类似, 到目前, 我们一直专注于理解反向传播算法。 这就是我们的 “基础挥杆动作”, 是学习神经网络的基础。 这一张, 我会解释一系列可以用于改善我们反向传播算法初级实现的技巧, 从而改善我们的神经网络学习的方式。
我们在本章将要学习的技巧包括: 一个更好的成本函数, 被称为 “交叉熵” 成本函数; 四个所谓的 “规范化” 方法 (L1, L2 规范化, 中途断离(dropout),训练数据的人工扩展 ), 这些方法使我们的神经网络可以更好地超越训练数据集而完成泛化的任务;一个更好的用于初始化神经网络权重的方法; 一系列可以帮助我们为神经网络选择好的超参数(hyper-parameter)的启发探索方法。 我也会对一些其他的技巧进行概览。这些内容之前基本都是相互独立的, 所以你可以跳跃式阅读。我们还会在代码中实现很多上述提到的技巧, 然后用他们来改进我们在第一章节获得的手写数字分类问题的结果。
当然, 目前我们仅仅覆盖了神经网络被发展出的众多技巧的一小部分。但这里想要传达的哲学性思想是, 对于所有的技巧的最好学习方式是深入的研究其中最重要的几个。 掌握了最重要的技巧的收益不仅仅在于那些技巧本身, 还会加深你对神经网络使用过程中其他可能出现问题的理解。 这可以让你在需要的时候, 很快地学会其他的技巧。
交叉熵成本函数
大部分人都不会喜欢做错的感觉。在我开始学习钢琴不久后, 我在一个观众前进行了第一次演出。 我当时很紧张, 然后把一个片段弹低了一整个八度 。我变得很困惑, 以致于无法继续弹奏, 直到有一个人指出了我的错误之处。 我非常尴尬。 但尽管很不开心, 当我们犯过明确的错误后, 我们也可以很快的从中学到很多。 你可以推断出, 我在下一次给观众演出时, 成功在正确的八度音节上完成了演奏。 与之恰恰相反的是, 如果我们的错误不太明确, 那么我们会学的很慢。
理想情况下, 我们希望我们的神经网络可以很快地从它的错误中进行学习。 但在实践中能如愿吗?为了回答这个问题, 让我们看一个玩具性质的例子。这个例子的神经元仅仅拥有一个输入:
我们会训练这个神经元做一些极度简单的事: 获取输入 1 , 然后输出 0 。 当然, 这是如此简单的一个任务, 以致于我们可以直接给出一个合适的权重和偏倚量。然而, 如果我们用梯度下降算法来试着学习出一个权重和偏倚量, 这个过程会很具有指导意义。 所以让我们看一下这个神经元是如何学习的。
为了使得过程明晰, 我将初始的权重选为 0.6 0.6 0.6 , 初始的偏倚量选为 0.9 0.9 0.9, 这些就是非常一般化的选择, 没有任何特殊的斟酌。 这个神经元接收 1 作为输入后, 初始输出是 0.82 0.82 0.82 , 所以这和我们的目标输出 0 0 0之间有很长一段距离需要学习。
下面可以通过一个网页端的动态实验(下面这个只是截图, 动态实验移步原站)来观看这个过程:
点击右下角的 “Run”按钮后可以看到神经元是如何逐渐学习, 使得输出接近于 0 。 注意: 这不是一个提前录制好的动画, 你的浏览器实际上是在动态计算梯度, 然后根据梯度来更新权重和偏倚量, 然后展示结果。 学习速率 η = 0.15 \eta =0.15 η=0.15, 这个速率恰好足够满,使得我们可以看清楚整个学习过程, 又足够快使得我们在几秒钟的时间完成大量的学习。 成本是通过我们在第一张所介绍的二次成本函数计算的。 我之后会帮你回想起这个成本函数的具体形式, 这里没有必要去深挖其定义。 注意, 你可以多次点击运行这个动画。
正如你所看到的, 神经元快速的学习了一个权重和偏移量使得成本函数值下降, 且最终输出了一约0.09的值。 这个不是我们期待的结果 0.0 0.0 0.0, 但是已经很不错了。 假设, 我们开始选用的初始权重和偏倚量分别为 2.0 和 0.98, 初始的输出是 0.98 , 这个结果离我们的预期输出更远了。 在这种情况下, 我们看看神经元是如何学习着输出 0 。 (下面依旧是图片, 移步原站进行实验)
尽管这个例子使用了相同的学习速率( η = 0.15 \eta=0.15 η=0.15), 我们可以看到学习进行的缓慢了许多。 事实上, 大约前150 个学习世代(epoch) 中, 权重和偏倚量都根本没怎么改变。
因笔者未能在工作中应用机器学习相关技能, 介于时间和精力问题,翻译至此中断,有兴趣的读者可以从其他渠道获取该教程的翻译内容