详解如何从TensorFlow的mnist数据集导出手写体数字图片


Posted in Python onAugust 05, 2019

在TensorFlow的官方入门课程中,多次用到mnist数据集。

mnist数据集是一个数字手写体图片库,但它的存储格式并非常见的图片格式,所有的图片都集中保存在四个扩展名为idx3-ubyte的二进制文件。

如果我们想要知道大名鼎鼎的mnist手写体数字都长什么样子,就需要从mnist数据集中导出手写体数字图片。了解这些手写体的总体形状,也有助于加深我们对TensorFlow入门课程的理解。

下面先给出通过TensorFlow api接口导出mnist手写体数字图片的python代码,再对代码进行分析。代码在win7下测试通过,linux环境也可以参考本处代码。

(非常良心的注释和打印有木有)

#!/usr/bin/python3.5
# -*- coding: utf-8 -*-
 
import os
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
 
from PIL import Image
 
# 声明图片宽高
rows = 28
cols = 28
 
# 要提取的图片数量
images_to_extract = 8000
 
# 当前路径下的保存目录
save_dir = "./mnist_digits_images"
 
# 读入mnist数据
mnist = input_data.read_data_sets("MNIST_data/", one_hot=False)
 
# 创建会话
sess = tf.Session()
 
# 获取图片总数
shape = sess.run(tf.shape(mnist.train.images))
images_count = shape[0]
pixels_per_image = shape[1]
 
# 获取标签总数
shape = sess.run(tf.shape(mnist.train.labels))
labels_count = shape[0]
 
# mnist.train.labels是一个二维张量,为便于后续生成数字图片目录名,有必要一维化(后来发现只要把数据集的one_hot属性设为False,mnist.train.labels本身就是一维)
#labels = sess.run(tf.argmax(mnist.train.labels, 1))
labels = mnist.train.labels
 
# 检查数据集是否符合预期格式
if (images_count == labels_count) and (shape.size == 1):
  print ("数据集总共包含 %s 张图片,和 %s 个标签" % (images_count, labels_count))
  print ("每张图片包含 %s 个像素" % (pixels_per_image))
  print ("数据类型:%s" % (mnist.train.images.dtype))
 
  # mnist图像数据的数值范围是[0,1],需要扩展到[0,255],以便于人眼观看
  if mnist.train.images.dtype == "float32":
    print ("准备将数据类型从[0,1]转为binary[0,255]...")
    for i in range(0,images_to_extract):
      for n in range(pixels_per_image):
        if mnist.train.images[i][n] != 0:
          mnist.train.images[i][n] = 255
      # 由于数据集图片数量庞大,转换可能要花不少时间,有必要打印转换进度
      if ((i+1)%50) == 0:
        print ("图像浮点数值扩展进度:已转换 %s 张,共需转换 %s 张" % (i+1, images_to_extract))
 
  # 创建数字图片的保存目录
  for i in range(10):
    dir = "%s/%s/" % (save_dir,i)
    if not os.path.exists(dir):
      print ("目录 ""%s"" 不存在!自动创建该目录..." % dir)
      os.makedirs(dir)
 
  # 通过python图片处理库,生成图片
  indices = [0 for x in range(0, 10)]
  for i in range(0,images_to_extract):
    img = Image.new("L",(cols,rows))
    for m in range(rows):
      for n in range(cols):
        img.putpixel((n,m), int(mnist.train.images[i][n+m*cols]))
    # 根据图片所代表的数字label生成对应的保存路径
    digit = labels[i]
    path = "%s/%s/%s.bmp" % (save_dir, labels[i], indices[digit])
    indices[digit] += 1
    img.save(path)
    # 由于数据集图片数量庞大,保存过程可能要花不少时间,有必要打印保存进度
    if ((i+1)%50) == 0:
      print ("图片保存进度:已保存 %s 张,共需保存 %s 张" % (i+1, images_to_extract))
  
else:
  print ("图片数量和标签数量不一致!")

上述代码的实现思路如下:

1.读入mnist手写体数据;

2.把数据的值从[0,1]浮点范围转化为黑白格式(背景为0-黑色,前景为255-白色);

3.根据mnist.train.labels的内容,生成数字索引,也就是建立每一张图片和其所代表数字的关联,由此创建对应的保存目录;

4.循环遍历mnist.train.images,把每张图片的像素数据赋值给python图片处理库PIL的Image类实例,再调用Image类的save方法把图片保存在第3步骤中创建的对应目录。

在运行上述代码之前,你需要确保本地已经安装python的图片处理库PIL,pip安装命令如下:

pip3 install Pillow

或 pip install Pillow,取决于你的pip版本。

上述python代码运行后,在当前目录下会生成mnist_digits_images目录,在该目录下,可以看到如下内容:

详解如何从TensorFlow的mnist数据集导出手写体数字图片

可以看到,我们成功地生成了黑底白字的数字图片。

如果仔细观察这些图片,会看到一些肉眼也难以分辨的数字,譬如:

