【C/C++】MNISTの手書き数字の画像/ラベルデータをサクっと読み込む
機械学習で定番の数字認識では、サンプルデータとしてMNISTの手書き数字画像を使用する事が多いですね。PythonではMNIST画像を読み書きするライブラリがあるため手間いらずですが、C/C++では自力で読み書きする必要があるため、サンプルを紹介します。
なお、MNIST画像データの詳細な仕様は下記ブログが参考になります。
MNIST データの仕様を理解しよう
#define MNIST_TRAINING_IMG_PATH "train-images-idx3-ubyte" #define MNIST_TRAINING_LABEL_PATH "train-labels-idx1-ubyte" #define MNIST_TRANING_IMG_CNT (60000) // MNISTの教師画像/ラベルを開く FILE *fpImg = fopen(MNIST_TRAINING_IMG_PATH, "rb"); FILE *fpLabel = fopen(MNIST_TRAINING_LABEL_PATH, "rb"); if(!fpImg || !fpLabel){ printf("Mnist Load Err\n"); return -1; } // 教師データの読み込み for(int iCnt = 0; iCnt < MNIST_TRANING_IMG_CNT; iCnt++){ // 画像データ読み込み(16バイト目から開始) unsigned char szImg[MNIST_IMG_SIZE]; fseek(fpImg, 16 + iCnt * MNIST_IMG_SIZE, SEEK_SET); fread(szImg, sizeof(char), MNIST_IMG_SIZE, fpImg); // ラベルデータ読み込み(8バイト目から開始) char cLabel; fseek(fpLabel, 8 + iCnt, SEEK_SET); fread(&cLabel, sizeof(char), sizeof(char), fpLabel); // TODO:学習処理 } // ファイルを閉じる fclose(fpImg); fclose(fpLabel);
for文内で1データ毎に画像とラベルをszImgとcLabelに読み込んでいます。
szImgは0-255の生の値のため必要に応じて0-1.0に正規化して下さい。
なお、画像の幅/高さやデータ数の情報は固定情報なので、ファイルからロードせずに定数定義としています。