如何理解c ++中的MNIST二进制转换器?

时间:2017-03-22 07:28:54

标签: c++ c algorithm

我最近需要将mnist数据集转换为图片和标签,它是二进制的,结构在上一个链接中,所以我做了一些研究,因为我做了c ++的粉丝,我已经阅读了I/O binary in c++,之后我在堆栈中找到了this link。这个链接运行良好,但没有代码注释,也没有算法解释,所以我感到困惑,在我的脑海里提出了一些问题,我需要一个专业的c ++程序员来问。

1 - 在ifstream的帮助下,用c ++转换数据集的算法是什么?

我已经意识到将文件作为带有file.read的二进制文件读取并移动到下一条记录,但在C中,我们定义了一个结构并将其移动到文件中但我不能例如,请参阅c ++程序中的任何结构来阅读:

[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

我们如何转到示例0004的特定偏移量并读取示例32 bit integer并将其放入整数变量。

2 - reverseInt的功能是什么? (显然不是简单地反转整数)

int ReverseInt (int i)
{
    unsigned char ch1, ch2, ch3, ch4;
    ch1 = i & 255;
    ch2 = (i >> 8) & 255;
    ch3 = (i >> 16) & 255;
    ch4 = (i >> 24) & 255;
    return((int) ch1 << 24) + ((int)ch2 << 16) + ((int)ch3 << 8) + ch4;
}

我已经对cout进行了一些调试,当它修改为例如270991360时,它返回10000,我找不到任何关系,我理解它和数字倍数为2 255但为什么呢?

PS:

1 - 我已经有MNIST转换的图像,但我想了解算法。

2-I我已经解压缩了gz文件,因此该文件是纯二进制文件。

1 个答案:

答案 0 :(得分:0)

  

1 - 在ifstream的帮助下,用c ++转换数据集的算法是什么?

此函数读取文件(t10k-images-idx3-ubyte.gz),如下所示:

  • 读取幻数并调整字节顺序
  • 读取图像数量并调整字节顺序
  • 读取数字行并调整字节顺序
  • 读取列数并调整字节顺序
  • 读取所有给定的图像x行x列字符(但松散它们)。

该函数使用普通int并始终切换字节序,这意味着它针对非常特定的架构而且不可移植。

  

我们如何转到示例0004的特定偏移量并读取例如32位整数并将其放入整数变量。

ifstream提供了寻找特定位置的功能:

file.seekg( posInBytes, std::ios_base::beg);

在给定位置,您可以读取32位整数:

int32_t val;
file.read ((char*)&val,sizeof(int32_t));
  

2- reverseInt函数正在做什么?

此函数与int值的字节的反向顺序:

考虑像aaaaaaaabbbbbbbbccccccccdddddddd这样的32位整数,它返回整数ddddddddccccccccbbbbbbbbaaaaaaaa

这对于标准化字节顺序很有用,但它可能不是很便携,因为int可能不是32位(但例如16位或64位)