0

我有一个关于阅读 MNIST 数据集的问题。我了解了如何构建 MNIST 数据集。但是,我不知道它是如何读取以下代码的。你们中的一些人可能认为 couts 的结果是显而易见的(我写了 values 作为评论)。但是对我来说这没有意义,因为它使用相同的输入四次使用相同的确切功能,但每次都会得到不同的输出。这怎么可能?如果我的问题有任何歧义,请告诉我。

谢谢你。

代码开始:

    typedef unsigned char BYTE;

int main()
{

...

FILE *fp = fopen("MNIST/train-images.idx3-ubyte", "rb");

    // delcare function;
    int magicNumber = readFlippedInteger(fp);
    int numImages = readFlippedInteger(fp);
    int numRows = readFlippedInteger(fp);
    int numCols = readFlippedInteger(fp);

    cout << magicNumber << endl;   // 2051
    cout << numImages << endl;     // 60000
    cout << numRows << endl;       // 28
    cout << numCols << endl;       // 28
...

}

int readFlippedInteger(FILE *fp)
{
    int ret = 0;

    BYTE *temp;

    temp = (BYTE*)(&ret);
    fread(&temp[3], sizeof(BYTE), 1, fp);
    fread(&temp[2], sizeof(BYTE), 1, fp);
    fread(&temp[1], sizeof(BYTE), 1, fp);
    fread(&temp[0], sizeof(BYTE), 1, fp);

    return ret;
}
4

1 回答 1

0

除非绝对必要,否则请不要混合使用 C 和 C++。潜在的混淆是调用fread“移动”文件指针通过文件为您。正如@RetiredNinja 指出的那样,您一次将文件指针推进4 个字节。这就是它“知道”如何读取下一个值的方式,即使您没有明确告诉它。您可以在此处阅读有关文件指针的所有信息。


使用稍微更惯用的 C++ 的实现可能是

#include <fstream>
#include <iostream>
#include <algorithm>

int readFlippedInteger(std::istream &in) {
    char temp[sizeof(int)];
    in.read(temp, sizeof(int));
    std::reverse(temp, temp+sizeof(int));
    return *reinterpret_cast<int*>(temp);
}

int main() {
    std::ifstream fin("MNIST/train-images.idx3-ubyte", std::ios::binary);

    if (!fin) {
        std::cerr << "Could not open file\n";
        return -1;
    }

    // delcare function;
    int magicNumber = readFlippedInteger(fin);
    int numImages = readFlippedInteger(fin);
    int numRows = readFlippedInteger(fin);
    int numCols = readFlippedInteger(fin);

    std::cout << magicNumber << std::endl // 2051
              << numImages << std::endl   // 60000
              << numRows << std::endl    // 28
              << numCols << std::endl;  // 28
}

使用用户定义的流操纵器的实现留给读者练习。

于 2016-07-10T05:37:02.320 回答