既然我们已经为我们的神经网络设计了一个模型,它怎么能学会识别数字呢?我们需要的第一件事就是从所谓的训练数据集中学到的数据集,我们将使用MNIST的数据集,它包含数以万计的手写数字的扫描图像,以及它们正确的分类。NIST的名字来源于一个事实,那就是它是由美国国家标准与技术研究所收集的两个数据集的一个修改子集。以下是一些来自MNIST的图片:
正如你所看到的,这些数字实际上和第一章开头所显示的是一样的,是一种需要识别的挑战。当然,在测试我们的网络时,我们会要求它识别不在训练集里的图像!
MNIST的数据分为两部分。第一部分包含6万张图片作为训练数据。这些图片是来自250人的扫描笔迹样本,其中一半是美国人口普查局的雇员,其中一半是高中生。这些图像是灰度级的,28x28像素。MNIST数据集的第二部分是作为测试数据使用的10000张图像。再一次,这些是28x28的灰度图像。我们将使用测试数据来评估我们的神经网络是如何学会识别数字的。为了使这成为一个良好的性能测试,测试数据来自于不同的250人,而不是最初的培训数据(尽管仍然是人口普查局雇员和高中生之间的一个群体)。这有助于让我们相信,我们的系统能够识别那些在训练中没有看到的人的数字。
我们将使用符号x来表示训练输入。将每个训练输入 x x 作为28x28=784维矢量的一个维度向量。矢量中的每一个元素代表图像中单个像素的灰色值。我们将用 y=y(x) y = y ( x ) 表示相应的期望输出,其中 y y 是 10 10 维向量。例如,如果一个特定的训练图像x,描绘的是 6 6 , y(x)=(0,0,0,0,0,0,1,0,0,0)T y ( x ) = ( 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 ) T 是来自神经网络的期望输出值。请注意, T T 是转置操作,将行向量变成普通(列)向量。
我们想要的是一种算法,它可以让我们找到权重和偏差,这样网络的输出就可以近似于 y(x) y ( x ) ,所有的训练输入都是 x x 。为了量化我们实现这个目标的程度,我们定义了一个成本函数,有时被称为损失或目标函数。我们在这本书中使用了术语成本函数,但是你应该注意其他的术语,因为它经常被用于研究论文和其他关于神经网络的讨论。
在这里, w w 表示网络中所有权重的集合, b b 表示所有的偏差, n n 是培训输入的总数, a a 是当 x x 输入时来自网络的输出的矢量,而总和超过了所有的训练输入 x x 。当然,输出 a a 依赖于 x x 、 w w 和 b b ,但是为了保持符号的简单,我没有明确指出这种依赖。符号 v v 表示向量v的一般长度函数。我们把它叫做二次成本函数;它有时也被称为平均平方误差或者是MSE。检查二次成本函数的形式,我们看到 C(w,b) C ( w , b ) 是非负的,因为和式中的每一项都是非负的。此外, C(w,b) C ( w , b ) 的成本也变得很小。 C(w,b)0 C ( w , b ) 0 正好当 y(x) y ( x ) 近似等于输出 a a ,对于所有的训练输入 x x 。所以我们的训练算法做得很好如果它能找到重量和偏差那么 C(w,b)0 C ( w , b ) 0 。相比之下,当 C(w,b) C ( w , b ) 很大时,它做得不太好,这意味着 y(x) y ( x ) 对于大量输入来说并不接近于输出 a a 。因此,我们的训练算法的目的是将成本 C(w,b) C ( w , b ) 作为权重和偏差的函数最小化。换句话说,我们想要找到一组权重和偏差,使成本尽可能小。我们会用一种叫做梯度下降的算法来做这个。
为什么要引入二次成本?毕竟,我们不是主要对网络正确分类的图像数量感兴趣吗?为什么不试着直接最大化这个数字,而不是最小化像二次成本这样的代理度量呢?这样做的问题是,正确分类的图像数量并不是网络中权重和偏差的平滑函数。在大多数情况下,对权重和偏差进行小的改动不会对正确分类的训练图像的数量造成任何改变。这就使得我们很难弄清楚如何改变权重和偏差以获得更好的性能。如果我们用一个平滑的成本函数,比如二次成本,结果很容易就能知道如何在权重和偏差上做出微小的改变,从而提高成本。这就是为什么我们首先关注最小化二次成本的原因,只有在那之后我们才会检查分类的准确性。
即使考虑到我们想要使用平滑的成本函数,您可能仍然想知道为什么我们选择在等式中使用的二次函数,这不是一个特别的选择吗?也许如果我们选择了一个不同的成本函数我们会得到一个完全不同的最小化权重和偏差的集合?这是一个有效的问题,稍后我们将重新讨论成本函数,并进行一些修改。然而,方程的二次成本函数对于理解神经网络中学习的基础非常有效,所以我们现在就坚持下去。
重新定位,我们在训练神经网络的目标是找到重量和偏差,使二次成本函数 C(w,b)最小化 C ( w , b ) 最 小 化 。这是一个很好的问题,但是它有很多令人分心的结构——对w和b的解释是权重和偏差,在后台隐藏的功能,网络架构的选择,MNIST,等等。事实证明,我们可以通过忽略大部分的结构来理解大量的内容,而只关注最小化方面。所以现在我们要忘掉成本函数的具体形式,和神经网络的连接,等等。相反,我们将想象我们得到了一个很多变量的函数我们想要最小化这个函数。我们将开发一种叫做梯度下降的技术,它可以用来解决这样的最小化问题。然后我们会回到我们想要最小化神经网络的特定函数。
那么,我们假设要最小化一些函数 C(v) C ( v ) ,这可以是很多变量的实值函数, v=v1,v2 v = v 1 , v 2 ……注意,我已经用 v v 替换了 w w 和 b b 符号来强调这可能是任何函数—我们在神经网络的上下文中没有特别的思考。为了最小化 C(v) C ( v ) ,它有助于把 C C 想象成两个变量的函数,我们称之为 v1 v 1 和 v2 v 2 :
我们想要找到 C C 实现其最小值的地方。现在,当然,对于上面的函数,我们可以观察这个图并找到最小值。从这个意义上说,我可能已经展示了一个过于简单的函数!一个通用的函数 C C ,可能是许多变量的复杂函数,通常不可能只看图来找到最小值。
解决这个问题的一种方法是用微积分来找出最小的分析方法。我们可以计算导数,然后试着用它们来找到 C C 是极值点的地方。如果 C C 只是一个或几个变量的函数,那么幸运的话就会起作用。但当我们有更多的变量时,它就会变成一场噩梦。对于神经网络,我们通常需要更多的变量—最大的神经网络的成本函数依赖于数十亿的权重和偏差,这是一种极其复杂的方式。用微积分来最小化这是行不通的!
(在断言我们将通过想象 C C 作为两个变量的函数来获得洞察力之后,我在两段中翻了两遍,然后说,“嘿,但是如果它是一个多于两个变量的函数呢?”很抱歉。请相信我,当我说它确实有助于把C想象成两个变量的函数。只是有时候这张照片会坏掉,最后两段是在处理这样的故障。对数学的思考通常需要同时处理多个直观的图片,学习什么时候适合使用每一张图片,什么时候不合适。)
好了,微积分是行不通的。幸运的是,有一个很好的类比,它提出了一种非常有效的算法。我们首先把我们的功能想象成一个山谷。如果你稍微斜视一下上面的情节,那就不应该太难了。我们想象一个球滚落在山谷的斜坡上。我们每天的经验告诉我们,球最终会滚到山谷的底部。也许我们可以用这个想法来找到这个函数的最小值?我们会随机选择一个(假想的)球的起始点,然后模拟球滚到谷底时的运动。我们可以简单地通过计算C的导数(或许还有一些二阶导数)来做这个模拟,这些导数会告诉我们关于山谷的局部“形状”的一切,以及我们的球应该如何滚动。
根据我刚刚写的,你可能会认为我们会尝试写下牛顿的运动方程,考虑到摩擦和重力的影响,等等。实际上,我们不会很严肃地对待这个球滚动的类比——我们正在设计一种算法来最小化C,而不是对物理定律进行精确的模拟!球的视角是为了刺激我们的想象力,而不是限制我们的思维。因此而不是进入所有混乱的物理细节,让我们简单地问自己:如果我们被宣布上帝一天,并可能构成自己的物理定律,决定如何滚球,什么法律或运动定律我们可以选择,让球总是滚山谷的底部?
为了让这个问题更精确,让我们想想当我们把球移动到 v1 v 1 方向上的一个小的 v1 v 1 ,以及 v2 v 2 方向上的一个小的 v2 v 2 时,会发生什么。微积分告诉我们 C C 的变化如下:
我们将会找到一种方法来选择 Δv1 Δ v 1 和 Δv2 Δ v 2 ,以便使 c c 为负;即,我们会选择它们,这样球就会滚落到山谷里。为了弄清楚如何做出这样的选择而定义 Δv Δ v , Δv≡(Δv1,Δv2)T Δ v ≡ ( Δ v 1 , Δ v 2 ) T 的变化向量,T又是转置运算,把行向量变成列向量。我们还将定义C的梯度为偏导数的向量 (∂C/∂v1,∂C/∂v2)T ( ∂ C / ∂ v 1 , ∂ C / ∂ v 2 ) T 。我们用C表示梯度向量,也就是:
这个方程有助于解释为什么 ∇C ∇ C 被称为梯度向量: ∇C ∇ C 将 Δv Δ v 中的变化与 ∇C ∇ C 中的变化联系起来,就像我们期望的梯度一样。但是这个方程真正令人兴奋的是它让我们看到如何选择 Δv Δ v 使 ΔC Δ C 为负。特别是,假设我们选择
η η 是一个小的,正的参数(称为学习速率)
然后我们将再次使用这个更新规则,来做另一个动作。如果我们一直这样做下去,我们会一直减少 C C 直到-我们希望-我们达到一个全球最小值。总而言之,梯度下降算法的工作方式是反复计算梯度 ∇C ∇ C ,然后向相反的方向移动,“下降”谷的斜率。我们可以把它想象成这样:
注意,有了这个规则,梯度下降并不能重现真实的物理运动。在现实生活中,一个球有动量,这个动量可以让它滚过斜坡,或者甚至(瞬间)滚上坡。只有在摩擦产生的影响之后,球才会被保证滚落到山谷中。相比之下,我们选择 Δv Δ v 的规则只是说“现在就去吧”。这仍然是找到最小值的一个很好的规则!
为了使梯度下降工作正确,我们需要选择学习速率足够小, ΔC≈∇C⋅Δv Δ C ≈ ∇ C ⋅ Δ v 是一个很好的近似。如果我们不这样做,我们最终可能会得到 ΔC>0 Δ C > 0 ,这显然是不好的!与此同时,我们不想太小,因为这会使 Δv Δ v 的变化很小,因此梯度下降算法将会非常缓慢地工作。在实际的实现中,常常是不同的,所以这个等式仍然是一个很好的近似,但是这个算法不是太慢了。我们稍后会看到它是如何工作的。
当 C C 是两个变量的函数时,我已经解释了梯度下降。但是,事实上,即使在 C C 是许多变量的函数时,一切都是一样的。特别是, C C 是 v1,…,vm v 1 , … , v m 变量的函数,然后在 C C 中,由一个小的变化产生的 ΔC Δ C , Δv=(Δv1,…,Δvm)T Δ v = ( Δ v 1 , … , Δ v m ) T
我们保证ΔC的(近似)表达式 ΔC≈∇C⋅Δv Δ C ≈ ∇ C ⋅ Δ v 是负的。这为我们提供了一种将梯度降到最低的方法,即使 C C 是许多变量的函数,通过反复应用更新规则
人们已经研究了许多梯度下降的变化,包括更接近真实物理球的变化。这些模仿球的变化有一些优势,但也有一个很大的缺点:它被证明是计算 C C 的二阶偏导数的必要条件,而这可能是相当昂贵的。要知道为什么它是昂贵的,假设我们要计算所有的第二个偏导数 ∂2C/∂vj∂vk ∂ 2 C / ∂ v j ∂ v k 。如果有一百万个这样的 vj v j 变量那么我们就需要计算一个万亿(例如100万的平方),不过,你明白这将会是计算成本很高的。话虽如此,但也有避免这种问题的方法,寻找梯度下降的替代方法是一个积极的研究领域。但是在这本书中,我们将使用梯度下降(和变化)作为我们在神经网络中学习的主要方法。
我们如何应用梯度下降法在神经网络中学习?我们的想法是使用梯度下降法来发现权重 wk w k 和偏差 bl b l ,从而最小化了方程的成本 C(w,b)≡1/2n∑x∥y(x)−a∥2 C ( w , b ) ≡ 1 / 2 n ∑ x ∥ y ( x ) − a ∥ 2 。为了了解它是如何工作的,让我们重申一下梯度下降更新规则,用权值和偏差代替 vj v j 变量。换句话说,我们的“位置”现在有 wk w k 和 bl b l 的组件,而梯度向量 ∇C ∇ C 有相应的组件 ∂C/∂wk ∂ C / ∂ w k 和 ∂C/∂bl ∂ C / ∂ b l 。用组件的形式写出梯度下降更新规则,则为:
通过反复应用这个更新规则,我们可以“滚下山”,并希望找到最小的成本函数。换句话说,这是一个可以用来在神经网络中学习的规则。
一个叫做随机梯度下降的概念可以用来加速学习。这个想法是通过计算随机选择的训练输入的一小部分的 Cx C x 来估计梯度 ∇C ∇ C 。通过对这个小样本的平均化,我们可以很快得到对真正的梯度C 的很好的估计,这有助于加速梯度下降。
为了使这些想法更精确,随机梯度下降法可以随机挑选出一小部分随机选择的训练输入。我们将把这些随机的训练输入标记为 X1,X2,。,Xm X 1 , X 2 , 。 , X m ,并将它们作为一个小批处理。如果样本容量足够大,我们期望 ∇CXj ∇ C X j 的平均值将大致等于所有 ∇Cx ∇ C x 的平均值,也就是说,
变换一下,得到
为了将其与神经网络中的学习联系起来,假设 wk w k 和 bl b l 表示我们的神经网络中的权重和偏差。然后随机梯度下降法通过随机选择的小批训练输入,并进行训练,
我们可以把随机梯度下降看作是一种政治投票:比起将梯度下降法应用到全批,更容易抽样一个小批量,就像进行投票比进行一次完整的选举要容易得多。例如,如果我们有一个大小为n=60000 的训练集,就像在MNIST一样,并选择一个小批量的(比如)m=10,这意味着我们将得到6000的加速估计的速度!当然,估计不会是完美的——会有统计上的波动——但它不需要是完美的:我们真正关心的是朝着一个大致的方向移动,这将有助于减少 C C ,这意味着我们不需要精确计算梯度。在实践中,随机梯度下降法是一种常用的、强大的神经网络学习技术,它是我们在这本书中发展的大部分学习技巧的基础。
让我来总结一下这一节,讨论一个有时会让人们对梯度下降感到陌生的观点。在神经网络中, C C 是一个由许多变量组成的函数—包括所有的权值和偏差—因此在某种意义上,它在一个非常高维的空间中定义了一个曲面。有些人挂在心里想着:“嘿,我必须能把所有这些额外的维度都形象化。”他们可能会开始担心:“我不能在四维空间中思考,更不用说五个(或500万)了”。他们是否有一些特殊的能力,他们缺失了,一些“真正的”超级数学家的能力?当然,答案是否定的。即使是最专业的数学家也不能把四个维度想象得很好,如果有的话。相反,他们使用的技巧是开发其他的方式来表示正在发生的事情。这就是我们上面所做的:我们使用了一个代数(而不是视觉)的 ΔC Δ C 来表示如何移动以减少 C C 。在高维度上思考的人有一个包含许多不同技术的思维库;我们的代数技巧就是一个例子。这些技术可能没有我们在可视化三个维度时所习惯的简单性,但是一旦您建立了这样的技术库,您就可以在高维度上进行思考。我不会在这里讲更多的细节,但是如果你感兴趣的话,你可能会喜欢读一些专业数学家在高维度上思考的技巧的讨论。虽然讨论的一些技术相当复杂,但大部分最好的内容都是直观的、可访问的,并且可以被任何人掌握。