详解如何从TensorFlow的mnist数据集导出手写体数字图片

详解如何从TensorFlow的mnist数据集导出手写体数字图片

上面这几个数字是2。想不到吧?

下面这两个是5(看起来更像6):

详解如何从TensorFlow的mnist数据集导出手写体数字图片详解如何从TensorFlow的mnist数据集导出手写体数字图片

这个是7:(7长这样?有句MMP不知当讲不当讲)

详解如何从TensorFlow的mnist数据集导出手写体数字图片

猜猜下面这个是什么:

详解如何从TensorFlow的mnist数据集导出手写体数字图片

这是大写的L?不是。

有点像1,是1吗?也不是。

倒立拉粑的7?sorry,又猜错了。

实话告诉您,它是2!一开始我也是不相信的,知道真相的那一刻我下巴差点掉下来!

这些手写图片,一般人用肉眼观察,识别率能达到98%就不错了,但是通过TensorFlow搭建的卷积神经网络识别率可以达到99%,非常地神奇!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中的urllib模块使用详解
Jul 07 Python
使用Python来开发微信功能
Jun 13 Python
Python类和对象的定义与实际应用案例分析
Dec 27 Python
python调用c++传递数组的实例
Feb 13 Python
Flask框架工厂函数用法实例分析
May 25 Python
python实现按关键字筛选日志文件
Dec 24 Python
python中使用input()函数获取用户输入值方式
May 03 Python
tensorflow模型转ncnn的操作方式
May 25 Python
python/golang 删除链表中的元素
Sep 14 Python
python3代码中实现加法重载的实例
Dec 03 Python
Pandas对每个分组应用apply函数的实现
Dec 13 Python
Python+Pillow+Pytesseract实现验证码识别
May 11 Python
Python获取时间范围内日期列表和周列表的函数
Aug 05 #Python
Django ORM 查询管理器源码解析
Aug 05 #Python
python实现车牌识别的示例代码
Aug 05 #Python
使用python实现滑动验证码功能
Aug 05 #Python
Django 源码WSGI剖析过程详解
Aug 05 #Python
Python使用itchat 功能分析微信好友性别和位置
Aug 05 #Python
Python队列RabbitMQ 使用方法实例记录
Aug 05 #Python
You might like
PHP mkdir()定义和用法
2009/01/14 PHP
解读PHP中的垃圾回收机制
2015/08/10 PHP
PHP-FPM 的管理和配置详解
2019/02/17 PHP
JQuery之拖拽插件实现代码
2011/04/14 Javascript
js中的异常处理try...catch使用介绍
2013/09/21 Javascript
JS如何判断移动端访问设备并解析对应CSS
2013/11/27 Javascript
用js动态添加html元素,以及属性的简单实例
2016/07/19 Javascript
利用JavaScript判断浏览器类型及版本
2016/08/23 Javascript
AngularJS的依赖注入实例分析(使用module和injector)
2017/01/19 Javascript
提高JavaScript执行效率的23个实用技巧
2017/03/01 Javascript
nodejs模块nodemailer基本使用-邮件发送示例(支持附件)
2017/03/28 NodeJs
Angular2环境搭建具体操作步骤(推荐)
2017/08/04 Javascript
Vue组件之Tooltip的示例代码
2017/10/18 Javascript
利用ECharts.js画K线图的方法示例
2018/01/10 Javascript
JS中判断某个字符串是否包含另一个字符串的五种方法
2018/05/03 Javascript
基于jQuery ztree实现表格风格的树状结构
2018/08/31 jQuery
[01:00:11]DOTA2-DPC中国联赛 正赛 CDEC vs DLG BO3 第一场 2月7日
2021/03/11 DOTA
简析Python的闭包和装饰器
2016/02/26 Python
python/sympy求解矩阵方程的方法
2018/11/08 Python
pandas读取csv文件,分隔符参数sep的实例
2018/12/12 Python
Python简单获取二维数组行列数的方法示例
2018/12/21 Python
python实现tail -f 功能
2020/01/17 Python
Python抓新型冠状病毒肺炎疫情数据并绘制全国疫情分布的代码实例
2020/02/05 Python
python中if及if-else如何使用
2020/06/02 Python
Python如何把字典写入到CSV文件的方法示例
2020/08/23 Python
2020版Python学习路线图(附学习资料)
2020/09/15 Python
PyQt5的QWebEngineView使用示例
2020/10/20 Python
css3 旋转按钮 使用CSS3创建一个旋转可变色按钮
2012/12/31 HTML / CSS
Sql面试题
2013/03/20 面试题
教师专业理论水平的自我评价分享
2013/11/09 职场文书
作风建设整改方案
2014/10/27 职场文书
外国人来华邀请函
2015/01/31 职场文书
给病人的慰问信
2015/03/23 职场文书
2015年项目经理工作总结
2015/04/30 职场文书
Vue详细的入门笔记
2021/05/10 Vue.js
解决vue-router的beforeRouteUpdate不能触发
2022/04/14 Vue.js