C+++ファイルフローに基づいて、armadilloとmnistを読み出す例を詳しく説明する。


前言
ネット上の大柄は全部pythonでmnistを読み取っています。C++を使ってほとんどopencvで読み取っていますが、opencvはあまり使わないので、自分でファイルフローを使ってmnistを読み取る方法を模索しました。armadilloはストレージマトリックスとしての一つの方法だけです。
1.mnistファイル
まずピットを避けて、これらの書類は解凍します。

公式サイトのスクリーンショットによると、ファイルヘッドは簡単で、いくつかの32ビットの整数しかなく、MSB、ピクセルとラベルは符号なしバイト(すなわちunsigned char)であり、先にファイルヘッダを読み取り、残りの部分を読み取ることができます。
2.ファイルヘッダの読み込み
必要はないと思いますが、直接飛ばしてはいけませんか?
書類のヘッダは全部32位です。それなら4つのunsigned charを整えます。

 uchar a, b, c, d;
 File >> a >> b >> c >> d;
このようにa、b、c、dは1つの整数を保存しました。

x = ((((a * 256) + b) * 256) + c) * 256 + d;
そして手に入れますよ。
ファイルごとにどれぐらいのファイルヘッドがあるかを見て、何回操作しますか?残りはファイルの内容です。
3.内容を読み取る
この部分は前の方法で一度に文字を読み、マトリックスに保存することができます。たとえば:

uchar a;
mat image(28, 28, fill::zeros); //      !
for(int i = 0; i < 28; i++) //28 28        
 for(int j = 0; j < 28; j++)
 {
  File >> a;
  image(i, j) = double(a);
 }
これで一枚の写真を読みました。あとはこれを類推しましょう。
4.完全コード
コピーもできますし、修正もできます。商用や学術にも使えます。
mnist.h

#ifndef MNIST_H  
#define MNIST_H
#include<iostream>
#include<fstream>
#include<armadillo>

#define uchar unsigned char

using namespace std;
using namespace arma;

//      
int reverseInt(uchar a, uchar b, uchar c, uchar d);

//  image     
mat read_mnist_image(const string fileName);

//  label     
mat read_mnist_label(const string fileName);
#endif

mnist.cpp

//mnist.cpp
//  :C 
#include "mnist.h"

int reverseInt(uchar a, uchar b, uchar c, uchar d)
{
 return ((((a * 256) + b) * 256) + c) * 256 + d;
}

mat read_mnist_image(const string fileName)
{
 fstream File;
 mat image;
 File.open(fileName);
 if (!File.is_open()) // cannot open file
 {
  cout << "      " << endl;
  return mat(0, 0, fill::zeros);
 }
 uchar a, b, c, d;
 File >> a >> b >> c >> d;
 int magic = reverseInt(a, b, c, d);
 if (magic != 2051) //magic number wrong
 {
  cout << magic;
  return mat(0, 0, fill::zeros);
 }
 File >> a >> b >> c >> d;
 int num_img = reverseInt(a, b, c, d);
 File >> a >> b >> c >> d;
 int num_row = reverseInt(a, b, c, d);
 File >> a >> b >> c >> d;
 int num_col = reverseInt(a, b, c, d);
 //        
 image = mat(num_img, num_col * num_row, fill::zeros);
 for(int i = 0; i < num_img; i++)
  for (int j = 0; j < num_col * num_row; j++)
  {
   File >> a;
   image(i, j) = double(a);
  }
 return image;
}

mat read_mnist_label(const string fileName)
{
 fstream File;
 mat label;
 File.open(fileName);
 if (!File.is_open()) // cannot open file
 {
  cout << "      " << endl;
  return mat(0, 0, fill::zeros);
 }
 uchar a, b, c, d;
 File >> a >> b >> c >> d;
 int magic = reverseInt(a, b, c, d);
 if (magic != 2049) //magic number wrong
 {
  cout << magic;
  return mat(0, 0, fill::zeros);
 }
 File >> a >> b >> c >> d;
 int num_lab = reverseInt(a, b, c, d);
 //        
 label = mat(num_lab, 10, fill::zeros);
 for (int i = 0; i < num_lab; i++)
 {
  File >> a;
  label(i, int(a)) = 1;
 }
 return label;
}

締め括りをつける
ここでC++についてはファイルフローとarmadilloに基づいてmnistの文章を読んで紹介します。もっと関連しているC++armadilloはmnistの内容を読み取ります。以前の文章を検索してください。または下記の関連記事を引き続きご覧ください。これからもよろしくお願いします。