有一个关于mnist的一个事例可以参考,我觉得写的很好:http://www.cnblogs.com/x1957/archive/2012/06/02/2531503.html
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import struct
# from bp import *
from datetime import datetime
# 数据加载器基类
class Loader(object):
    def __init__(self, path, count):
        '''
        初始化加载器
        path: 数据文件路径
        count: 文件中的样本个数
        '''
        self.path = path
        self.count = count
    def get_file_content(self):
        '''
        读取文件内容
        '''
        f = open(self.path, 'rb')
        content = f.read()
        print content[:20]
        f.close()
        return content
 
    def to_int(self,h):
        return struct.unpack('B',h)[0]
 
# 图像数据加载器
class ImageLoader(Loader):
    def get_picture(self, content, index):
        '''
        内部函数,从文件中获取图像
        '''
        start = index * 28 * 28 + 16
        picture = []
        # print(content[16])
        for i in range(28):
            picture.append([])
            for j in range(28):
                picture[i].append(
#在python2.7中,红色字体部分就是对的,但是在python3.x中,蓝色字体才是对的
                    self.to_int(content[start + i * 28 + j-1:start + i * 28 + j ]))
                    self.to_int(content[start + i * 28 + j]))
        return picture
    def get_one_sample(self, picture):
        '''
        内部函数,将图像转化为样本的输入向量
        '''
        sample = []
        for i in range(28):
            for j in range(28):
                sample.append(picture[i][j])
        return sample
    def load(self):
        '''
        加载数据文件,获得全部样本的输入向量
        '''
        content = self.get_file_content()
        data_set = []
        for index in range(self.count):
            data_set.append(
                self.get_one_sample(
                    self.get_picture(content, index)))
        return data_set
# 标签数据加载器
class LabelLoader(Loader):
    def load(self):
        '''
        加载数据文件,获得全部样本的标签向量
        '''
        content = self.get_file_content()
        # print content[:15]
        labels = []
        for index in range(self.count):
#在python2.7中,红色字体部分就是对的,但是在python3.x中,蓝色字体才是对的
            labels.append(self.norm(content[index + 7 :index + 8]))
            labels.append(self.norm(content[index + 8]))
        return labels
    def norm(self, label):
        '''
        内部函数,将一个值转换为10维标签向量
        '''
        label_vec = []
        # print('label is \n')
        # print(label[:20])
        label_value = self.to_int(label)
        for i in range(10):
            if i == label_value:
                label_vec.append(0.9)
            else:
                label_vec.append(0.1)
        return label_vec
def get_training_data_set():
    '''
    获得训练数据集
    '''
    filename1 = r'E:\workspace\pythonpaper\importment\dataset\train-images.idx3-ubyte'
    filename2 = r'E:\workspace\pythonpaper\importment\dataset\train-labels.idx1-ubyte'
    image_loader = ImageLoader(filename1, 60000)
    label_loader = LabelLoader(filename2, 60000)
    return image_loader.load(), label_loader.load()
def get_test_data_set():
    '''
    获得测试数据集
    '''
    filename3 = r'E:\workspace\pythonpaper\importment\dataset\t10k-images.idx3-ubyte'
    filename4 = r'E:\workspace\pythonpaper\importment\dataset\t10k-labels.idx1-ubyte'
    image_loader = ImageLoader(filename3, 10000)
    label_loader = LabelLoader(filename4, 10000)
    return image_loader.load(), label_loader.load()
 
def train_and_evaluate():
 
    train_data_set, train_labels = get_training_data_set()
    test_data_set, test_labels = get_test_data_set()
    # print '[dataset train:]\n'
    # print train_data_set[:10]
 
if __name__ == '__main__':
    train_and_evaluate()
 
