MyFPGA Forum

 找回密码
 注册
搜索
热搜: 活动 交友 discuz
查看: 78|回复: 1

神经网络和深度学习(二)——一个简单的手写数字分类...

[复制链接]
发表于 2020-6-30 14:45:10 | 显示全部楼层 |阅读模式
本帖最后由 winter 于 2020-6-30 15:11 编辑

一个简单的手写数字分类网络

接上一篇文章,我们定义了神经网络,现在我们开始手写体的识别。我们可以将识别手写数字这个问题划分为两个子问题,一,我们需要将一幅包含了许多数字的图像分解为一系列独立的图像,每一幅图像包含了一个数字。比如,我们需要把下图分解:



1.png
将该图分解为6幅独立的图像:


2.png
我们人可以很轻松的将其分开,但是计算机可不那么认为。一旦图片被分割后,程序需要将每个数字单独识别。因此,举个例子,我们想要我们的程序可以识别上图中的第一个数字为5。


3.png
这里我们致力于解决第二个问题,就是对单一数字的分类。因为对于第一个分割问题,这里有许多方法可以解决了。因此,与其关⼼分割问题,我们不如把精⼒集中在设计⼀个神经⽹络来解决更有趣、更困难的问题,即⼿写数字的识别。

为了识别单个数字,我们将用到三层神经网络:


4.png
网络的输入层包含了对输入像素值编码的神经元。正如后面讨论的,我们的训练数据有许多28X28的手写数字的像素图组成,也就是说我们的输入层包含了28X28=784个神经元,一个神经元对应一个像素位的值。输入的像素值为灰度值,0.0表示白色,1.0表示黑色,0到1之间的值表示不同程度的灰色。

网络的第二层为隐藏层,我们记隐藏层的神经元数量为n,我们将对n的取值进行实验。这个图例中展示了一个小的隐藏层,它的隐藏层只有15个。

网络的输出层包含了10个神经元。如果第一个神经元被激活,也就是输出值无限接近1,那么我们可以认为这个网络识别出来的数字是0.如果是第二个神经元激活,那么识别出来的数字为1。更准确的说,我们将对输出神经元从0到9编号,然后找出激活值最高的神经元。如果编号为6的神经元激活值最高,那么我们认为输入的数字为6。

这里使用是个输出神经元很现实是为了对应输出的十种可能性。一种看起来更自然的方法是使用4个输出神经元,每一个神经元看作一个二进制数,结果取决于改神经元输出更靠近0还是更靠近1。4个输出神经元对于10个数字来说已经足够了,毕竟 QQ截图20200630145607.png 是大于10的。那为什么我们选择使用是个输出的神经元而不是看起来更方便简洁的4个神经元呢?经验告诉我们:通过对两种设计的实验对比,是个输出的神经元比4个输出的神经元更加准确的识别数字。但这是为什么呢?有没有什么启发性的方法可以告诉提前告诉我们使用10个输出神经元比使用4个效果要更好。

为了理解为什么要这样做,了解神经网络的工作的基本原理是很有帮助的。首先考虑我们使用10个输出神经的情况。让我们把目光放在第一个输出神经上,该神经决定了是否该数字是0。它是通过权衡隐藏层所输出的信息做出判断的。那么隐藏层的神经元做了些什么呢?假设隐藏层的第一个神经元是为了检测图像中是否存在如下图形:


5.png
它是通过对输入图像中与该图形重合的像素赋予很大的权值,而其他部分赋予很小的权值来判断的。以同样的方式,我们假设第二个第三个第四个神经元分别是为了探测图像中是否存在以下图形:


6.png
可能你已经看出来上面四个图形可以组成数字0:


8.png
因此,如果隐藏层的这四个神经元都被激活,那么我们可以认为这个图像上的数字是0。当然这不是我们用来推断数字为0的唯一组合,我们可以通过诸多图形组合得到0(比如将上图进行扭曲变形,但它还是0)。但至少在这个例子中,我们可以推断出输入数字是0。

如果神经网络是这样工作的,那么我们似乎可以给出一个对为什么使用10个输出神经而不是4个这件事一个合理的解释。如果是4个输出神经元,那么,我们的第一个输出神经元将用于判断该数字对应二进制的最高有效位是什么,然而,我们很难将图形和数字的最高有效位对应起来。

上面说了这么多都只是一个启发性的方法,没人说三层神经网络必须按照我上面所说的方式去工作,即每个隐藏层的神经元去探测一个简单的图像组成部分。也许一些聪明的学习算法会找到一些权重分配让我们使用4个输出神经元。但是作为一种启发,我所描述的方法可以工作的很好,这可以让你节省许多时间在设计神经网络的结构上。



 楼主| 发表于 2020-7-9 13:58:33 | 显示全部楼层
本帖最后由 winter 于 2020-7-9 14:04 编辑

使用梯度下降算法进行学习

现在我们已经设计出了一个神经网络,那么我们如何使用它去学习识别数字呢。首先,我们需要一个数据集去学习,我们使用的是MNIST数据集,它包含了数以万计的手写数字的扫描图像,以及他们的正确分类。下图是取值MNIST的几个图像:

QQ截图20200630144742.png
正如你所见,这些数字和上一篇文章的数字是一样,当然我们需要我们的网络可以识别不在数据集中的图像。

MNIST数据集包含两个部分,第一个部分包含了60000张图片被用作训练数据。这些通过扫面250个人的手写数字获得,其中有些是美国人口普查局的员工,有些是高中生。这些图像是28X28的灰度图。数据集的第二部分是10000张图片被用来测试,与训练数据的格式一样。我们将使用测试数据衡量我们的神经网络学习得怎么样。当然第二部分的图片是另外250个人的手写样本,这有可以让我们证实网络可以识别不在训练集中的人的手写数字。

