图像集存储成MNIST数据集格式实现

2023-11-15

有时会用到将一组图像存放成MNIST中那样的数据格式,以便于用于网络的训练和测试,如MNSIT中的测试集标签t10k-labels.idx1-ubyte和测试集图像t10k-images.idx3-ubyte,各包含了10000个样本,这里以此两个测试集为例详细说明下实现过程:

http://yann.lecun.com/exdb/mnist/  中对MNIST的数据存放格式进行了介绍,存储的数据都以大多数非英特尔处理器使用的MSB优先(高端)格式存储,英特尔处理器和其他低端机器的用户必须翻转标头的字节(All the integers in the files are stored in the MSB first(high endian) format used by most non-Intel processors. Users of Intel processors and other low-endian machines must flip the bytes of the header.)。

t10k-labels.idx1-ubyte(训练集标签train-labels.idx1-ubyte与此存放格式完全相同):第1至第4个字节存放magic number(MSB first);第5至第8个字节存放标签数即10000;从第9个字节开始,每个字节存放一个标签值(label value),标签值的范围为0到9。

此处的magic number(MSB first)是一个四个字节的整数,是一个IDX文件格式;第1,第2个字节总是0;第3个字节值表示数据的类型,如0x08表示unsigned byte;0x09表示signed byte;0x0B表示short(2 bytes);0x0C表示int(4 bytes);0x0D表示float(4 bytes);0x0E表示double(8 bytes);因为t10k-labels.idx1-ubyte中标签值范围为0到9,因此这里第3字节值为0x08;第4个字节表示向量/矩阵的维数,1表示向量,2表示矩阵等;这里的标签为一维向量,因此第4字节为0x01。t10k-labels.idx1-ubyte中的前8个字节是两个magic number。

打开t10k-labels.idx1-ubyte二进制文件,前8个字节数据是:00 00 08 01 00 00 27 10,这里需要注意的是,magic number是一个四字节int,在读或写时每次性读取4个字节,高字节在后,低字节在前,与存储时顺序不同,高字节在前,低字节在后,因此在读或写magic number时,需要做个转换,即高字节变低字节,低字节变高字节,实现见ReverseInt函数。

t10k-images.idx3-ubyte(训练集图像train-images.idx3-ubyte与此存放格式完全相同):第1至第4个字节存放magic number(MSB first);第5至第8个字节存放图像数即10000;第9至第12个字节存放每个图像的行数即高,这里为28;第13至第16个字节存放每个图像的列数即宽,这里为28;从第17个字节开始,每个字节存放一个像素值,像素值的范围为0到255,0表示背景,255表示前景,像素按行排列;每28*28个字节大小存放一幅图像数据。

此处的magic number(MSB first)是一个四个字节的整数,是一个IDX文件格式;第1,第2个字节总是0;第3个字节值表示数据的类型,如0x08表示unsigned byte;0x09表示signed byte;0x0B表示short(2 bytes);0x0C表示int(4 bytes);0x0D表示float(4 bytes);0x0E表示double(8 bytes);因为t10k-images.idx3-ubyte中图像像素值范围为0到255,因此这里第3字节值为0x08;第4个字节表示向量/矩阵的维数,1表示向量,2表示矩阵等;这里的图像可看做三维即channels*height*width,因此第4字节为0x03。t10k-images.idx3-ubyte中的前16个字节是四个magic number。打开0x03.t10k-images.idx3-ubyte二进制文件,前16个字节数据是:00 00 08 03 00 00 27 10 00 00 00 1c 00 00 00 1c。

测试代码如下:

#include "funset.hpp"
#include <iostream>
#include <fstream>
#include <vector>
#include <memory>
#include <opencv2/opencv.hpp>

// MNIST /
namespace {
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;
}

void read_Mnist(std::string filename, std::vector<cv::Mat> &vec)
{
	std::ifstream file(filename, std::ios::binary);
	if (file.is_open()) {
		int magic_number = 0;
		int number_of_images = 0;
		int n_rows = 0;
		int n_cols = 0;
		file.read((char*)&magic_number, sizeof(magic_number));
		magic_number = ReverseInt(magic_number);
		file.read((char*)&number_of_images, sizeof(number_of_images));
		number_of_images = ReverseInt(number_of_images);
		file.read((char*)&n_rows, sizeof(n_rows));
		n_rows = ReverseInt(n_rows);
		file.read((char*)&n_cols, sizeof(n_cols));
		n_cols = ReverseInt(n_cols);

		for (int i = 0; i < number_of_images; ++i) {
			cv::Mat tp = cv::Mat::zeros(n_rows, n_cols, CV_8UC1);
			for (int r = 0; r < n_rows; ++r) {
				for (int c = 0; c < n_cols; ++c) {
					unsigned char temp = 0;
					file.read((char*)&temp, sizeof(temp));
					tp.at<uchar>(r, c) = (int)temp;
				}
			}
			vec.push_back(tp);
		}

		file.close();
	}
}

