为什么 Python MNIST 解析器硬编码值“2051”?

Why does the Python MNIST parser hardcode the value "2051"?

变量extract_path是一个mnist训练文件,然后我使用gzip模块从该文件中提取数据,令我困惑的是变量magic的值可能是2051, 2051 意味着什么?

第二个问题,变量bytestream,它读了四次,我不知道它做了什么?


    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)

任何帮助表示赞赏。

这与gzipPython无关。它是 MNIST 数据库中训练集图像文件的文件格式规范的一部分。

来自http://yann.lecun.com/exdb/mnist/

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

因此,值2051用于区分训练集图像文件与其他文件类型(例如标签文件,使用幻数2049)。

与此相对应的是,magic number后面多了三个4-byte / 32-bit的值,表示图像的数量、行数和列数;随后的 _read32() 调用因此使用该数据,将值分别放入变量 num_imagesrowscols

在此上下文中使用 "magic numbers" 与文件格式上下文中 "magic numbers" 的一般含义一致,其中这些是 libmagic 使用的常量(工具file 实用程序用来猜测文件类型)。对于新开发的格式,更好的做法是使用正确的 UUID 而不是短整数,后者更有可能是偶然发生的。