这篇文章中,我们将使用CNN构建一个Tensorflow.js模型来分辨手写的数字。首先,我们通过使之“查看”数以千计的数字图片以及他们对应的标识来训练分辨器。然后我们再通过此模型从未“见到”过的测试数据评估这个分辨器的精确度。

一、运行代码

  这篇文章的全部代码可以在仓库TensorFlow.js examples中的tfjs-examples/mnist 下找到,你可以通过下面的方式clone下来然后运行这个demo:

$ git clone https://github.com/tensorflow/tfjs-examples
$ cd tfjs-examples/mnist
$ yarn
$ yarn watch

  上面的这个目录完全是独立的,所以完全可以copy下来然后创建你个人的项目。

  

二、数据相关

  这篇文章中,我们将会使用  MNIST 的手写数据,这些我们将要去分辨的手写数据如下所示:
                    

  为了预处理这些数据,我们已经写了 data.js这个文件包含了Minsdata类,而这个类可以帮助我们从MNIST的数据集中获取到任意的一些列的MNIST。

  而MnistData这个类将全部的数据分割成了训练数据和测试数据。我们训练模型的时候,分辨器就会只观察训练数据。而当我们评价模型时,我们就仅仅使用测试数据,而这些测试数据是模型还没有看见到的,这样就可以来观察模型预测全新的数据了。

  这个MnistData有两个共有方法:

  • nextTrainBatch(batchSize): 从训练数据中返回一批任意的图片以及他们的标识。
  • nextTestBatch(batchSize):  从测试数据中返回一批图片以及他们的标识。

  注意:当我们训练MNIST分辨器时,应当注意数据获取的任意性是非常重要的,这样模型预测才不会受到我们提供图片顺序的干扰。例如,如果我们每次给这个模型第一次都提供的是数字1,那么在训练期间,这个模型就会简单的预测第一个就是1(因为这样可以减小损失函数)。 而如果我们每次训练时都提供的是2,那么它也会简单切换为预测2并且永远不会预测1(同样的,也是因为这样可以减少损失函数)。如果每次都提供这样典型的、有代表性的数字,那么这个模型将永远也学不会做出一个精确的预测。

  

三、创建模型

  在这一部分,我们将会创建一个卷积图片识别模型。为了这样做,我们使用了Sequential模型(模型中最为简单的一个类型),在这个模型中,张量(tensors)可以连续的从一层传递到下一层中。

  首先,我们需要使用tf.sequential先初始化一个sequential模型:

const model = tf.sequential();

  既然我们已经创建了一个模型,那么我们就可以添加层了。

四、添加第一层

  我们要添加的第一层是一个2维的卷积层。卷积将过滤窗口掠过图片来学习空间上来说不会转变的变量(即图片中不同位置的模式或者物体将会被平等对待)。

  我们可以通过tf.layers.conv2d来创建一个2维的卷积层,这个卷积层可以接受一个配置对象来定义层的结构,如下所示:

model.add(tf.layers.conv2d({
inputShape: [, , ],
kernelSize: ,
filters: ,
strides: ,
activation: 'relu',
kernelInitializer: 'VarianceScaling'
}));

  让我们拆分对象中的每个参数吧:

  • inputShape。这个数据的形状将回流入模型的第一层。在这个示例中,我们的MNIST例子是28 x 28像素的黑白图片,这个关于图片的特定的格式即[row, column, depth],所以我们想要配置一个[28, 28, 1]的形状,其中28行和28列是这个数字在每个维度上的像素数,且其深度为1,这是因为我们的图片只有1个颜色:
  • kernelSize。划过卷积层过滤窗口的数量将会被应用到输入数据中去。这里,我们设置了kernalSize的值为5,也就是指定了一个5 x 5的卷积窗口。
  • filters。这个kernelSize的过滤窗口的数量将会被应用到输入数据中,我们这里将8个过滤器应用到数据中。
  • strides。 即滑动窗口每一步的步长。比如每当过滤器移动过图片时将会由多少像素的变化。这里,我们指定其步长为1,这意味着每一步都是1像素的移动。
  • activation。这个activation函数将会在卷积完成之后被应用到数据上。在这个例子中,我们应用了relu函数,这个函数在机器学习中是一个非常常见的激活函数。
  • kernelInitializer。这个方法对于训练动态的模型是非常重要的,他被用于任意地初始化模型的weights。我们这里将不会深入细节来讲,但是 VarianceScaling (即这里用的)真的是一个初始化非常好的选择。

  

五、添加第二层  

  让我们为这个模型添加第二层:一个最大的池化层(pooling layer),这个层中我们将通过 tf.layers.maxPooling2d 来创建。这一层将会通过在每个滑动窗口中计算最大值来降频取样得到结果。

model.add(tf.layers.maxPooling2d({
poolSize: [, ],
strides: [, ]
}));
  • poolSize。这个滑动池窗口的数量将会被应用到输入的数据中。这里我们设置poolSize为[2, 2],所以这就意味着池化层将会对输入数据应用2x2的窗口。
  • strides。 这个池化层的步长大小。比如,当每次挪开输入数据时窗口需要移动多少像素。这里我们指定strides为[2, 2],这就意味着过滤器将会以在水平方向和竖直方向上同时移动2个像素的方式来划过图片。

  注意:因为poolSize和strides都是2x2,所以池化层空口将会完全不会重叠。这也就意味着池化层将会把激活的大小从上一层减少一半。

  

