深度学习入门第四讲

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

定义神经网络后,让我们回到手写识别上来。我们可以把识别手写数字的问题分成两个子问 题。首先,我们希望有个方式把包含许多数字的图像分成一系列单独的图像,每个包含单个数 字。例如,我们想要把图像

分成六个单独的图像,

我们人类可以很容易解决这个分割的问题,但是对于计算机程序来说却是个挑战。一旦图像 被分割,那么程序需要把每个单独的数字分类。例如,我们想要我们的程序能识别上面的第一 个数字

是 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 个输出神经元就行。但是这个启发性的方法通常很有效,它会 节省你大量时间去设计一个好的神经网络结构。

练习

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


原文发布于微信公众号 - UAI人工智能(UniversityAI)

原文发表时间:2017-10-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏desperate633

LeetCode Invert Binary Tree题目分析

Invert a binary tree. 4 / \ 2 7 / \ / \1 3 6 9 to4 / \ 7 2 / \ / \9 6 3 1 Tri...

831
来自专栏拭心的安卓进阶之路

Java 集合深入理解(6):AbstractList

今天心情比天蓝,来学学 AbstractList 吧! ? 什么是 AbstractList ? AbstractList 继承自 AbstractCollec...

19110
来自专栏赵俊的Java专栏

从源码上分析 ArrayList

1161
来自专栏ml

朴素贝叶斯分类器(离散型)算法实现(一)

1. 贝叶斯定理:        (1)   P(A^B) = P(A|B)P(B) = P(B|A)P(A)   由(1)得    P(A|B) = P(B|...

3417
来自专栏java闲聊

JDK1.8 ArrayList 源码解析

当运行 ArrayList<Integer> list = new ArrayList<>() ; ,因为它没有指定初始容量,所以它调用的是它的无参构造

1192
来自专栏xingoo, 一个梦想做发明家的程序员

20120918-向量实现《数据结构与算法分析》

#include <iostream> #include <list> #include <string> #include <vector> #include...

1706
来自专栏xingoo, 一个梦想做发明家的程序员

AOE关键路径

这个算法来求关键路径,其实就是利用拓扑排序,首先求出,每个节点最晚开始时间,再倒退求每个最早开始的时间。 从而算出活动最早开始的时间和最晚开始的时间,如果这两个...

2507
来自专栏MelonTeam专栏

ArrayList源码完全分析

导语: 这里分析的ArrayList是使用的JDK1.8里面的类,AndroidSDK里面的ArrayList基本和这个一样。 分析的方式是逐个API进行解析 ...

4469
来自专栏后端之路

LinkedList源码解读

List中除了ArrayList我们最常用的就是LinkedList了。 LInkedList与ArrayList的最大区别在于元素的插入效率和随机访问效率 ...

19110
来自专栏刘君君

JDK8的HashMap源码学习笔记

3008

扫码关注云+社区