(Tensorflow)手把手CNN入门:手写数字识别

摘要: 手把手带你实战——《CNN入门:手写数字识别》!

深度学习最使人兴奋的领域之一就是计算机视觉。经过卷积神经网络,咱们已经可以建立自动驾驶汽车系统、面部检测系统和自动医学图像分析等等。在本文中,我将向你展现卷积神经网络的基本原理以及如何本身建立一个对手写数字进行分类的系统。git

卷积神经网络的功能彷佛是人类大脑中生物功能的复制,早在1959年,David Hubel和Torsten Wiesel对猫和猴进行了研究,这些研究揭示了动物视觉皮层的功能。他们发现的是,许多神经元具备小的局部接受性,即仅对整个视野的一小块有限区域起反应。他们发现某些神经元会对某些特定模式作出反应,例如水平线、垂直线和其余圆形。他们还发现其余神经元具备更大的感觉野而且被更复杂的模式刺激,这些模式是由较低水平神经元收集的信息组合。这些发现奠基了咱们如今称之为卷积神经网络的基础。接下来,咱们逐一介绍卷积神经网络的组成。算法

一、卷积层服务器

卷积神经网络中每层卷积层由若干卷积单元组成,每一个卷积单元的参数都是经过反向传播算法最佳化获得的。卷积运算的目的是提取输入的不一样特征,第一层卷积层可能只能提取一些低级的特征如边缘、线条和角等层级,更多层的网路能从低级特征中迭代提取更复杂的特征。你能够将每一个过滤器描绘成一个窗口,该窗口在图像的尺寸上滑动并检测属性。滤镜在图像上滑动的像素数量称为步幅。步幅为1意味着滤波器一次移动一个像素,其中2的步幅将向前跳过2个像素。网络

在上面的例子中,咱们能够看到一个垂直线检测器。原始图像为6x6,它使用3x3滤镜进行扫描,步长为1,从而产生4x4尺寸输出。而过滤器仅对其视野左右列中的部分感兴趣。经过对图像的输入求和并乘以3×3滤波器的配置,咱们获得3+1+2-1-7-5=-7。而后滤波器向右移动一步,而后计算1+0+3-2-3-1=-2。-2而后进入-7右侧的位置。此过程将持续到4x4网格完成为止。以后,下一个特征图将使用它本身的惟一过滤器/内核矩阵计算本身的值。架构

2.池化层机器学习

池化层的目标是经过聚合卷积层收集的值或所谓的子采样来进一步下降维度。除了为模型提供一些正则化的方案以免过分拟合以外,这还将减小计算量。它们遵循与卷积层相同的滑动窗口思想,但不是计算全部值,而是选择其输入的最大值或平均值。这分别称为最大池化和平均池化。ide

这两个组件是卷积层的关键构建块。而后,你一般会重复此方法,进一步减小特征图的尺寸,但会增长其深度。每一个特征图将专门识别它本身独特的形状。在卷积结束时,会放置一个彻底链接的图层,其具备激活功能,例如Relu或Selu,用于将尺寸从新整形为适合的尺寸送入分类器。例如,若是你的最终转换层为3x3x128矩阵,但你只预测10个不一样的类,则须要将其从新整形为1x1152向量,并在输入分类器以前逐渐减少其大小。彻底链接的层也将学习它们本身的特征,如在典型的深度神经网络中。函数

如今让咱们看看在MNIST手写数字数据集上的Tensorflow中的实现。首先,咱们将加载咱们的库。使用sklearn中的fetch_mldata,咱们加载mnist数据集并将图像和标签分配给x和y变量。而后咱们将建立咱们的训练/测试装置。最后,咱们将举几个例子来了解任务。性能

接下来,咱们将进行一些数据加强,这是提升模型性能的可靠方法。经过建立训练图像的轻微变化,能够为模型建立正则化。咱们将使用Scipy的ndimage模块将图像向右、向左、向上和向下移动1个像素。这不只提供了更多种类的例子,并且还会大大增长咱们训练集的大小。学习

我将向你展现的最后一种数据加强的方式:使用cv2库建立图像的水平翻转。咱们还须要为这些翻转图像建立新标签,这与复制原始标签同样简单。

设置“flipCode = 0”将产生垂直翻转