六、添加剩下的层

 

  

  

图片训练:使用卷积神经网络(CNN)识别手写数字的更多相关文章

  1. 如何用卷积神经网络CNN识别手写数字集?

    前几天用CNN识别手写数字集,后来看到kaggle上有一个比赛是识别手写数字集的,已经进行了一年多了,目前有1179个有效提交,最高的是100%,我做了一下,用keras做的,一开始用最简单的MLP, ...

  2. python手写神经网络实现识别手写数字

    写在开头:这个实验和matlab手写神经网络实现识别手写数字一样. 实验说明 一直想自己写一个神经网络来实现手写数字的识别,而不是套用别人的框架.恰巧前几天,有幸从同学那拿到5000张已经贴好标签的手 ...

  3. 使用神经网络来识别手写数字【译】(三)- 用Python代码实现

    实现我们分类数字的网络 好,让我们使用随机梯度下降和 MNIST训练数据来写一个程序来学习怎样识别手写数字. 我们用Python (2.7) 来实现.只有 74 行代码!我们需要的第一个东西是 MNI ...

  4. matlab手写神经网络实现识别手写数字

    实验说明 一直想自己写一个神经网络来实现手写数字的识别,而不是套用别人的框架.恰巧前几天,有幸从同学那拿到5000张已经贴好标签的手写数字图片,于是我就尝试用matlab写一个网络. 实验数据:500 ...

  5. 【TensorFlow-windows】(四) CNN(卷积神经网络)进行手写数字识别(mnist)

    主要内容: 1.基于CNN的mnist手写数字识别(详细代码注释) 2.该实现中的函数总结 平台: 1.windows 10 64位 2.Anaconda3-4.2.0-Windows-x86_64. ...

  6. 6 TensorFlow实现cnn识别手写数字

    ------------------------------------ 写在开头:此文参照莫烦python教程(墙裂推荐!!!) ---------------------------------- ...

  7. keras—神经网络CNN—MNIST手写数字识别

    from keras.datasets import mnist from keras.utils import np_utils from plot_image_1 import plot_imag ...

  8. 第三节,TensorFlow 使用CNN实现手写数字识别(卷积函数tf.nn.convd介绍)

    上一节,我们已经讲解了使用全连接网络实现手写数字识别,其正确率大概能达到98%,这一节我们使用卷积神经网络来实现手写数字识别, 其准确率可以超过99%,程序主要包括以下几块内容 [1]: 导入数据,即 ...

  9. Android+TensorFlow+CNN+MNIST 手写数字识别实现

    Android+TensorFlow+CNN+MNIST 手写数字识别实现 SkySeraph 2018 Email:skyseraph00#163.com 更多精彩请直接访问SkySeraph个人站 ...

  10. C#中调用Matlab人工神经网络算法实现手写数字识别

    手写数字识别实现 设计技术参数:通过由数字构成的图像,自动实现几个不同数字的识别,设计识别方法,有较高的识别率 关键字:二值化  投影  矩阵  目标定位  Matlab 手写数字图像识别简介: 手写 ...

随机推荐

  1. linux命令详解之useradd命令使用方法[linux下 添加用户、删除用户、修改用户密码、用户组管理]

    http://www.jb51.net/article/45848.htm Linux 系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这 ...

  2. hibernate4.3.5,Final hibernate.cfg.xml的配置

    今天是接触hibernate的第二天,用来练习的是hibernate最新的版本hibernate-release-4.3.5.Final 要使用hibernate,则先要引入它的jar包,要引入的ja ...

  3. 好文推荐系列---------(4)使用Yeoman自动构建Ember项目

    好文原文地址:http://segmentfault.com/a/1190000000368881 我决定学习前端开发的效率工具Yeoman.本文将首先介绍Yeoman的基本情况,接着我们会使用Yeo ...

  4. ON_UPDATE_COMMAND_UI和ON_COMMAND有什么区别?

    区别如下: UPDATE_COMMAND_UI表示处理菜单对应的用户界面显示状态. COMMAND表示处理该菜单对应的功能. 传统SDK程序要改变选单命令项状态,可以呼叫EnableMenuItem或 ...

  5. 模板引擎(smarty)知识点总结四

    /*   smarty 引入对象 */ require_once 'libs/Smarty.class.php';  require 'MySmarty.class.php';  $msma = ne ...

  6. 6609 - Minimal Subarray Length

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  7. [ X.XX]CF每日一题系列线下更新中

    现在做的都好水啊,就不写博客了,线下有记录滴

  8. Python自动化开发 - Python操作MySQL

    本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy 一.pymysql pymsql是Python中操作MySQL的模块,其使用方法和mysq ...

  9. DXP常用有效的快捷操作记录

    1.在PCB中快速选中一个器件 1)  M+C+Enter将弹出元件对话框,移动一个元件后,在十字架光标 状态时按[Enter]键 2)M(Move)+M(Move)按下时,鼠标光标变成“+”后,点击 ...

  10. unigui的编译部署

    unigui的编译部署 unigui既可以EXE形态部署,也可以IIS的ISAPI的形态部署.关键在工程文件.dpr里面的编译开关. {$define UNIGUI_VCL} // 注释此编译开关将使 ...