zoukankan      html  css  js  c++  java
  • 《神经网络和深度学习》系列文章五:用简单的网络结构解决手写数字识别

    出处: Michael Nielsen的《Neural Network and Deep Learning》,点击末尾“阅读原文”即可查看英文原文。

    本节译者:哈工大SCIR本科生 赵怀鹏 (https://github.com/zhaohuaipeng)

    声明:我们将在每周一,周四,周日定期连载该书的中文翻译,如需转载请联系wechat_editors@ir.hit.edu.cn,未经授权不得转载。


    1. 使用神经网络识别手写数字

      • 感知机

      • sigmoid神经元

      • 神经网络的结构

      • 用简单的网络结构解决手写数字识别

      • 通过梯度下降法学习参数

      • 实现我们的网络来分类数字

      • 关于深度学习

    2. 反向传播算法是如何工作的

    3. 改进神经网络的学习方法

    4. 神经网络能够计算任意函数的视觉证明

    5. 为什么深度神经网络的训练是困难的

    6. 深度学习

    用简单的网络结构解决手写数字识别

    定义了神经网络之后,让我们回到手写数字识别的问题上来。我们可以把手写数字识别问题拆分为两个子问题。首先,我们要找到一种方法能够把一张包含若干数字的图像分割为若干小图片,其中每个小图像只包含一个数字。举个例子,我们想将下面的图像


    分割为6张小图像


    我们人类能够很容易地解决这个分割问题,但是让计算机去正确地分割图像是一件极具挑战的任务。当图像被分割之后,接下来的任务就是如何识别每个独立的手写数字。举个例子来说,我们想要程序去识别上述图像中的第一个数字,


    结果是5。

    我们将把精力集中在实现程序去解决第二个问题,即如何正确分类每个单独的手写数字。因为事实证明,只要你解决了数字分类的问题,分割问题相对来说不是那么困难。分割问题的解决方法有很多。一种方法是尝试不同的分割方式,用数字分类器对每一个切分片段打分。如果数字分类器对每一个片段的置信度都比较高,那么这个分割方式就能得到较高的分数;如果数字分类器在一或多个片段中出现问题,那么这种分割方式就会得到较低的分数。这种方法的思想是,如果分类器有问题,那么很可能是由于图像分割出错导致的。这种思想以及它的变种能够比较好地解决分割问题。因此,与其关心分割问题,我们不如把精力集中在设计一个神经网络来解决更有趣、更困难的问题,即手写数字的识别。

    为了识别数字,我们将会使用一个三层神经网络:

    这个网络的输入层是对输入像素编码的神经元。正如我们在下一节将要讨论的,我们的训练数据是一堆28乘28手写数字的位图,因此我们的输入层包含了784=28×28个神经元。为了方便起见,我在上图中没有完全画出784个输入神经元。输入的像素点是其灰度值,0.0代表白色,1.0代表黑色,中间值表示不同程度的灰度值。

    网络的第二层是隐层。我们为隐层设置了n个神经元,我们会实验n的不同取值。在这个例子中我们只展现了一个规模较小的隐层,它仅包含了n=15个神经元。

    网络的输出层包含了10个神经元。如果第一个神经元被激活,例如输出≈1,然后我们可以推断出这个网络认为这个数字是0。如果第二层被激活那么我们可以推断出这个网络认为这个数字是1。以此类推。更精确一些的表述是,我们把输出层神经元依次标记为0到9,我们要找到哪一个神经元拥有最高的激活值。如果6号神经元有最高值,那么我们的神经网络预测输入数字是6。对其它的神经元也如此。

    你可能会好奇为什么我们用10个输出神经元。毕竟我们的任务是能让神经网络告诉我们哪个数字(0,1,2,…,9)能和输入图片匹配。一个看起来更自然的方式就是使用4个输出神经元,把每一个当做一个二进制值,结果取决于它的输出更靠近0还是1。四个神经元足够编码这个问题了,因为24=16大于10种可能的输入。为什么我们反而要用10个神经元呢?这样做难道效率不低吗?最终的判断是基于经验主义的:我们可以实验两种不同的网络设计,结果证明对于这个特定的问题而言,10个输出神经元的神经网络比4个的识别效果更好。但是令我们好奇的是为什么使用10个输出神经元的神经网络更有效呢。有没有什么启发性的思考能提前告诉我们用10个输出编码比使用4个输出编码更有好呢?

    为了理解为什么我们这么做,我们需要从根本原理上理解神经网络究竟在做些什么。首先考虑有10个神经元的情况。我们首先考虑第一个输出神经元,它告诉我们一个数字是不是0。它能那么做是因为可以权衡从隐藏层来的信息。隐藏层的神经元在做什么呢?假设隐藏层的第一个神经元只是用于检测如下的图像是否存在:


    为了达到这个目的,它通过对此图像对应部分的像素赋予较大权重,对其它部分赋予较小的权重。同理,我们可以假设第二,第三,第四个隐藏层的神经元是为检测下列图片是否存在:


    正如你所猜到的那样,这四个图像拼到一起就组成了数字0 :


    如果所有这四个隐藏层的神经元被激活那么我们就可以推断出这个数字是0。当然,这不是我们推断出0的唯一方式——我们能通过很多其他合理的方式得到0 (举个例子来说,通过上述图像的转换,或者稍微变形)。但至少在这个例子中我们可以推断出输入的数字是0 。

    假设神经网络以上述方式运行,我们可以给出一个貌似合理的理由去解释为什么用10个输出而不是4个。如果我们有4个输出,那么第一个输出神经元将会尽力去判断数字的最高有效位是什么。把数字的最高有效位和数字的形状联系起来并不是一个简单的问题。很难想象出有什么恰当的历史原因,一个数字的形状要素会和一个数字的最高有效位有什么紧密联系。

    上面我们说的只是一个启发性的思考。没有什么理由表明这个三层的神经网络必须按照我所描述的方式运行,即隐藏层是用来探测数字的组成形状。可能一个聪明的学习算法将会找到一些合适的权重能让我们仅仅用4个输出神经元就行。但是这个启发式的思考通常很有效,它会节省你大量时间去设计一个好的神经网络结构。

    练习


    • 通过在上述的三层神经网络加一个额外的一层就可以实现按位表示数字。额外的一层把原来的输出层转化为一个二进制表示,如下图所示。为新的输出层寻找一些合适的权重和偏移。假定原先的3层神经网络在第三层得到正确输出(即原来的输出层)的激活值至少是0.99,得到错误的输出的激活值至多是0.01。

    下一节我们将介绍“通过梯度下降法学习参数”,敬请关注!


      • “哈工大SCIR”公众号

      • 编辑部:郭江,李家琦,徐俊,李忠阳,俞霖霖

      • 本期编辑:徐俊

  • 相关阅读:
    iOS开发之Socket
    IOS开发之Bug--使用KVC的易错情况
    IOS开发之功能模块--给任意的UIView添加点击事件
    IOS开发之开发者账号遇到的bug
    iOS开发--关于TableViewCell的可视化设置细节
    学习Coding-iOS开源项目日志(四)
    Learn how to Use UIPageViewController in iOS
    关于Storyboard的使用
    学习Coding-iOS开源项目日志(三)
    学习Coding-iOS开源项目日志(二)
  • 原文地址:https://www.cnblogs.com/sdlypyzq/p/4971323.html
Copyright © 2011-2022 走看看