我最近需要将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文件,因此该文件是纯二进制文件。
答案 0 :(得分:0)
1 - 在ifstream的帮助下,用c ++转换数据集的算法是什么?
此函数读取文件(t10k-images-idx3-ubyte.gz
),如下所示:
该函数使用普通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位)