我最近需要转换 mnist图像和标签的数据集,它是二进制的,结构在前面的链接中,所以我做了一些研究,因为我是 c++ 的粉丝,我已经阅读了 I/O binary in c++ ,之后我找到了this link在堆栈中。该链接运行良好,但没有代码注释,也没有算法解释,所以我很困惑,这在我脑海中提出了一些问题,我需要专业的 C++ 程序员来问。
1-在 C++ 中借助 ifstream 转换数据集的算法是什么?
我已经意识到可以使用 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 位整数
,并将其放入一个整数变量。
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 和 2 的倍数是 255 但为什么呢?
附言:
1-我已经有了 MNIST 转换后的图像,但我想了解算法。
2-我已经解压缩了 gz 文件,所以该文件是纯二进制文件。
最佳答案
1-What is the algorithm to convert the data-set in c++ with help of ifstream?
这个函数读取一个文件(t10k-images-idx3-ubyte.gz
)如下:
- 读取魔数(Magic Number)并调整字节顺序
- 读取图片数量并调整字节顺序
- 读取数字行并调整字节顺序
- 读取列数并调整字节顺序
- 读取所有给定的图像 x 行 x 列字符(但放散它们)。
该函数使用普通的 int
并始终切换字节顺序,这意味着它针对非常特定的体系结构并且不可移植。
How can we go to the specific offset for example 0004 and read for example 32 bit integer and put it to an integer variable.
ifstream
提供了一个寻找给定位置的函数:
file.seekg( posInBytes, std::ios_base::beg);
在给定的位置,你可以读取到 32 位整数:
int32_t val;
file.read ((char*)&val,sizeof(int32_t));
2- What the function
reverseInt
is doing?
此函数反转 int
值的字节顺序:
考虑像 aaaaaaaabbbbbbbbccccccccdddddddd
这样的 32 位整数,它返回整数 ddddddddccccccccbbbbbbbbaaaaaaaa
。
这对于标准化字节顺序很有用,但是,它可能不是很便携,因为 int
可能不是 32 位(但例如 16 位或 64 位)
关于c++ - 如何理解 C++ 中的 MNIST 二进制转换器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42945285/