天天看点

深度学习入门之从感知机开始

深度学习的一些个人学习(1)

首先我们从感知机开始说起。

通常感知机的形式如下图:

深度学习入门之从感知机开始

其中 x1 x2 x3 是输入,output是输出。

当我们想由输入得到输出时,可以按照如下的公式得到:

output=⎧⎩⎨⎪⎪⎪⎪01if ∑jwjxj≤ thresholdif ∑jwjxj> threshold(1)

你可以这样理解: x1,x2,x3 是衡量结果、影响最终结果判断的因素,而 wj 则是用来判断这些因素在对结果的影响中,能占多大的权重,也就是会多大程度上影响结果。通过(1)式我们也可以看出来,通过调节不同的threshold,我们可以获得不同的判断结果。

但是很明显的,这么简单的模型不能理解我们这个世界,于是我们让中间再加两层:

深度学习入门之从感知机开始

在这里,输入的的因素不仅仅做出一个判断,而是三个。而这三个输出结果,又成为下一层的输入,综合这一次的权重,影响第三层的结果判断。以此类推,我们可以增加好多层的感知机结构。

虽然这种情况下还是不能很好的描述我们这个世界,但是起码朝着理解世界更前进了一步。

从上面的结构来看,我们会以为多层的感知机有多个输出结果,但是实际上只有一个。我们这样画,只是为了表明一个感知机的多种不同的可能结果,作为下一层的输入来说,是怎么样组合起来,是怎样影响下一层的输出的。这样看起来比较方便些。

