亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

C++基于文件流和armadillo讀取mnist

標簽:
C++

发现网上大把都是用python读取mnist的,用C++大都是用opencv读取的,但我不怎么用opencv,因此自己摸索了个使用文件流读取mnist的方法,armadillo仅作为储存矩阵的一种方式。

1. mnist文件

首先避坑,这些文件要解压。
没有肾么描述
官网截图可知,文件头很简单,只有若干个32位整数,MSB,像素和标签均是无符号字节(即unsigned char)可以先读取文件头,再读取剩下的部分。

2. 读取文件头

我觉得没什么必要啊,直接跳过不行吗
文件头都是32位,那就整四个unsigned char呗。

	uchar a, b, c, d;
	File >> a >> b >> c >> d;

这样a、b、c、d就保存了一个整数。

x = ((((a * 256) + b) * 256) + c) * 256 + d;

然后就得到了呗。
看每个文件有多少文件头,就操作几次(并可以顺便与官方的magic number进行对比),剩下的就是文件的内容了。

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

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消