我们用x
表示一个训练输入。显然x是一个28X28=784的向量,向量中每一个元素表示图像中的一个灰度值。我们用y=y(x)表示对应的期望输出值,其中y是一个10维的向量。比如,有一个特定的显示为6的图像输入为x,那么它期望的输出值应该为y(x)=(0,0,0,0,0,0,1,0,0,0)T,其中T表示矩阵的转置。

我们想有这样一个算法,它可以让我们找到权重和偏差,这样网络的输出y(x)可以拟合所有的输入x。为了量化我们如何实现这个目标,我们定义一个代价函数:


11.png

其中w记为网络中的所有权重的集合,b为所有的偏差,n是所有训练输入的数量,a是当输入向量为x时网络的输出向量,并且对所有的输入x进行计算并求和。的确,输出a依赖于输入x、w和b,但是为了简介,我并没用使用axi 这样的符号。符号||v||表示的是向量v的长度(模)。我们把C称为二次代价函数,有时也被称为均方误差或者MSE。观察二次代价函数,我们可以发现C(w,b)是非负的。此外,对于所有的x,当y(x)接近于a时,C(w,b)的值是很小的,也就是C(w,b)≈0,因此我们的训练算法需要能够找到合适的权重和偏差,使得C(w,b)≈0。相反,如果C(w,b)的值很大,就说明有大量的y(x)和a相差很大,这是不好的。因此我们的训练算法目标是要能够找到最小化代价函数C(w,b)的权重和偏差。换句话说,我们需要找到一组权重和偏差,使得代价最小,下面我们将使用梯度下降算法来达到目标。

为什么要介绍二次代价函数?我们不应该关注于图像的正确分类的数量上面吗?为什么不尝试直接最大化正确分类的数量而是要使用最小化一个二次代价函数来简介评测呢?这是因为正确分类图像的数量对于权重和偏差来说不是一个平滑的函数,那么在大多数情况下,对权重和偏差的微小改变不会造成目标函数即正确分类数量的值的改变,这让我们很难找到通过改变权重和偏差提高性能的方法。如果我们使用一个像二次代价函数这样的平滑函数,那将很容易找到通过改变权重和偏差来提高性能的方法。这就是我们为什么专注于最小化二次代价,因为只有这样,我们才能测试分类的准确性。

那么可能你又会好奇为什么要选择式(6)那样的二次函数来作为平滑函数呢?这时临时想出来的么?可能如果我们选择另外一个不一样的代价函数,我们将会得到不同的代价最小时的权重和偏差。这个疑问是有必要的,稍后我将对上面的成本函数再次进行讨论,并作一些修改。然而式(6)中的代价函数对于我们理解神经网络的基础很有帮助,所以我们将一直使用它。

重申一次,我们的目标是训练一个神经网络,找到权重和偏差使得二次代价函数C(w,x)C(w,x)最小化。这个目标没毛病,但是,现在有许多让我们分散精力的东西——对权重ww和偏差bb的解释,难以弄清的σσ函数,网络架构的选择,MNIST等等。其实我们可以通过忽略上述这些中的绝大部分,仅仅考虑最小化这一点来理解这些东西。现在,我们打算忘掉代价函数的具体形式,神经网络的组成等等。现在我们只专注于最小化一个给定的多元函数。我们将学习一种用于最小化问题的梯度下降算法,然后再回到我们想要最小化神经网络的特定函数上去。

OK,现在假设我们尝试最小化某些函数,C(v),它可能是任意的多元实数函数,v=v1,v2,...。注意到我将使用v代替前面的w和b,因为我们刚说过我们不再特定研究神经网络代价函数的最小化问题上,而是任意的函数。我们先假设C是只有两个变量的函数,我们称为v1和v2:


22.png
我们想要找到使C达到全局最小的位置。现在对于上述的图像中,我们可以很容易的找到全局最小值。从某种意义上说,我可能展示了一个过于简单的函数。通常函数C是一个拥有许多变量的复杂的函数,并且将不可能通过肉眼一下找到它的全局最小值。


解决这个问题的一种方法是使用微积分的方法。我们将计算函数 C 的导数来寻找它的极值点。运气好的话函数可能只有一个或者几个变量,但是一旦变量过多那将很麻烦。尤其是神经网络中,往往拥有数亿计的权重和偏差,微积分的方法将不再有效。

现在微积分是不能解决最小值的问题了。幸运的是,有一种漂亮的推导法暗示有一种算法可以很好的解决问题。首先我们把函数想象成山谷,向上面那幅图画一样。然后我们假设有一个球从山谷上沿斜坡滚下,常识告诉我们这颗球会滚落到山谷底部。也许我们可以使用这样一个想法去寻找函数的最小值。开始我们把球随机放置在一个位置,然后模拟球从该点滚落到谷底这一过程。我们可以通过计算C的导数(和一些二阶导数)来简单模拟——这些导数将告诉我们这个山谷的一切局部形状,然后我们就知道这个球该怎么滚落了。

说了这么多,你可能会以为接下来我将介绍牛顿定理,摩擦力和重力对球体的影响。事实上,我们只是做了一个假设,并不是真的要用这个球的运动来寻找最小值。提到球只是用来激发我们的想象力,而不是束缚我们的思维。因此与其陷进物理学⾥凌乱的细节,不如我们就这样问⾃⼰:如果我们扮演⼀天的上帝,能够 构造⾃⼰的物理定律,能够⽀配球体可以如何滚动,那么我们将会采取什么样的运动学定律来 让球体能够总是滚落到谷底呢?



您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|MyFPGA

GMT+8, 2020-8-10 13:23 , Processed in 0.107634 second(s), 18 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表