我们简化下公式(1):

  1. 我们用向量点乘来代替 ∑jwjxj :

    w⋅x=∑jwjxj

  2. 将thresh_hold进行转化,放到方程里面去 b≡−thresh_hold

    通过上面的转化,我们可以重写(1)

    output={01if w⋅x+b≤0if w⋅x+b>0(2)

b我们称之为偏差,可以理解为我们让结果输出为1的难易程度:b越大,结果为1就越难;b越小,结果为1就越简单。

这样一看,公式是不是清爽了好多。

通过感知机,我们可以“制作”简单的与门,或门,或者与非门。

例如我们看下面的例子:

深度学习入门之从感知机开始

我们可以看到:输入(0,0) ,(-2)* 0 + (-2)*0 +3 = 3 ,结果输出为正;

我们输入(1,0)(0,1),都会输出结果1;而如果输入(1,1),就会输出结果-1;

这样,我们就实现了一个与非门!

利用这个与非门,我们可以实现一些更复杂的逻辑,比如:

计算bitwise sum,也就是bit和;还可以用来标识当x1 x2都设定为1时进行标识:

深度学习入门之从感知机开始

可以自己看下结果:当x1, x2均为输入1时, x1x2结果为1,其余为0;

然后可以自己再设定下x1 x2分别为0,1,看下 x1⊕x2 ,可以看到结果就是他们的bit相加的结果。

注意,这里显示的器件都是nand门,也就是与非门。

通过这里我们可以看到感知机的一些潜力:他可以根据我们输入的一些因素,来对最终的结果产生影响,而不用我们人为的去定义一些规则。因此我们可以更深入的去挖掘它。

sigmod 神经元

想一下:我们想要使用感知机来处理结果,比如我们有一个要处理的图像,图像是数字8。我们的感知机最终的输出结果是数字9.那么如何来进行调整呢?加入你有一个小扳手,可以轻轻的调动参数w的值的话,那么理想的情况应该是:我稍微动一点扳手,也就是稍微动下w,那么最终的结果就稍微的变下,在这里我们可以理解为图像是9的概率小了些,而图像为8的概率大了些;我使劲的动了下调整的扳手,那么相对的8,9 的概率也会变大。这种情况下,实在是太方便我们调整参数了。

深度学习入门之从感知机开始

但是实际上你要相信,美好的事情不会这么容易发生。

更通常的情况是,你稍微扳了下扳手,这一层的输出结果没啥变化;你使劲扳了下,还是没啥变化;你再扳,结果噗的发生了突变,比如说从0变到了1,而这种突变使得后面各层的输入输出都会发生巨大变化!

牵一发而动全身,南美的蝴蝶啊,同志们。

所以,如果你不断的调参,最后的输出即使是9,那么在用这个网络去预测别的图像的时候,结果也会变得十分的有问题。

那么怎么解决这个问题呢?很明显,我们就找一个“动一下参数,结果就稍微动一下的输出函数”就可以了。而sigmod函数就是我们的真命天子了。

sigmod函数如下:

σ(z)≡11+e−z.(3)

为了避免你忘了z,我们将z带入一下:

11+exp(−∑jwjxj−b).(4)

这就是我们新的输出公式了。

为什么我们要选择这个函数作为我门的输出公示呢?

一开始,我们说,是为了实现“你动一点,我动一点”这个功能而选择的它。

首先,让我们来看下这个函数本身,能不能作为一个激活函数。

当z很大时,结果趋向于1;当z很小时,结果趋向于0;

我们看下该函数的图形:

从该图形我们也可以看出,sigmod函数的有着很好的平滑性,这种平滑性的有点就是:我们在对结果求导之后,得到的结果:

Δoutput≈∑j∂output∂wjΔwj+∂output∂bΔb,(5)

sigmod的这种平滑性,使得最终的结果也可以可控。想象一下,如果结果直接是

如果直接是这种形状,那么导数直接为0,就会影响我们的“微调”。

为什么我们用这个函数,而不是用其他的呢?实际上,我们也会用其他的函数来作为激活函数。我们选用sigmod函数,是因为sigmod函数的求导有着十分好的性质,这个性质方便我们进行处理。

于是,通常情况下,我们可以得到如下的模型:

深度学习入门之从感知机开始

这种模型,就是深度学习的模型了。

当然有时候,由于一些历史的原因,我们也会称之为multilayer perceptrons or*MLPs*。

接下来我们用一个例子来详细的说明。这个例子是用来识别手写字符的,例如:

深度学习入门之从感知机开始

我们希望可以从这个图片中,把里面的数字识别出来。

假设我们的输入为x,所希望的输出为y,也就是说我们给了一个字符“5”,那么输出的结果y(x)就是“5”。设定输入输出关系为y = y(x). 而a,则是我们输入字符“5”,我们通过深度学习网络能得到的结果。至于这个结果是5,还是其他的结果,就取决于我们的这个学习网络的能耐了。

那么,怎么来衡量这个网络结果的好坏呢?我们希望的情况是,通过调整合适的w和b,从而使得理想结果y(x)与a的结果尽量的小。我们使用代价函数来表征这个结果:

C(w,b)≡12n∑x∥y(x)−a∥2.(6)

我们称该方程为二次代价方程,也成为均值平方差或者MSE。

从方程的形式我们可以看出来, C(w,b) 是非负的。而且,当我们的网络预测的很好时,它的结果就是 C(w,b)≈0 ;当预测的结果很差时,它的结果就是 C(w,b) 很大。因此,我们希望通过调整w,b,使得(6)很小,从而使得误差很小。

怎么找w,b呢?

这时候,梯度下降gradient descent 就要出场了。

也许有人会问了,我们的本心是为了预测图片准确识别的数量,为什么不直接去衡量图片识别的准确率,而是间接的要通过一个二次方的代价呢?本来这是可以的,但是有个问题:图片的准确率对于w和b来说不是平滑可导的, 大部分情况下,小的w和b的改变对于结果没啥影响,这就很不利于调整参数。而如果用(6)式的话,就会有一个平滑可导的结果,从而可以让我们可以方便的去调整参数。

但是也会有人问,想要一个平滑可导的函数,好。可是,为什么非得选二次方呢?是随机选的吗?我们选其他的,那么不就得到了完全不同的w和b?

这是有道理的,后面我们再探讨这个事情。但是,二次导数在大部分情况下,是切实可行的,所以我们暂时先用这个进行计算。

接下来,我们暂时忘记我们要做的事情,把目标转移到另外一个问题上来。尽管可能你觉得很奇怪(当然,我知道其实你并不觉得),这个问题的探讨会很有帮助。

假设我们有一个函数 C(v) ,其中 v=v1,v2,v3…… 假设我们只有两个参数,我们可以画出如下的图形:

深度学习入门之从感知机开始

很明显的,我们可以看到有个谷底,这个谷底就是我们梦寐以求的最小值。然后我们就知道,我们肯定可以找到这个最小的点。但是我们肯定不能用肉眼来看最小值,而是用积分的方法来求。但是这个积分的方法话,对于只有几个参数的来说还行,但是参数一多,根本就无能为力了。

那么,我们该怎么求呢?

想象一下,我们站在一个山谷的谷顶,向下扔球,这个球会怎么样呢?这个球会自然的向谷底的地方滑去(假如没有摩擦力的话),那不正是我们期望的?!

假定一下,我们如果是个数学世界的造物主,有设定数学世界物理规律的能力,想要球按照上面的方式滚动,我们该怎么设计呢?

假如我们只有两个方向,v1和v2,我们向v1方向移动了 ∇v1 ,向v2方向移动了 ∇v2 ,那么我们可以知道总的移动:

ΔC≈∂C∂v1Δv1+∂C∂v2Δv2.(7)

因此,我们希望给 ∇v1,∇v2 找到一个值,使得 ∇C 为负值,这样,就使得球不断的往下走了么!

我们用下式进行变化:

∇C≡(∂C∂v1,∂C∂v2)T.(8)

于是就可以得到:

ΔC≈∇C⋅Δv.(9)

因此,我们设定

Δv=−η∇C,(10)

这样

ΔC≈−η∇C⋅∇C=−η∥∇C∥2

就一定是负值了!就一定可以向下走了!( η 设定为正值)

于是

v→v′=v−η∇C.(11)

这样不断地循环,我们就可以不断地向下走了!一直走到世界的,不是,是谷的低谷!

而且,更好的是,我们不仅仅希望向下走,而且可以以最快的速度向下走,这个问题也通过这个公式解决了。

设想下,我们移动 ∇v ,希望极可能的减小C ,也就是尽可能的使 ΔC≈∇C⋅Δv 小。也就是说,限定 ∥Δv∥=ϵ 步长的情况下,使其最小。可以证明,在当 Δv=−η∇C 时会使其尽可能的小。

因此,既可以减小,而且又可以尽量小!

好了,重新回到我们的深度学习的世界中来。

在这里, v1−>wk,v2−>bl ,因此我们可以设定为:

wkbl→→w′k=wk−η∂C∂wkb′l=bl−η∂C∂bl.(16)(17)

通过反复的迭代,我们可以找到C的最小值了。

再想一下,我门的代价函数是:

C(w,b)≡12n∑x∥y(x)−a∥2

设定

Cx≡∥y(x)−a∥22

于是就有 C=1n∑xCx ,求偏导则有: ∇C=1n∑x∇Cx

其中 x 是样例点的个数。可以看出来,每次更新,都需要综合考虑所有的样例点进行计算,可见非常的耗时。

因此,为了提高速度,有一种随机梯度下降的方法,来进行计算梯度。这个方法的思想就是,选择训练样本点中的一小部分来计算∇C ,通过这种处理,我们可以更快的来计算梯度下降。

那么,为什么我们可以这么算呢?

你可以这样假定:

∑mj=1∇CXjm≈∑x∇Cxn=∇C,(18)

这样,我们就可以得到:

∇C≈1m∑j=1m∇CXj,(19)

wk→w′k=wk−ηm∑j∂CXj∂wk(20) \

bl→b′l=bl−ηm∑j∂CXj∂bl(21) \

由此可见,我们可以有这种随机梯度下降的方法,来计算我们的函数了。

neuralnetworksanddeeplearning Michael Nielsen

继续阅读