2016-07-10 8 views
0

Ich habe eine Frage zum Lesen von MNIST-Datensätzen. Ich habe die Idee, wie der MNIST-Datensatz aufgebaut ist. Ich habe jedoch keine Ahnung, wie es durch einen folgenden Code gelesen wird. Einige von euch denken vielleicht, dass das Ergebnis von Couts offensichtlich ist (ich habe Werte als Kommentar geschrieben). Aber für mich ergibt das keinen Sinn, da es die gleiche genaue Funktion viermal mit der gleichen Eingabe verwendet, aber es bekommt jedes Mal die unterschiedliche Ausgabe. Wie ist das möglich? Bitte lassen Sie es mich wissen, wenn meine Frage zweideutig ist.Wie wird die Mnist-Datei durch den folgenden Code gelesen?

Vielen Dank.

-Code starten:

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; 
} 
+1

'readFlippedInteger' liest bei jedem Aufruf 4 Bytes aus der Datei. –

Antwort

0

Bitte nicht mischen C und C++, wenn es absolut notwendig ist. Die zugrunde liegende Verwirrung besteht darin, dass der Aufruf von fread den Dateizeiger für Sie durch die Datei "verschiebt". Wie Sie @RetiredNinja notiert haben, schieben Sie den Dateizeiger um 4 Bytes gleichzeitig vor. So "weiß" es, wie man den nächsten Wert liest, obwohl du es nicht explizit gesagt hast. Sie können alles über Dateizeiger lesen .


Eine Implementierung etwas idiomatische C++ verwendet, könnte sein

#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 
} 

Eine Implementierung, die einen benutzerdefinierten Strom Manipulator verwendet wird für den Leser als Übung.

+0

Danke Tim! Ich wusste nicht einmal, dass ich C und C++ mischte. Da ich den Großteil des Codes aus verschiedenen Projekten kopiere, habe ich wirklich Schwierigkeiten, irgendwann zu verstehen. Dieser Link ist wirklich hilfreich! Danke vielmals. –

Verwandte Themen