mnist数据集介绍

2023-10-28

参考博客:

https://blog.csdn.net/tostq/article/details/51786265

参考代码:

https://github.com/tostq/DeepLearningC/tree/master/CNN


MINST数据库

MINST数据库是由Yann提供的手写数字数据库文件,其官方下载地址http://yann.lecun.com/exdb/mnist/

 这个里面还包含了对这个数据库进行识别的各类算法的结果比较及相关算法的论文

数据库的里的图像都是28*28大小的灰度图像,每个像素的是一个八位字节(0~255)

这个数据库主要包含了60000张的训练图像和10000张的测试图像,主要是下面的四个文件

    /*
        Training set images: train-images-idx3-ubyte.gz (9.9 MB, 解压后 47 MB, 包含 60,000 个样本)
        Training set labels: train-labels-idx1-ubyte.gz (29 KB, 解压后 60 KB, 包含 60,000 个标签)
        Test set images: t10k-images-idx3-ubyte.gz (1.6 MB, 解压后 7.8 MB, 包含 10,000 个样本)
        Test set labels: t10k-labels-idx1-ubyte.gz (5KB, 解压后 10 KB, 包含 10,000 个标签)
    */

上述四个文件直接解压就可以使用了,虽然数据未压缩,但是我们还是需要将图像提取出来,方便我们进行操作

(1)存储图像数据的相关数据结构:

单张图像结构及保存图像的链表

typedef struct MinstImg{
    int c;           // 图像宽
    int r;           // 图像高
    float** ImgData; // 图像数据二维动态数组
}MinstImg;

typedef struct MinstImgArr{
    int ImgNum;        // 存储图像的数目
    MinstImg* ImgPtr;  // 存储图像数组指针
}*ImgArr;              // 存储图像数据的数组

图像实际数字标号(0~9)数据库里是用一个八位字节来表示,不过为了方便学习,需要用10位来表示。这里的10位表示网络输出层的10个神经元,某位为1表示数字标号即为该位。

这里我们可以理解为

float* LabelData;   相等  float LabelData[10]={0};

一共数组大小为10,数组中,第i个元素为1,即该数字标号为i

上文中说,数据库里是用一个8位字节,下面读入Label函数的时候我们再解析

接着:

typedef struct MinstLabel{
    int l;            // 输出标记的长 0 1 2 4 5 6 7 8 9
    float* LabelData; // 输出标记数据
}MinstLabel;

typedef struct MinstLabelArr{
    int LabelNum;
    MinstLabel* LabelPtr;
}*LabelArr;              // 存储图像标记的数组

(2)读入图像数据的相关函数

ImgArr read_Img(const char* filename) // 读入图像
{
	FILE  *fp = NULL;
	fp = fopen(filename, "rb");
	if (fp == NULL)
		printf("open file failed\n");
	assert(fp);

	int magic_number = 0;
	int number_of_images = 0;
	int n_rows = 0;
	int n_cols = 0;
	//从文件中读取sizeof(magic_number) 个字符到 &magic_number  
	fread((char*)&magic_number, sizeof(magic_number), 1, fp);
	magic_number = ReverseInt(magic_number);
	//获取训练或测试image的个数number_of_images 
	fread((char*)&number_of_images, sizeof(number_of_images), 1, fp);
	number_of_images = ReverseInt(number_of_images);
	//获取训练或测试图像的高度Heigh  
	fread((char*)&n_rows, sizeof(n_rows), 1, fp);
	n_rows = ReverseInt(n_rows);
	//获取训练或测试图像的宽度Width  
	fread((char*)&n_cols, sizeof(n_cols), 1, fp);
	n_cols = ReverseInt(n_cols);
	//获取第i幅图像,保存到vec中 
	int i, r, c;

	// 图像数组的初始化
	ImgArr imgarr = (ImgArr)malloc(sizeof(MinstImgArr));
	imgarr->ImgNum = number_of_images;
	imgarr->ImgPtr = (MinstImg*)malloc(number_of_images*sizeof(MinstImg));

	for (i = 0; i < number_of_images; ++i)
	{
		imgarr->ImgPtr[i].r = n_rows;
		imgarr->ImgPtr[i].c = n_cols;
		imgarr->ImgPtr[i].ImgData = (float**)malloc(n_rows*sizeof(float*));
		for (r = 0; r < n_rows; ++r)
		{
			imgarr->ImgPtr[i].ImgData[r] = (float*)malloc(n_cols*sizeof(float));
			for (c = 0; c < n_cols; ++c)
			{
				unsigned char temp = 0;
				fread((char*)&temp, sizeof(temp), 1, fp);
				imgarr->ImgPtr[i].ImgData[r][c] = (float)temp / 255.0;
			}
		}
	}

	fclose(fp);
	return imgarr;
}

