Python MNIST解析中硬编码值2051的含义及bytestream四次读取作用咨询
关于MNIST数据集读取代码的疑问解答
先把你贴的代码放在这里方便对照:
def _read32(bytestream): dt = np.dtype(np.uint32).newbyteorder('>') return np.frombuffer(bytestream.read(4), dtype=dt)[0] with open(extract_path, 'rb') as f: with gzip.GzipFile(fileobj=f) as bytestream: magic = _read32(bytestream) if magic != 2051: raise ValueError('Invalid magic number {} in file: {}'.format(magic, f.name)) num_images = _read32(bytestream) rows = _read32(bytestream) cols = _read32(bytestream) buf = bytestream.read(rows * cols * num_images) data = np.frombuffer(buf, dtype=np.uint8) data = data.reshape(num_images, rows, cols)
一、魔术值2051的含义
这个2051是MNIST数据集定义的文件类型标识,相当于一个“身份验证码”。MNIST的不同文件有专属的魔术值:
- 训练图像文件的魔术值就是2051
- 测试图像文件对应2052
- 训练标签文件是2049
- 测试标签文件是2050
代码里判断magic != 2051就报错,是为了确保你当前读取的确实是MNIST训练图像文件,避免误读成标签文件或者其他不相干的文件,保证后续数据解析的正确性。
二、四次调用_read32(bytestream)的作用
MNIST的二进制文件开头有固定的文件头结构,每个字段都是4字节的大端序无符号整数(这也是_read32函数的作用:读取4字节并转成大端格式的uint32),四次读取正好对应文件头的四个关键信息:
- 第一次读取:获取魔术值,完成文件类型的身份校验
- 第二次读取:获取
num_images,也就是当前文件包含的训练图像总数(MNIST训练集是60000张) - 第三次读取:获取
rows,每张图像的行数(MNIST图像是28x28规格,所以这里值为28) - 第四次读取:获取
cols,每张图像的列数(同样是28)
拿到这四个值之后,就能算出所有图像数据的总字节数(rows * cols * num_images),一次性读取所有图像数据后,再把一维的字节数组reshape成(num_images, rows, cols)的三维数组,也就是我们需要的训练图像数据格式。
内容的提问来源于stack exchange,提问作者M.Bonjour
相关产品推荐
相关产品推荐

