python3 mnist数据集解析、可视化展示、保存图片(格式和解析方法详细讲解)

mnist数据集介绍

  mnist数据集是比较流行的手写数字数据集之一,其中有60000个训练数据集,10000个测试数据集;

mnist数据集文件列表:

  • train-images-idx3-ubyte: 训练集图片 – 已全部转为二进制数组
  • train-labels-idx1-ubyte: 训练集标签
  • t10k-images-idx3-ubyte: 测试集图片
  • t10k-labels-idx1-ubyte: 测试机标签

mnist数据文件格式

mnist标签文件格式:

train-labels-idx1-ubyte和t10k-labels-idx1-ubyte文件格式一样,标签值为0-9的数字

[偏移量]        [数据类型]          [数据值]          [数据描述]
0000     32 bit integer  0x00000801(2049) 魔数
0004     32 bit integer  60000            标签数
0008     unsigned byte   ??               标签值
0009     unsigned byte   ??               标签值
........
xxxx     unsigned byte   ??               标签值

mnist图像文件格式:

train-images-idx3-ubyte和t10k-images-idx3-ubyte格式一样,像素值为0-255的数字,其中0代表白色,255代表黑色

[偏移量]        [数据类型]          [数据值]          [数据描述]
0000     32 bit integer  0x00000803(2051)  魔数
0004     32 bit integer  60000            图片数量
0008     32 bit integer  28               单个图片行数
0012     32 bit integer  28               单个图片列数
0016     unsigned byte   ??               像素值
0017     unsigned byte   ??               像素值
........
xxxx     unsigned byte   ??               像素值

图像表现形式

每一张图片为28*28数组,mnist中图像和数组的对应关系如下:
python3 mnist数据集解析、可视化展示、保存图片(格式和解析方法详细讲解)_第1张图片

python3解析mnist数据集

# 导入包
import struct
import numpy as np
from PIL import Image

class MnistParser:

   #
   # TRAINING SET IMAGE FILE (train-images-idx3-ubyte):
   # [offset] [type]          [value]          [description]
   # 0000     32 bit integer  0x00000803(2051) magic number
   # 0004     32 bit integer  60000            number of images
   # 0008     32 bit integer  28               number of rows
   # 0012     32 bit integer  28               number of columns
   # 0016     unsigned byte   ??               pixel
   # 0017     unsigned byte   ??               pixel
   # ........
   # xxxx     unsigned byte   ??               pixel
   # Pixels are organized row-wise. Pixel values are 0 to 255. 0 means background (white), 255 means foreground (black).
   # 加载图像
   def load_image(file_path):

       # 读取二进制数据
       binary = open(file_path,'rb').read()

       # 读取头文件
       fmt_head = '>iiii'
       offset = 0

       # 读取头文件
       magic_number,images_number,rows_number,columns_number = struct.unpack_from(fmt_head,binary,offset)

       # 打印头文件信息
       print('魔数:%d,图片数量:%d,图片行数:%d,图片列数:%d'%(magic_number,images_number,rows_number,columns_number))

       # 处理数据
       image_size = rows_number * columns_number
       fmt_data = '>'+str(image_size)+'B'
       offset = offset + struct.calcsize(fmt_head)

       # 读取数据
       images = np.empty((images_number,rows_number,columns_number))
       for i in range(images_number):
           # images[i] = np.array(struct.unpack_from(fmt_data,binary,offset)).reshape((rows_number,columns_number))
           images[i] = np.array(struct.unpack_from(fmt_data, binary, offset)).reshape((rows_number, columns_number))
           # images[i] = np.array(struct.unpack_from(fmt_data,binary,offset)).reshape((num_rows, num_cols))
           offset = offset + struct.calcsize(fmt_data)
           # 每1万张打印一次信息
           if (i+1)%10000 == 0:
               print('> 已读取:%d张图片'%(i+1))

       # 返回数据
       return magic_number,images_number,rows_number,columns_number,images

   # TRAINING SET LABEL FILE (train-labels-idx1-ubyte):
   # [offset] [type]          [value]          [description]
   # 0000     32 bit integer  0x00000801(2049) magic number (MSB first)
   # 0004     32 bit integer  60000            number of items
   # 0008     unsigned byte   ??               label
   # 0009     unsigned byte   ??               label
   # ........
   # xxxx     unsigned byte   ??               label
   # The labels values are 0 to 9.

   # 加载标签
   def load_labels(file_path):
       # 读取数据
       binary = open(file_path,'rb').read()

       # 读取头文件
       fmt_head = '>ii'
       offset = 0

       # 读取头文件
       magic_number,items_number = struct.unpack_from(fmt_head,binary,offset)

       # 打印头文件信息
       print('魔数:%d,标签数:%d'%(magic_number,items_number))

       # 处理数据
       fmt_data = '>B'
       offset = offset + struct.calcsize(fmt_head)

       # 读取数据
       labels = np.empty((items_number))
       for i in range(items_number):
           # images[i] = np.array(struct.unpack_from(fmt_data,binary,offset)).reshape((rows_number,columns_number))
           labels[i] = struct.unpack_from(fmt_data, binary, offset)[0]
           # images[i] = np.array(struct.unpack_from(fmt_data,binary,offset)).reshape((num_rows, num_cols))
           offset = offset + struct.calcsize(fmt_data)
           # 每1万张打印一次信息
           if (i+1)%10000 == 0:
               print('> 已读取:%d个标签'%(i+1))

       # 返回数据
       return magic_number,items_number,labels





   # 图片可视化
   def visualaztion(images,labels,is_save):
       for i in range(images.__len__()):
           im = Image.fromarray(images[i])
           if is_save == True:
               im.save("mnist/images/%s.jpeg"%(labels[i]))
           im.show()




   # 测试数据
   if __name__ == '__main__':
       trainImageFile = 'mnist/train-images-idx3-ubyte'
       magic_number_images,images_number,rows_number,columns_number,images = load_image(trainImageFile)

       # 读取标签
       trainLabelFile = 'mnist/train-labels-idx1-ubyte'
       magic_number_labels,items_number,labels = load_labels(trainLabelFile)

       # 图片显示
       visualaztion(images[0:5],labels[0:5],False)

效果测试

魔数:2051,图片数量:60000,图片行数:28,图片列数:28
已读取:10000张图片
已读取:20000张图片
已读取:30000张图片
已读取:40000张图片
已读取:50000张图片
已读取:60000张图片
魔数:2049,标签数:60000
已读取:10000个标签
已读取:20000个标签
已读取:30000个标签
已读取:40000个标签
已读取:50000个标签
已读取:60000个标签

python3 mnist数据集解析、可视化展示、保存图片(格式和解析方法详细讲解)_第2张图片

你可能感兴趣的:(数据分析与算法模型)