1、mnist数据集格式的介绍 
上面的代码是我参考的一个教程上的例子,它本身是用python2.7实现的,但是,因为一些原因,我用的python3.5的环境,在实现这个代码的时候,出现了一些问题,为此,我也探究了一下。
mnist数据集是一个idx的文件格式,从网上下载下来的是四个压缩文件,两个训练样本的压缩文件,两个测试样本的压缩文件,在导入代码之前需要把它们解压缩,解压后的文件是以idx3-ubyte为后缀的idx的文件,这个文件是不能直接打开的,所以我们需要编写程序把它处理成我们需要的内容。
以mnist数据集的train-images-idx3-ubyte为例介绍

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
32bit是说这个数据书32位的,8位=1B(1个字节),因此,32位=4B=4byte,我们真正要读出来的是value这一列,但是0000-0015的数据不是我们需要的,第一个4B是magic的数量,第二个4B是这个文件包含多少个图像,第三个4B是说一个图像的有多少行,第四个4B是说一个图像有多少列,mnist的一个样本图像是28*28的。从0016开始,才是我们需要的图像内容,28*28=784,也就是我们需要784个B才能读取一个图像,在0016以下的的description上,写的是pixel,这是像素的意思,也就是说,一个像素就是一个1byte=1B,举例,用1B(一个字节)的二进制表示一个十进制的3,二进制就是0000 0011,用十六进制表示3,就是\x03,3的缩写是ETX。这样784个像素,784行就是一个图像样本了。
下面是mnist数据集的train-labels-idx1-ubyte文件的结构
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
train-labels-idx1-ubyte文件的结构的读法和train-images-idx3-ubyte相同,前8个字节不是label的内容,从0008开始才是一个label的内容,而且,通过观察这个表格的offset和description字段可以发现,一个字节是一个label。
 
 2、像素和二进制,十六进制的关系,以及python中print 的输出的不同
先说明一下二进制和十六进制和十进制的关系,以及它们的缩写的关系
ASCII控制字符
二进制 十进制 十六进制 缩写 可以显示的表示法 名称/意义
0000 0000 0 00 NUL 空字符(Null)
0000 0001 1 01 SOH 标题开始
0000 0010 2 02 STX 本文开始
0000 0011 3 03 ETX 本文结束
0000 0100 4 04 EOT 传输结束
0000 0101 5 05 ENQ 请求
0000 0110 6 06 ACK 确认回应
0000 0111 7 07 BEL 响铃
0000 1000 8 08 BS 退格
0000 1001 9 09 HT 水平定位符号
0000 1010 10 0A LF 换行键
0000 1011 11 0B VT 垂直定位符号
0000 1100 12 0C FF 换页键
 
从open(filepath,'rb')中读出来的是二进制的内容,print content[:5],显示content的前5个元素,一个元素就是一个像素,这样就有5个像素,而一个像素占一个二进制,一个二进制就是一个字节,一个字节就是一个十六进制。
 
有个小例子可以进一步说明一个int包含了4个字节,而一个字节是\x14这样的形式。
>>> a=20
>>> b=400
>>> t=struct.pack('ii',a,b)
>>> t
'\x14\x00\x00\x00\x90\x01\x00\x00'
>>> len(t)
8
>>> type(a)
<type 'int'>
a是int型的,pack('ii',a,b)中的'ii'是格式,一个i对应了一个int,有两个i,对应了两个int,一个int型的a,占了4个字节(\x14\x00\x00\x00),len输出的是一个字节\x14就是一个,所有有8个\x这样的,len(t)就是8个
 
3、struct的介绍
a=20,b=400
struct有三个方法,pack(fmt,val)方法是把val的数据按照fmt的格式转换为二进制数据, t=struct.pack('ii',a,b),把a,b转换为二进制形式'\x14\x00\x00\x00\x90\x01\x00\x00'
unpack(fmt,val)方法是把val按照fmt的格式把二进制数据转换为python可以读的数据,unpack('ii',a,b),把a,b转换为20,400
struct.unpack_from('>IIII' , buf , index)'>IIII'是说使用大端法从index的位置读取4个unsinged int32
 
4、python2.7和python3.5对mnist数据集的格式引发的问题
在python2.7中,content输出的是20个二进制的缩写,但是在python3.5中,print content[:20]输出的是20个十六进制。
在python2.7中,在struct.unpack('B',byte)中的content[start+i*28+j],就可以运行,但是在python3中,这里就需要写成[start+i*28+j -1:start+i*28+j ]才可以运行成功
 

