如何用python解析mnist

如何用python解析mnist,第1张

1.我们首先看一下mnist的数据结构:

2.

可以看出在train-images.idx3-ubyte中,第一个数为32位的整数(魔数,图片类型的数),第二个数为32位的整数(图片的个数),第三和第四个也是32为的整数(分别代表图片的行数和列数),接下来的都是一个字节的无符号数(即像素,值域为0~255),因此,盯模颂我们只需要依次获取魔数和图片的个数,然后获取图片的长和宽,最后逐个像素读取就可以了。

3.如何使用Python解析数据呢? 首先需要安装python的图形处理库PIL,这个库支持像素级别的图像处理,对于学习数字图像处理有很大的帮助。安装完成之后,就可以进行图像的解析了。看一下代码:

4.首先打开文件,然后分别读取魔数,图片个数,以及行数和列数,在struct中,可以看到,使用了’>IIII’,这是什么意思呢?意思就是使用大端规则,读取四个整形数(Integer),如果要读取一个字节,则可以用’>B’(当然,这里用没用大端规则都是一样的,因此只有两个或两个以上的字节才有用)。

5.什么是大端规则呢?不懂的可以百度一下,这个不再赘述(http://baike.baidu.com/link?url=Bgg8b0vRr3b_SeGyOl8U4DmAbIQT9swGuNtD_21ctEI_NliqsQ-mKF73YT90EILF2EQy50mEua_M4z6Cma3rmK)

6.然后对于每张图片,先创建一张空白的图片,其中的’L’代表这张图片是灰度图,最后逐个像素读取,凯郑然后写进空白图片里,最后保存图片,就可以了

7.再来看一下mnist标签的数据结构:

可以发现,与上面的非常相似,只不过这里每一个字节变成了标签而已(标签大小为0~9)

8.好了,通过上述讲解,最后我们可以通过python将mnist解析出来了,看一下效果:

程序源代码如下:

#!/usr/bin/env python

# -*- coding: utf-8 -*-

from PIL import Image

import struct

def read_image(filename):

f = open(filename, 'rb')

index = 0

buf = f.read()

f.close()

magic, images, rows, columns = struct.unpack_from('>IIII' , buf , index)

index += struct.calcsize('>IIII')

for i in xrange(images):

#for i in xrange(2000):

image = Image.new('L'码腔, (columns, rows))

for x in xrange(rows):

for y in xrange(columns):

image.putpixel((y, x), int(struct.unpack_from('>B', buf, index)[0]))

index += struct.calcsize('>B')

print 'save ' + str(i) + 'image'

image.save('test/' + str(i) + '.png')

def read_label(filename, saveFilename):

f = open(filename, 'rb')

index = 0

buf = f.read()

f.close()

magic, labels = struct.unpack_from('>II' , buf , index)

index += struct.calcsize('>II')

labelArr = [0] * labels

#labelArr = [0] * 2000

for x in xrange(labels):

#for x in xrange(2000):

labelArr[x] = int(struct.unpack_from('>B', buf, index)[0])

index += struct.calcsize('>B')

save = open(saveFilename, 'w')

save.write(','.join(map(lambda x: str(x), labelArr)))

save.write('\n')

save.close()

print 'save labels success'

if __name__ == '__main__':

read_image('t10k-images.idx3-ubyte')

read_label('t10k-labels.idx1-ubyte', 'test/label.txt')

其实就是python怎么读取binnary file

mnist的结构如下,选取train-images

TRAINING SET IMAGE FILE (train-images-idx3-ubyte):

[offset] [type] [value] [description]

0000 32 bit integer 0x00000803(2051) magic number

0004 32 bit integer 60000number 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

也就是之前我们要读取4个 32 bit integer

试过很多方法,觉得最方便的,至少对我来键野说还是使用

struct.unpack_from()

filename = 'train-images.idx3-ubyte'

binfile = open(filename , 'rb')

buf = binfile.read()

先使用二进制方式把文件都读进来

index = 0

magic, numImages , numRows , numColumns = struct.unpack_from('>IIII' , buf , index)

index += struct.calcsize('>IIII')

然后使用struc.unpack_from

'>IIII'是说使用大端法读取4个unsinged int32

然后读取一个图片测试是否读取成功

im = struct.unpack_from('稿戚喊>784B' ,buf, index)

index += struct.calcsize('>784B')

im = np.array(im)

im = im.reshape(28,28)

fig = plt.figure()

plotwindow = fig.add_subplot(111)

plt.imshow(im , cmap='gray')

plt.show()

'>784B'的意思就是用大端法读取784个unsigned byte

完整代码如下

import numpy as np

import struct

import matplotlib.pyplot as plt

filename = 'train-images.idx3-ubyte'

binfile = open(filename , 'rb')

buf = binfile.read()

index = 0

magic, numImages , numRows , numColumns = struct.unpack_from('>IIII' , buf , index)

index += struct.calcsize('>IIII')

im = struct.unpack_from('>784B' ,buf, index)

index += struct.calcsize('>784B')

im = np.array(im)

im = im.reshape(28,28)

fig = plt.figure()

plotwindow = fig.add_subplot(111)

plt.imshow(im , cmap='gray')

plt.show()

只是为了测试是否成功所以只读仔拆了一张图片


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/12226563.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-22
下一篇 2023-05-22

发表评论

登录后才能评论

评论列表(0条)

保存