void read_Mnist_Label(std::string filename, std::vector<int> &vec)
{
	std::ifstream file(filename, std::ios::binary);
	if (file.is_open()) {
		int magic_number = 0;
		int number_of_images = 0;
		int n_rows = 0;
		int n_cols = 0;
		file.read((char*)&magic_number, sizeof(magic_number));
		magic_number = ReverseInt(magic_number);
		file.read((char*)&number_of_images, sizeof(number_of_images));
		number_of_images = ReverseInt(number_of_images);

		for (int i = 0; i < number_of_images; ++i) {
			unsigned char temp = 0;
			file.read((char*)&temp, sizeof(temp));
			vec[i] = (int)temp;
		}

		file.close();
	}
}

std::string GetImageName(int number, int arr[])
{
	std::string str1, str2;

	for (int i = 0; i < 10; i++) {
		if (number == i) {
			arr[i]++;
			str1 = std::to_string(arr[i]);

			if (arr[i] < 10) {
				str1 = "0000" + str1;
			} else if (arr[i] < 100) {
				str1 = "000" + str1;
			} else if (arr[i] < 1000) {
				str1 = "00" + str1;
			} else if (arr[i] < 10000) {
				str1 = "0" + str1;
			}

			break;
		}
	}

	str2 = std::to_string(number) + "_" + str1;

	return str2;
}

int write_images_to_file(const std::string& file_name, const std::vector<cv::Mat>& image_data,
	int magic_number, int image_number, int image_rows, int image_cols)
{
	if (image_number > image_data.size()) {
		fprintf(stderr, "Error: image_number > image_data.size(): \
			image_number: %d, image_data.size: %d", image_number, image_data.size());
		return -1;
	}

	std::ofstream file(file_name, std::ios::binary);
	if (!file.is_open()) {
		fprintf(stderr, "Error: open file fail: %s\n", file_name.c_str());
		return -1;
	}

	int tmp = ReverseInt(magic_number);
	file.write((char*)&tmp, sizeof(int));
	tmp = ReverseInt(image_number);
	file.write((char*)&tmp, sizeof(int));
	tmp = ReverseInt(image_rows);
	file.write((char*)&tmp, sizeof(int));
	tmp = ReverseInt(image_cols);
	file.write((char*)&tmp, sizeof(int));

	int size = image_rows * image_cols;
	for (int i = 0; i < image_number; ++i) {
		file.write((char*)image_data[i].data, sizeof(unsigned char) * size);
	}

	file.close();
	return 0;
}

int write_labels_to_file(const std::string& file_name, const std::vector<int>& label_data,
	int magic_number, int label_number)
{
	if (label_number > label_data.size()) {
		fprintf(stderr, "Error: label_number > label_data.size(): \
			label_number: %d, label_data.size: %d", label_number, label_data.size());
		return -1;
	}

	std::ofstream file(file_name, std::ios::binary);
	if (!file.is_open()) {
		fprintf(stderr, "Error: open file fail: %s\n", file_name.c_str());
		return -1;
	}

	int tmp = ReverseInt(magic_number);
	file.write((char*)&tmp, sizeof(int));
	tmp = ReverseInt(label_number);
	file.write((char*)&tmp, sizeof(int));

	std::unique_ptr<unsigned char[]> labels(new unsigned char[label_number]);
	for (int i = 0; i < label_number; ++i) {
		labels[i] = static_cast<unsigned char>(label_data[i]);
	}
	file.write((char*)labels.get(), sizeof(unsigned char) * label_number);

	file.close();
	return 0;
}
} // namespace //mnist