mnist的格式说明,以及在python3.x和python 2.x读取mnist数据集的不同的更多相关文章

  1. [Python]基于CNN的MNIST手写数字识别

    目录 一.背景介绍 1.1 卷积神经网络 1.2 深度学习框架 1.3 MNIST 数据集 二.方法和原理 2.1 部署网络模型 (1)权重初始化 (2)卷积和池化 (3)搭建卷积层1 (4)搭建卷积 ...

  2. python读取mnist

    python读取mnist 其实就是python怎么读取binnary file mnist的结构如下,选取train-images TRAINING SET IMAGE FILE (train-im ...

  3. 选择 Python3.6 还是 Python 3.7

    转自:白月黑羽在线教程:http://www.python3.vip/doc/blog/python/home/ 选择 Python3.6 还是 Python 3.7 Python 3.7 已经发布了 ...

  4. Python3.x:python: extend (扩展) 与 append (追加) 的区别

    Python3.x:python: extend (扩展) 与 append (追加) 的区别 1,区别: append() 方法向列表的尾部添加一个新的元素.只接受一个参数: extend()方法只 ...

  5. C++基于文件流和armadillo读取mnist

    发现网上大把都是用python读取mnist的,用C++大都是用opencv读取的,但我不怎么用opencv,因此自己摸索了个使用文件流读取mnist的方法,armadillo仅作为储存矩阵的一种方式 ...

  6. Python3 中codecs进行文件的读取

    简单的概念与说明 编码(动词):按照某种规则(这个规则称为:编码(名词))将"文本"转换为"字节流".而在python 3中则表示:unicode变成str 解 ...

  7. Python读取MNIST数据集

    MNIST数据集获取 MNIST数据集是入门机器学习/模式识别的最经典数据集之一.最早于1998年Yan Lecun在论文: Gradient-based learning applied to do ...

  8. 【Python3学习】Python环境搭建

    以前电脑上安装过一个python2的环境,这次由于项目跟其他团队人员对的时候,人家的是python3,因为python2也没怎么学,所以对里面还是很不了解的. 所以今天就重新开始python3的学习, ...

  9. Dataset:利用Python将已有mnist数据集通过移动像素上下左右的方法来扩大数据集为初始数据集的5倍—Jason niu

    from __future__ import print_function import cPickle import gzip import os.path import random import ...

随机推荐

  1. spring boot读取classpath下的json文件

    import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resour ...

  2. Asp.Net Core MongoDB

    废话不说直接上代码: using MongoDB.Bson.Serialization.Attributes; namespace XL.Core.MongoDB { public interface ...

  3. java static关键字的使用

    static关键字    通常来说,创建类的时候,是用new创建此类的对象才可以获得,执行new创建对象时数据存储空间才被分配,其方法才被外界调用    有两种情况用new无法解决:        1 ...

  4. 【C#】await & Result DeadLock

    随意使用异步的await和Result,被弄得欲仙欲死,然后看了 Don't Block on Async Code,稍许明白,翻译然后加上自己的理解以加深印象. 会死锁的两个例子 UI例子 publ ...

  5. oracle 同义词synonym

    在A用户下,想访问B用户下的表,一遍需要用 “用户名.表名 ”的格式进行访问.如果想不加用户名,直接访问,需要建同义词. 同义词语法如下: CREATE [PUBLIC] SYNONYM synony ...

  6. springboot +redis配置

    springboot +redis配置 pom依赖 <dependency> <groupId>org.springframework.boot</groupId> ...

  7. windows平台python svn模块的一个小 bug

    环境 编程语言版本:python 2.7 操作系统:win10 64位 模块名:svn svn  checkout时报错 File "D:\Python27\lib\site-package ...

  8. python学习-迭代器,列表解析和列表生成式

    迭代器为类序列对象提供了一个类序列的接口.Python 的迭代无缝的支持序列对象,而且还允许程序猿迭代非序列类型,包括用户定义的对象. 迭代器是一个next()方法的对象,而不是通过索引计数.当需要下 ...

  9. centos6.5卸载及安装git

    一.卸载原有的git 用whereis git命令来检查是否已经安装了git版本的 再使用命令:yum remove git卸载git 二.安装git (一)官网下载:https://mirrors. ...

  10. WEB学习笔记7-样式与结构分离

    CSS样式应用于HTML总共4种样式: (1)在HTML页面中链接一个CSS文件 文件以link形式添加到<head>部分,在link中可以设置media属性来表明样式使用的场景.例如,m ...