学习算法听起来很美妙。但是我们如何设计出这样的神经元网络算法呢?假设我们有一个想要用来学习解决问题的神经元网络。例如,输入网络的是扫描一副手写数字图片的原始像素数据。我们希望这个网络学习权重和偏移,然后输出数字的正确分类。来看一下学习如何工作,假设我们很小的改动了网络中的一些权重(或者偏移),我们期望的是通过改变这一点的权重仅仅使网络的输出有相应的很小的改变。正如接下来我们将要看到的,这个性质使学习称为了可能。如图所示,这就是我们想要的(显然这个网络太简单而不能用来做手写识别):
如果权重(或者偏移)很小的变化真的可以仅仅引起输出很小的改变,我们就可以用这个事实来修改权重和偏移来使我们的网络做出我们想要的表现。例如,假设网络错误的将一幅“9”的图片识别成“8”,我们可以算出怎样使权重和偏移做出很小的变化使网络更接近的能够将“9”的图片分类正确。然后重复这一步,一遍一遍的改变权重和偏移来得到越来越好的输出。这个网络就学习了。
问题是包含很多感知机的网络并不是这样。事实上,任何一个神经元权重或者偏移很小的改变都可能感知机输出完全反转,也就是从0到1。这种反转可能会引起剩余网络的行为以很复杂的方式完全改变。因此当“9”现在可能分类正确了,这个网络的行为在其它图片上可能不可控的完全改变了。这使得通过逐步修改权重和偏移来使网络得到跟接近想要的行为的方式是很难的。也许有更聪明的方法来解决这个问题,但是这不能立刻让我们明确的知道神经网络是怎样学习的。
我们可以通过引入一种被称为*sigmoid*的新的神经元来克服这个问题。Sigmoid神经元和感知机非常接近,但是修改他们很小的权重和偏移可以引起仅仅输出很小的改变。这是使sigmoid神经网络可以学习的决定性事实。
好了,让我们描述一下sigmoid神经元。我们将像画感知机一样画sigmoid神经元:
就像感知机一样,这个sigmoid神经元有输入,x1,x2,x3.... 但是输入可以**取0到1之间的任何值**,而不仅仅是0和1。因此,例如,0.638...对sigmoid神经元来说是有效的输入值。也像感知机一样,sigmoid神经元对没有输入也有相应的权重w1,w2.... 并且一个总的偏移b。但是输出不是0或1,而是<code>σ(w⋅x+b)</code>,σ被称为*sigmoid函数*,定义如下:
更明确的,一个输入为x1,x2,...,权重为w1,w2,....,并且偏移为b的sigmoid神经元的输出为:
乍一看,sigmoid神经元表现的和感知机很不一样。如果你对sigmoid函数代数式不熟悉的话,它看起来可能是陌生又令人敬畏的。事实上,sigmoid神经元和感知机之间有很多相似的地方,而sigmoid函数的代数形式更多的是技术细节而不是真正的理解障碍物。
为了理解和感知机模型的相似性,假设z≡w⋅x+b是一个很大的正数,那么,e^−z≈0并且σ(z)≈1。换句话说,当z=w⋅x+b的值是个正数并且很大的时候,sigmoid神经元的输出接近于1,就像一个感知机一样。相反的,假设z=w⋅x+b是一个很大的负数,那么e^−z→∞且σ(z)≈0。因此说,当z=w⋅x+b是一个很大的负数的时候,sigmoid神经元的行为和感知机也很接近。只有w⋅x+b是一个中等值的时候,感知机模型的值差别才会非常大。
σ的代数形式是怎样的呢?我们怎样理解它?事实上,σ的准确形式并不重要,重要的是这个函数画出来的时候是什么样子的。形如下图:
形似一个平滑的阶跃函数:
如果σ真的是一个阶跃函数,那么sigmoid神经元就成为了一个感知机,因为他的输出由w⋅x+b的正负决定是0还是1。正如上面暗示的那样,使用σ函数后我们得到了一个平滑输出的感知机。确实,σ函数的平滑性至关重要,而不是它的其他细节。σ平滑意味着权重很小的改变Δwj和偏移很小的改变Δb能够使神经元输出产生很小的改变Δoutput。事实上,经过计算,Δoutput大约为:
你不熟悉偏导数也不要惊慌! 虽然这个都是偏导数的表达式看起来很复杂,但是它实际上说的东西非常简单(这听起来是一个好消息):Δoutput是一个关于Δwj和Δb的**线性函数**。这种线性性质使的改变很小的权重和偏移使输出得到期望的微小变化变的很简单。虽然sigmoid神经元和感知机有很多相似的行为,但是它使得计算怎样改变权重和偏移来改变输出变得更简单。
如果σ的形状很重要而不是它的准确细节,那么我们为什么还要会用等式(3)中的形式呢?事实上,在本书接下来的部分中,对于神经元其他的**激励函数**f(·)我们会偶尔认为是f(w⋅x+b)。我们使用不同的激励函数后最大的变化就是等式(5)中的偏导数的值的变化。当我们计算偏导数的时候使用σ将会简代数,因为指数有很好的求导性质。无论如何,σ是一个在神经元网络中经常使用的函数,并且是我们在这本书中使用的最多的激励函数。
我们应该怎样解释sigmoid神经元的输出呢?非常明显的的是感知机和sigmoid神经元最大的不同是sigmoid神经元的输出不仅仅是0和1,也可以是像0.173...和0.689..的合法输出。这是很有用的,例如,如果我们想要输出输入到神经网络中一张图片像素的平均强度值,但是有时这是很令人讨厌的。假设我们想要从网络中输出表明是“输入的图片是9”或者“输入的图片不是9”。显然,最简单的是使用感知机输出0或1。实际中我们可以建立一个惯例来解决这个问题,例如,通过声明任何不小于0.5的输出是“9”,任何小于0.5的输出是“不是9”。当我们使用这种惯例的时候我会明确说明,所以这不会引起任何混乱。