int ImageToMNIST()
{
	// read images
#ifdef _MSC_VER
	std::string filename_test_images = "E:/GitCode/NN_Test/data/database/MNIST/t10k-images.idx3-ubyte";
#else
	std::string filename_test_images = "data/database/MNIST/t10k-images.idx3-ubyte";
#endif
	const int number_of_test_images = 10000;
	std::vector<cv::Mat> vec_test_images;

	read_Mnist(filename_test_images, vec_test_images);
	if (vec_test_images.size() != number_of_test_images) {
		fprintf(stderr, "Error: fail to parse t10k-images.idx3-ubyte file: %d\n", vec_test_images.size());
		return -1;
	}

	// read labels
#ifdef _MSC_VER
	std::string filename_test_labels = "E:/GitCode/NN_Test/data/database/MNIST/t10k-labels.idx1-ubyte";
#else
	std::string filename_test_labels = "data/database/MNIST/t10k-labels.idx1-ubyte";
#endif
	std::vector<int> vec_test_labels(number_of_test_images);

	read_Mnist_Label(filename_test_labels, vec_test_labels);

	// write images
	const int image_magic_number = 2051; // 0x00000803
	const int image_number = 10000;
	const int image_rows = 28;
	const int image_cols = 28;
#ifdef _MSC_VER
	const std::string images_save_file_name = "E:/GitCode/NN_Test/data/new_t10k-images.idx3-ubyte";
#else
	const std::string images_save_file_name = "data/new_t10k-images.idx3-ubyte";
#endif

	if (write_images_to_file(images_save_file_name, vec_test_images, image_magic_number,
		image_number, image_rows, image_cols) != 0) {
		fprintf(stderr, "Error: write images to file fail\n");
		return -1;
	}

	// write labels
	const int label_magic_number = 2049; // 0x00000801
	const int label_number = 10000;
#ifdef _MSC_VER
	const std::string labels_save_file_name = "E:/GitCode/NN_Test/data/new_t10k-labels.idx1-ubyte";
#else
	const std::string labels_save_file_name = "data/new_t10k-labels.idx1-ubyte";
#endif

	if (write_labels_to_file(labels_save_file_name, vec_test_labels, label_magic_number, label_number) != 0) {
		fprintf(stderr, "Error: write labels to file fail\n");
		return -1;
	}

	return 0;
}

新生成的两个数据文件为new_t10k-labels.idx1-ubyte和new_t10k-images.idx3-ubyte,通过md5可知,新生成的文件与原始文件完全相同,结果如下:

GitHub: https://github.com/fengbingchun/NN_Test 

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