为什么这么读入,我们看一下官网的文件,32bit = 4字节 = int(C++/C)

读出第1个4字节放入number_of_images

//从文件中读取sizeof(magic_number) 个字符到 &magic_number  
fread((char*)&magic_number, sizeof(magic_number), 1, fp);
magic_number = ReverseInt(magic_number);
//获取训练或测试image的个数number_of_images 
fread((char*)&number_of_labels, sizeof(number_of_labels), 1, fp);
number_of_labels = ReverseInt(number_of_labels);

通过函数ReverseInt,去解析出真正的个数

int ReverseInt(int i)
{
	unsigned char ch1, ch2, ch3, ch4;
	ch1 = i & 255;
	ch2 = (i >> 8) & 255;
	ch3 = (i >> 16) & 255;
	ch4 = (i >> 24) & 255;
	return((int)ch1 << 24) + ((int)ch2 << 16) + ((int)ch3 << 8) + ch4;
}

他是用4字节的大小空间,去存放了number_of_images这个数,我们第一次取到的是4字节,并不是一个int数,解析它

截完图我发现截错了,应该截读入图片的,现在是读入Label的,反正大致意思一样,我觉得大家可以清晰理解的

就以截图中的数据说话,原来是1625948160 解析后 变成了60000

96=0110 0000,   234=1110 1010

0000 0000 ,0000 0000,1110 1010,0110 0000 

下面都是同理的,不再叙述

读出第2个4字节放入number_of_images

读出第3个4字节放入n_rows

读出第4个4字节放入n_cols

接着:

放入之前还进行了归一化

imgarr->ImgPtr[i].ImgData[r][c] = (float)temp / 255.0;

 

一个像素点,用一个无符号字节表示

一个字节=8bit

程序中使用,unsigned char,在C/C++中,unsigned char=1字节

即每次从文件中取出一个字节,作为1个像素点

最后一句话,像素按行排列,至此,解析完毕

(3)读入图像数据标号

LabelArr read_Lable(const char* filename)// 读入图像
{
	FILE  *fp = NULL;
	fp = fopen(filename, "rb");
	if (fp == NULL)
		printf("open file failed\n");
	assert(fp);

	int magic_number = 0;
	int number_of_labels = 0;
	int label_long = 10;

	//从文件中读取sizeof(magic_number) 个字符到 &magic_number  
	fread((char*)&magic_number, sizeof(magic_number), 1, fp);
	magic_number = ReverseInt(magic_number);
	//获取训练或测试image的个数number_of_images 
	fread((char*)&number_of_labels, sizeof(number_of_labels), 1, fp);
	number_of_labels = ReverseInt(number_of_labels);

	int i, l;

	// 图像标记数组的初始化
	LabelArr labarr = (LabelArr)malloc(sizeof(MinstLabelArr));
	labarr->LabelNum = number_of_labels;
	labarr->LabelPtr = (MinstLabel*)malloc(number_of_labels*sizeof(MinstLabel));

	for (i = 0; i < number_of_labels; ++i)
	{
		labarr->LabelPtr[i].l = 10;
		labarr->LabelPtr[i].LabelData = (float*)calloc(label_long, sizeof(float));
		unsigned char temp = 0;
		fread((char*)&temp, sizeof(temp), 1, fp);
		labarr->LabelPtr[i].LabelData[(int)temp] = 1.0;
	}

	fclose(fp);
	return labarr;
}

