0

MNIST データセットの読み取りについて質問があります。MNIST データセットがどのように構築されているかを理解しました。ただし、次のコードをどのように読み取るのか、私にはわかりません。couts の結果は明らかだと思う人もいるかもしれません (コメントとして値を書きました)。しかし、同じ入力で同じ正確な関数を4回使用するため、私にとっては意味がありませんが、毎回異なる出力が得られます..どうすれば可能ですか? 私の質問にあいまいさがある場合はお知らせください。

ありがとうございました。

コード開始:

    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 に答える