图像集存储成MNIST数据集格式实现 的相关文章

  • 【c++】14.编译proto和proto相关用法

    编译proto和proto相关用法 关于proto相关的知识可以参考系列博客 https blog csdn net daaikuaichuan category 9869251 html xx proto文件中如果要注释的话 注释符号也是
  • Caffe源码中caffe.proto文件分析

    Caffe源码 caffe version 09868ac date 2015 08 15 中有一些重要文件 这里介绍下caffe proto文件 在src caffe proto目录下有一个caffe proto文件 proto目录下除了
  • 如何将 .npy 文件转换为 .binaryproto?

    我使用 python 创建了一个平均图像文件并将其保存到 numpy 文件中 我想知道如何将此 npy 文件转换为 binaryproto 文件 我正在使用此文件来使用 GoogLeNet 进行训练 您可以简单地使用 numpy 创建 bi
  • 三元组损失的softmax版本的梯度计算

    我一直在尝试在Caffe中实现softmax版本的三元组损失 描述于 霍弗和艾隆 使用三元组网络进行深度度量学习 ICLR 2015 我已经尝试过这个 但我发现很难计算梯度 因为指数中的 L2 不是平方的 有人可以帮我吗 使用现有的 caf
  • 为 Caffe 生成 LMDB

    我正在尝试使用 caffe 我正在使用 python 包装器 构建用于显着性分析的深度学习模型 但我无法理解如何为此目的生成 lmdb 数据结构 我已经浏览了 Imagenet 和 mnist 示例 我明白我应该以以下格式生成标签 my t
  • PyCaffe中的layer模块在哪里定义

    我正在修改一个Caffe教程 http nbviewer jupyter org github BVLC caffe blob master examples pascal multilabel with datalayer ipynb实现
  • CNN 上的快速损失收敛意味着什么?

    我正在两个不同的深度学习库 Caffe e Tensorflow 中训练两个 CNN AlexNet e GoogLeNet 该网络由每个图书馆的开发团队实施 here https github com BVLC caffe tree ma
  • 未知的底部 blob“数据”(层“conv1”,底部索引 0)

    尝试在我自己的数据集上训练 LeNet 我从长一维矢量数据集生成了 HD F5 文件 并创建了 HDF5 数据层 如下所示 我对顶部 blob 的命名与生成 HDF5 时的命名相同 name Test net layer name data
  • 如何在非 NVIDIA 设置上加速深度学习?

    由于我只有 AMD A10 7850 APU 并且没有资金购买 800 1200 美元的 NVIDIA 显卡 因此我正在尝试利用我拥有的资源通过 TensorFlow Keras 加速深度学习 最初 我使用了 Tensorflow 的预编译
  • 使用 Caffe 没有提高 RMSprop、Adam、AdaDelta 测试精度

    I am finetuning using Caffe在图像数据集上Tesla K40 用一个batch size 47 solver type SGD base lr 0 001 lr policy step momentum 0 9 g
  • Caffe 到 Tensorflow(Kaffe by Ethereon):TypeError:不应直接创建描述符,而只能从其父级检索

    我想使用 ethereon 的精彩包 caffe tensorflow 但遇到了中描述的相同问题这个已关闭的问题 https github com ethereon caffe tensorflow issues 10 当我运行该示例或尝试
  • 由于 gcc 编译器版本不受支持,Caffe 编译失败

    我挣扎着Caffe http caffe berkeleyvision org 汇编 不幸的是我没能编译它 Steps http caffe berkeleyvision org installation html cmake compil
  • PyInstaller“ValueError:太多值无法解压”

    pyinstaller 版本 3 2 操作系统 win10 我的 python 脚本在 Winpython Python 解释器中运行良好 但是当我使用 Pyinstaller 包时 python 脚本包含 caffe 模块 我将面临的问题
  • 在 Yosemite 上编译 caffe

    我正在尝试在 Yosemite 上安装 caffe 但我的 C 不是最强的 这是我的错误 Alis MacBook Pro caffe ali make all NVCC src caffe layers absval layer cu u
  • Caffe:如果内存中只能容纳一小部分,我该怎么办?

    我正在尝试训练一个非常大的模型 因此 我只能将非常小的批量大小放入 GPU 内存中 处理小批量的结果非常噪声梯度估计 https stackoverflow com a 33717093 1714410 我该怎么做才能避免这个问题 您可以更
  • 如何加载 caffe 模型并转换为 numpy 数组?

    我有一个 caffemodel 文件 其中包含 ethereon 的 caffe tensorflow 转换实用程序不支持的层 我想生成我的咖啡模型的 numpy 表示 我的问题是 如何将 caffemodel 文件 我还有 prototx
  • Caffe,在层中设置自定义权重

    I have a network In one place I want to use concat As on this picture 不幸的是 该网络无法训练 为了理解为什么我想连续改变权重 这意味着 FC4096 中的所有值一开始都
  • Caffe 的 LSTM 模块

    有谁知道 Caffe 是否有一个不错的 LSTM 模块 我从 russel91 的 github 帐户中找到了一个 但显然包含示例和解释的网页消失了 以前是http apollo deepmatter io http apollo deep
  • 通过 Caffe 中的层提供数据的多种路径

    我想在 Caffe 中构建一个网络 其中传入的数据最初被分割 分别通过同一组层 最后使用 eltwise 层重新组合 此后 所有部件将作为一个斑点移动 除了学习的参数之外 数据并行移动的网络部分的层配置将是相同的 有没有一种方法可以在 Ca
  • 卷积 ImageNet 网络对于翻转图像具有不变性

    我正在使用深度学习 caffe 框架进行图像分类 我有一些有头像的硬币 有些是左向的 有些是右向的 为了对它们进行分类 我使用常见的方法 从预训练的 ImageNet 网络中获取权重和结构 该网络已经捕获了大量图像模式 并主要训练最后一层以