上述代码中,

读出第1个4字节放入magic_number

读出第2个4字节放入number_of_labels

接着:

一个label,用一个无符号字节表示

一个字节=8bit

程序中使用,unsigned char,在C/C++中,unsigned char=1字节

即每次从文件中取出一个字节,作为1个Label

labarr->LabelPtr[i].LabelData[(int)temp] = 1.0;

label为i,就将数组第i个元素,置为1

上图是最终的读入信息

接着:

用代码将每一个数据显示,查看它是

0 0 0 0.....1 1 1 1 1 ...... 2 2 2 2 ........ 3 3 3 3 3.......     9 9 9.....这样显示

还是

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3......这样显示

还是

无规律..........

很明显,是第三种情况,读入的分别是,2 7 8 9 5 8 5 0 4 ..............

至此,全部解析完毕

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mnist数据集介绍 的相关文章

  • STL——map、set等红黑树结构的最后一个元素

    map set等背后由于红黑树的关系 插入元素后便成为 平衡 搜索树了 所以末尾元素默认为最大值 得到该值的方法 1 利用 rbegin 反向迭代器 int main int argc char argv map
  • IntersectionObserver实现小程序长列表优化

    IntersectionObserver实现小程序长列表优化 关于 IntersectionObserver 思路 这里以一屏数据为单位 一个分页的10条数据 最好大于视口高度 监听每一屏数据和视口的相交比例 即用户能不能看到它 只将可视范
  • 接口测试之Jmeter+Ant+Jenkins接口自动化测试平台

    平台简介 一个完整的接口自动化测试平台需要支持接口的自动执行 自动生成测试报告 以及持续集成 Jmeter支持接口的测试 Ant支持自动构建 而Jenkins支持持续集成 所以三者组合在一起可以构成一个功能完善的接口自动化测试平台 环境准备