接下来,咱们将建立一个辅助函数,用于将随机微型批次提供给咱们的神经网络输入。因为卷积层的性质,它们在前向和后向传播步骤期间须要大量的存储器。考虑具备4x4滤镜的图层,输出128步幅为1的特征图和具备尺寸299x299的RGB图像输入的SAME填充。参数的数量将相等(4x4x3+1)x128 = 6272.如今考虑这128个特征图中的每个都计算299x299个神经元,而且这些神经元中的每个都计算4x4x3输入的加权和。这意味着咱们须要4x4x3x299x299x150=643,687,200次计算,这只是一个训练的例子。

如今咱们开始建立咱们的网络架构。首先,咱们为咱们的培训数据/特征建立占位符。咱们须要将它们从新整形为(-1,28,28,1)矩阵,由于tensorflow conv2d层须要4维输入。咱们将第一个维度设置为“null”,以容许将任意批量大小提供给占位符。

接着咱们设计咱们的卷积层,我是从Le-NET5(由Yann LeCun开创)网络架构中获取灵感,该架构因其在手写数字分类方面成功而闻名。我建议你研究Le-NET5以及其余通过验证的模型,这样就能够了解哪一种卷积网络适用于不一样的任务。连接:http://yann.lecun.com/exdb/publis/pdf/lecun-01a.pdf

咱们模型卷积层的第一层由12个特征图组成,使用3x3过滤器,步幅为1。咱们选择了SAME填充,经过在输入周围添加一个零填充来保持图像的尺寸。而后,咱们设置最大池化层使用3x3过滤器,步幅为1,这将输出13x13x12矩阵。因此咱们从一个28x28x1的图像开始,而后咱们将这个矩阵传递给第二个转换层,第二个转换层具备3x3过滤器的深度,stride=1和SAME填充。这将输出一个6616维矩阵。你能够看到咱们正在缩小特征图的维度空间,但要更深刻。接下来,咱们使用Selu函数激活两个密集层来减小每层输入的数量大约一半,直到最终将它们输入咱们的logits。

接着咱们建立咱们的损失函数,在这种状况下,它将是softmax交叉熵,它将输出多类几率。你能够将交叉熵视为各类数据点之间距离的度量。咱们选择AdamOptimizer(自适应矩估计),当梯度降低时自动调整它的学习率。最后,咱们建立了一种评估结果的方法。Tensorflow的in_top_k函数将计算咱们的logits并选择最高分。而后咱们使用咱们的准确度变量输出0-1%之间的百分比。

如今咱们已经为训练阶段作好了准备,让咱们看看咱们的模型表现得如何。

在第19epoch,咱们的正确率在0.9907。这已经比任何机器学习算法的结果更好,所以卷积已经取得了领先。如今让咱们尝试使用咱们的移位功能/翻转功能,并为咱们的网络添加两个新元素:dropout和批量标准化。

咱们使用placeholder_with_default节点修改现有占位符,这些节点将保存批量标准化和dropout层生成的值。在训练期间,咱们将这些值设置为True,在测试期间,咱们将经过设置为False将其关闭。

批量标准化只是简单地对每批次的数据进行标准化。咱们指定了0.9的动量。而dropout和正则化指定动量为1才能在训练期间彻底随机地关闭节点。这致使其他节点必须松弛,从而提升其有效性。想象一下,一家公司决定每周随机选择50名员工留在家里。其他的工做人员将不得不有效地处理额外的工做,提升他们在其余领域的技能。

接着咱们建立咱们的损失函数,训练步骤和评估步骤,而后对咱们的执行阶段进行一些修改。经过批量标准化执行的计算在每次迭代期间保存为更新操做。为了访问这些,咱们分配一个变量extra_update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)。在咱们的训练操做期间,咱们将其做为列表项与training_op一块儿提供给sess.run。最后,在执行验证/测试预测时,咱们经过feed_dict为占位符分配False值。咱们不但愿在预测阶段有任何随机化。为了得到输出,咱们使用咱们的测试集运行logits操做。让咱们看看这个模型添加正则化/标准化而且正在使用加强数据的方法后表现得如何。

在29epoch,咱们在10,000个数字的测试集上达到了99.5%的准确率。正如你所看到的那样,第二个epoch时模型精确度达到了99%,而以前的模型只有16%。虽然0.05%可能不是不少,但在处理大量数据时这是一个重大改进。最后,我将向你展现如何在logits输出上使用np.argmax产生的预测。

云服务器99元拼团购!拉新还可赢现金红包!300万等你瓜分!
立刻一键开团赢红包: http://click.aliyun.com/m/100...



本文做者:【方向】

阅读原文

本文为云栖社区原创内容,未经容许不得转载。

相关文章
相关标签/搜索