随机推荐

  • 计算机毕业设计 基于SSM框架+Vue的企业人事信息管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

    博主介绍 从事软件开发10年之余 专注于Java技术领域 Python人工智能及数据挖掘 小程序项目开发和Android项目开发等 CSDN 掘金 华为云 InfoQ 阿里云等平台优质作者 文末获取源码联系 精彩专栏推荐订阅 不然下次找不到
  • idea中配置Tomcat找不到的解决办法

    idea中配置Tomcat找不到的解决办法 最近重装了系统 所以重新下载了一下idea 配置tomcat时发现找不到Tomcat Server 下面是一种解决方法 希望也可以帮助到大家 具体的实施步骤 File gt Settings gt
  • C++中nothrow的介绍及使用

    在C中 使用malloc等分配内存的函数时 一定要检查其返回值是否为 空指针 并以此作为检查内存操作是否成功的依据 这种Test for NULL代码形式是一种良好的编程习惯 也是编写可靠程序所必需的 在C 中new在申请内存失败时默认会抛
  • 使用布谷鸟算法优化的LSTM进行数据回归预测

    使用布谷鸟算法优化的LSTM进行数据回归预测 在时间序列数据分析方面 长短时记忆网络 LSTM 已经成为一种流行的方法 然而 LSTM模型中的大量参数使得该模型的训练变得困难 因此 本文提出了一种基于布谷鸟算法的优化方法来加速LSTM模型的
  • 一网通办的内涵解构

    一网通办 节选 一网通办 这四个字的每一个字都有特定的含义 整合在一起便构成了具有内在逻辑关系的特定概念 1 一网通办 的核心在于 办 办 重视的是办理 一方面从民众角度出发 提高和丰富企业与个人办事的体验度 满意度 获得感 使民众能够及时
  • 1074 Reversing Linked List (25 point(s))

    1074 Reversing Linked List 25 point s Given a constant K and a singly linked list L you are supposed to reverse the link
  • [CentOS]Chkrootkit后门检测工具的安装

    工具介绍 Chkrootkit 工具用来监测 rootkit 是否被安装到当前系统中 rootkit 是 攻击者经常使用的后门程序 这类后门程序通常非常隐秘 不易被察觉 植入后 等于为攻击者建立了一条能够长时间入侵系统或可对系统进行实时控制
  • 基于置换均线的二次穿越突破均线

    1 名词解释 置换均线 移位移动平均线也称置换移动平均线 置换均线 DMA 不是将当根bar上计算的均线值画上当根bar上 而是将历史的均线值画在当根bar上 使均线值整体向未来偏移了指定数量的bar 将移动平均K线向后平移一定BAR数即为
  • 西瓜书学习(一)—决策树(上)

    1 什么是决策树 顾名思义 决策树是以树形的结构方式来对事件做决定和分类 我们以来判断一个瓜是不是好瓜来举例子 如下 决策树的结构一般包含一个根节点 若干个内部节点和若干个叶节点 根节点包含所有样本 各种各样的瓜 内部节点是西瓜的属性 根茎
  • js获取数组中的最大值最小值

    1 遍历方法 var tmp 1 12 8 5 var max tmp 0 for var i 1 i
  • 【hadoop】AccessControlException: SIMPLE authentication is not enabled. Available:[TOKEN, KERBEROS]

    文章目录 1 场景1 1 1 概述 1 2 我的异常 1 场景1 1 1 概述 今天要对接华为的hadoop环境 然后我要执行相关的kerberos认证 然后获取到他们的YarnClient 但是报错 AccessControlExcept
  • 变换的矩阵

    import java io InterruptedIOException import java time chrono JapaneseChronology import java util Scanner public class M
  • SPSS 进行两因素重复测量方差分析(Two-way repeated-measures ANOVA)详细操作步骤 (上)

    一 问题与数据 研究者研究了16名健康人在五种状态 P1 P2 P3 P4 P5 下的参数 MS A MS B MS C MS D 是否存在显著性差异 每种状态下均有参数 MS A MS B MS C MS D 因为自变量均为Within
  • B样条曲线

    学习B样条曲线需要先学习贝塞尔曲线 若未了解 看我一篇上博客https blog csdn net weixin 42513339 article details 83019610 贝塞尔函数不足 由于贝塞尔曲线存在以下不足 1 缺乏局部修
  • 字典排序 案例

    一 字典序 字典序 就是按照字典中出现的先后顺序进行排序 1 单个字符 在计算机中 25个字母以及数字字符 字典排序如下 0 lt 1 lt 2 lt lt 9 lt a lt b lt lt z 比如在 python 中 0 lt 9 l
  • 安装MySQL时提示错误:由于找不到MSVCP120.dIl,无法继续执行代码。重新安装程序可能会解决此 问题。

    问题 这是因为没有安装Visual C Redistributable Packages for Visual Studio 2013导致的错误 解决方案 vc 2013 官网下载地址 https www microsoft com zh
  • Android 使用Get请求获取网络数据(极速数据)

    1 环境配置 android studio 2 3 3 java 16 0 1 1 1 配置Json库 需要准备的jar包 json lib 2 4 kdj15 jar 第一步 拷贝需要用到的jar包到项目目录的app libs路径下 第二
  • cpp mqtt paho 使用_C++实现mqtt协议

    实例简介 C 实现mqtt协议 官网的mqtt c 实现 个觉得写得非常棒 实例截图 核心代码 mqtt cpp org eclipse paho mqtt cpp 55216695b73dc7ab2a9f917878de2b8eddb7c
  • Android Studio:SVN->GIT(三)

    在使用git进行代码管理时 首先简单介绍一下git 目前主流的版本管理工具主要是 svn git svn是集中式的代码管理工具 而git是散布式的代码管理工具 它采用了分布式版本库的方式 不必服务器端软件支持 基于git的github更是全
  • 图像集存储成MNIST数据集格式实现

    有时会用到将一组图像存放成MNIST中那样的数据格式 以便于用于网络的训练和测试 如MNSIT中的测试集标签t10k labels idx1 ubyte和测试集图像t10k images idx3 ubyte 各包含了10000个样本 这里