在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目录,在该目录下,可以看到如下内容:
可以看到,我们成功地生成了黑底白字的数字图片。
如果仔细观察这些图片,会看到一些肉眼也难以分辨的数字,譬如:
上面这几个数字是2。想不到吧?
下面这两个是5(看起来更像6):
这个是7:(7长这样?有句MMP不知当讲不当讲)
猜猜下面这个是什么:
这是大写的L?不是。
有点像1,是1吗?也不是。
倒立拉粑的7?sorry,又猜错了。
实话告诉您,它是2!一开始我也是不相信的,知道真相的那一刻我下巴差点掉下来!
这些手写图片,一般人用肉眼观察,识别率能达到98%就不错了,但是通过TensorFlow搭建的卷积神经网络识别率可以达到99%,非常地神奇!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]