本文所用的MNIST 数据集来自美国国家标准与技术研究所, National Institute of Standards and Technology (NIST). 训练集 (training set) 由来自 250 个不同人手写的数字构成, 其中 50% 是高中学生, 50% 来自人口普查局 (the Census Bureau) 的工作人员。 测试集(test set) 也是同样比例的手写数字数据。数据库可在 http://yann.lecun.com/exdb/mnist/ 获取, 它包含了四个部分:
train-images-idx3-ubyte: training set images
train-labels-idx1-ubyte: training set labels
t10k-images-idx3-ubyte: test set images
t10k-labels-idx1-ubyte: test set labels
其中,训练数据集包含60000幅图片,测试集包含10000幅图片。
1.读取数据集的数据
//mnist.h
#ifndef MNIST_H
#define MNIST_H
#include <iostream>
#include <string>
#include <fstream>
#include <ctime>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
//小端存储转换
int reverseInt(int i);
//读取image数据集信息
Mat read_mnist_image(const string fileName);
//读取label数据集信息
Mat read_mnist_label(const string fileName);
#endif
大端模式:高位字节放在内存低地址处,低位字节放在内存高地址处;
小端模式:低位字节放在内存低地址处,高位字节放在内存高地址处;Intel处理器一般为小端模式。
MNIST使用了大端存储模式,因此第一步我们要做的就是大端转小端。
//mnist.cpp
#include "mnist.h"
//计时器
double cost_time;
clock_t start_time;
clock_t end_time;
//测试item个数
int testNum = 10000;
int reverseInt(int i) {
unsigned char c1, c2, c3, c4;
c1 = i & 255;
c2 = (i >> 8) & 255;
c3 = (i >> 16) & 255;
c4 = (i >> 24) & 255;
return ((int)c1 << 24) + ((int)c2 << 16) + ((int)c3 << 8) + c4;
}
Mat read_mnist_image(const string fileName) {
int magic_number = 0;
int number_of_images = 0;
int n_rows = 0;
int n_cols = 0;
Mat DataMat;
ifstream file(fileName, ios::binary);
if (file.is_open())
{
cout << "成功打开图像集 ... \n";
file.read((char*)&magic_number, sizeof(magic_number));
file.read((char*)