随机推荐

  • IDEA中输入法无法输入中文

    偶尔而遇到这个问题 又忘记了 记录下 在idea内无法输入中文 win环境可以 很简单快捷键 ctrl shift e 解决问题 看到好多文章去改变量 改配置文件 这
  • LinearLayout加载动态view时显示不全解决办法

    问题 在某个主要Layout里面有个LinearLayout 用来动态加载别的view页面 如果需要加载的动态view内容很空洞 例如没有足够的Text长度来撑起整个layout宽度 这时候这个被加载的view就会不能以fill paren
  • 图像处理入门5-特征提取

    特征提取 图像特征提取属于图像分析的范畴 是对图像信息的深层理解 是数字图像处理的高级阶段 同时也是图像识别的开始 特征工程是图像处理的必备工具 所以掌握它的重要性不言而喻 什么是特征 特征是某一类对象区别于其他类对象的相应 本质 特点或特
  • mybatis-plus的落地实践

    一 mybatis plus官网 MyBatis Plus 二 应用层面 mapper entitty 三 配置 1 引入依赖
  • cv_bridge 冲突(完美解决)

    ubuntu18 04 ros 用 opencv3 2 0 版本 设置 cmake 找到 OpenCVConfig cmake CMakeLists txt 文件里 find package 之前加一行 set set OpenCV DIR
  • 2018.07.20 WorkSummary——04

    今天任务 优化后台代码 简化前端js部分 收获 1 数据库部分表关联与左右连接的分别占用内存的问题 一下面的为例子 SELECT FROM 表a left joint 表b ON 表a bid 表b id LEFT JOIN 表c ON 表
  • 现代控制理论5——稳定性与稳定性判据

    注 本文是在MOOC平台上学习西北工业大学 现代控制理论基础 郭建国 赵斌 郭宗易 的课程进行随笔记录与整理 一 李雅普诺夫稳定性理论 1 前期铺垫 稳定性是系统正常工作的重要特性 稳定性 是描述初始条件 不一定为0 下 系统是否具有收敛性
  • vue实用插件分享

  • 特征学习与特征工程

    特征学习与特征工程 表示学习 当我们学习一个复杂概念时 总想有一条捷径可以化繁为简 机器学习模型也不例外 如果有经过提炼的对于原始数据的更好表达 往往可以使得后续任务事倍功半 这也是表示学习的基本思路 即找到对于原始数据更好的表达 以方便后
  • Java 序列化详解

    Java 序列化 Serialization 是指将一个 Java 对象转换成字节序列 以便在网络上传输或存储在本地磁盘中 而反序列化 Deserialization 则是将已经序列化的字节序列恢复为 Java 对象 Java 提供了自带的
  • 延迟执行PostDelayed

    Android程序中 使用postDelayed 方法 表示 在一段时间之后 执行新的线程 即可以达到一段特定程序延迟执行的目的 使用 延迟15秒 new Handler postDelayed new Runnable public vo
  • ACM---贪心----hdoj 1052

    http acm hdu edu cn showproblem php pid 1052 题目大意 田忌赛马问题 这类要从数组头尾比较的问题 一般设置两个变量记录头尾下标的变化 分析 1 如果田忌最快的马比齐王最快的马快 则比之 2 如果田
  • VMWare里Linux的网络配置

    今天终于把十几天前安装在VMWare里的Linux的网络配置搞定了 高兴啊 刚使用虚拟机时 就被它神奇的虚拟功能所着迷 因为一直想在电脑里装Linux 可是由于它与Windows的不兼容 怕一安装就把原来的系统破坏 但是在虚拟机里真的能很好
  • C++_自定义函数实现返回两个数中的较小数

    本文仅仅发布在CSDN我的博客 点击打开链接 http blog csdn net pythontojava viewmode contents 转载请注明出处 我用的IDE是VS2013 代码在vc 6 0不能编译 要把int tmain
  • python怎样用stata_Python 读取stata文件

    利用Python读取stata文件 并防止中文乱码 其中 load large dta用于读取stata文件 decode str用于编译中文字符串 import pandas as pd import numpy as np import
  • Java反射详解

    目录 反射是框架设计的灵魂 一 反射的概述 反射就是把java类中的各种成分映射成一个个的Java对象 二 反射机制有什么用 三 Java反射机制的优点 四 反射机制相关的重要的类有哪些 编辑 Class类 接下来 我们已Student实体
  • 硬件系统工程师宝典(40)-----Datasheet要全都看完吗?

    各位同学大家好 欢迎继续做客电子工程学习圈 今天我们继续来讲这本书 硬件系统工程师宝典 上篇我们介绍了ESD对电路的影响以及ESD器件的选型 今天我们来讲一讲Datasheet要怎么看 我们在进行IC原理图设计时 经常需要查看IC的Data
  • qt通过Lable设置背景图片

    在lable中可以添加resoures中包含的图片 设置图片 QPixmap pix new QPixmap 1 jpg 添加resources中的文件 QSize sz ui gt background lable gt size ui
  • 成年人的自由,从学会拒绝开始

    一位读者问我 润总 我总是不好意思 也不敢 拒绝别人 常常被迫扭曲自己 做一些不情愿的事 怎么办 怎么才能得体地拒绝别人呢 今天我想告诉你一个拒绝别人的心法 坚定而柔软 1 什么叫做坚定而柔软 坚定 代表不左右动摇 不模棱两可 但是坚定 并
  • mnist数据集介绍

    参考博客 https blog csdn net tostq article details 51786265 参考代码 https github com tostq DeepLearningC tree master CNN MINST数