MNIST数据集导出

news2024/11/30 14:45:34

MNIST数据集导出

文章目录

  • MNIST数据集导出
    • 1、 MNIST数据集介绍
    • 2、 MNIST数据集下载
      • 2.1 使用Pytorch自带的MNIST数据集
    • 3、 MNIST数据集解析
      • 3.1 训练集图片文件解析规则
      • 3.2 训练集标签文件解析规则
      • 3.3 测试集图片文件解析规则
      • 3.4 测试集标签文件解析规则
    • 4、 MNIST数据集转图片
      • 4.1 使用python手动解析MNIST数据
      • 4.2 使用C++导出数据
    • 5、 总结

1、 MNIST数据集介绍

  MNIST数据集是一个包含手写数字图像的大型数据库,被广泛应用于训练各种图像处理系统和机器学习模型。

来源
  MNIST数据集由美国国家标准与技术研究所(National Institute of Standards and Technology,NIST)发起整理,一共统计了来自250个不同的人手写数字图片。其中50%是高中生,50%来自人口普查局的工作人员。

数据信息
  MNIST数据集包含70000张图像,其中60000张用于训练,10000张用于测试。每一张图像都是28×28像素的灰度图像,代表一个手写数字。这种格式使得机器学习模型更容易识别和分类这些数字,并且能够更好地捕捉到数字的细节和纹理信息。

应用场景
  MNIST数据集被广泛应用于各种图像处理和机器学习的任务中,特别是手写数字识别。它已经成为计算机视觉和深度学习领域中的一个经典数据集。许多关于神经网络的教程都会使用MNIST数据集作为例子来解释神经网络的工作原理。此外,许多研究者会使用MNIST数据集来比较和评估他们的算法和模型,并与其他研究者的结果进行比较。

评估指标
  在手写数字识别任务中,常用的评估指标包括准确率、精确率、召回率和F1分数等。这些指标用于评估模型的性能,并帮助我们了解模型的优缺点。

类别说明
  MNIST数据集中的每个图像都属于一个特定的类别,即手写数字。数据集中的数字类别是从0到9的整数,总共有10个不同的类别。每个类别中包含了大量的图像,以便训练模型进行分类。在训练过程中,模型需要学会将每个图像归类到相应的数字类别中,并尽可能准确地预测出数字的值。在测试过程中,模型需要对其从未见过的图像进行分类和预测,以评估其性能和准确性。

2、 MNIST数据集下载

2.1 使用Pytorch自带的MNIST数据集

  MNIST作为一个经典数据集,Pytorch已经在datasets里自带了该数据集,可以通过pytorch数据集自动下载该数据集。

from torchvision import datasets, transforms
import matplotlib.pyplot as plt

# 下载MNIST数据集
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
trainset = datasets.MNIST('./data/mnist', download=True, train=True, transform=transform)
testset = datasets.MNIST('./data/mnist', download=True, train=False, transform=transform)

# 可视化数据集图像
n = 10  # 展示10张图像
plt.figure(figsize=(10, 5))
for i in range(n):
    images, labels = trainset[i]
    plt.subplot(2, 5, i+1)
    plt.imshow(images[0].view(28, 28), cmap='gray')
    plt.title(f'Label: {labels}')
plt.show()

  该脚本会在data/mnist/MNIST/raw路径下下载MNIST数据集,并自动解压,生成4个二进制文件。

dataset_uncompressed/
├── t10k-images-idx3-ubyte                #测试集图像数据,7840016字节
├── t10k-labels-idx1-ubyte                #测试集标签数据,10008字节
├── train-images-idx3-ubyte                #训练集图像数据,47040016字节
└── train-labels-idx1-ubyte                #训练集标签数据,60008字节

3、 MNIST数据集解析

3.1 训练集图片文件解析规则

  MNIST数据集中,训练集图片保存在二进制文件train-images-idx3-ubyte中。

偏移量(offset)值类型数值含义
032位整型0x00000803magic number
432位整型60000图片总数
832位整型28图片宽度
1232位整型28图片高度
16unsigned 8位整型28 × \times × 28个第0个图片数据
16+i × \times × 28 × \times × 28unsigned 8位整型28 × \times × 28个第i个图片数据

  数据文件总大小47040016 = 60000 × \times × 28 × \times × 28 + + + 4 × \times × 4.

3.2 训练集标签文件解析规则

  MNIST数据集中,训练集标签保存在二进制文件train-labels-idx1-ubyte中。

偏移量(offset)值类型数值含义
032位整型0x00000801magic number
432位整型60000图片总数
8+ iunsigned 8位整型0-9第i个图片的标签

  数据文件总大小60008 = 60000 × \times × 1 + + + 2 × \times × 4.

3.3 测试集图片文件解析规则

  MNIST数据集中,测试集图片保存在二进制文件t10k-images-idx3-ubyte中。

偏移量(offset)值类型数值含义
032位整型0x00000803magic number
432位整型10000图片总数
832位整型28图片宽度
1232位整型28图片高度
16unsigned 8位整型28 × \times × 28个第0个图片数据
16+i × \times × 28 × \times × 28unsigned 8位整型28 × \times × 28个第i个图片数据

  数据文件总大小7840016 = 10000 × \times × 28 × \times × 28 + + + 4 × \times × 4.

3.4 测试集标签文件解析规则

  MNIST数据集中,测试集标签保存在二进制文件t10k-labels-idx1-ubyte中。

偏移量(offset)值类型数值含义
032位整型0x00000801magic number
432位整型10000图片总数
8+ iunsigned 8位整型0-9第i个图片的标签

  数据文件总大小10008 = 10000 × \times × 1 + + + 2 × \times × 4.

4、 MNIST数据集转图片

4.1 使用python手动解析MNIST数据

  根据第3节中所述的数据解析规则,可以使用python手动解析其中的数据,并保存成png图片文件。

import numpy as np
import os
import cv2
import matplotlib.pyplot as plt

def load_image_data(filename):
    with open(filename, 'rb') as f:
        data = f.read()
    magic_number, num_images, num_rows, num_cols = np.frombuffer(data[:16], np.dtype('>i4'))
    images = np.frombuffer(data[16:], np.dtype('u1')).reshape(num_images, num_rows, num_cols)
    return images

def load_label_data(filename):
    with open(filename, 'rb') as f:
        data = f.read()
    magic_number, num_labels = np.frombuffer(data[:8], np.dtype('>i4'))
    labels = np.frombuffer(data[8:], np.dtype('u1'))
    return labels

def save_image_data(images, labels, type='train'):
    for i, (image, label) in enumerate(zip(images, labels)):
        if not os.path.exists(f'./data/mnist/{type}/{label}'):
            os.makedirs(f'./data/mnist/{type}/{label}')
        cv2.imwrite(f'./data/mnist/{type}/{label}/{i}.png', image)

def main():
    # 读取训练集数据
    train_images = load_image_data('./data/mnist/MNIST/raw/train-images-idx3-ubyte')
    train_labels = load_label_data('./data/mnist/MNIST/raw/train-labels-idx1-ubyte')
    # 读取测试集数据
    test_images = load_image_data('./data/mnist/MNIST/raw/t10k-images-idx3-ubyte')
    test_labels = load_label_data('./data/mnist/MNIST/raw/t10k-labels-idx1-ubyte')
    # 保存训练集数据
    save_image_data(train_images, train_labels, 'train')
    # 保存测试集数据
    save_image_data(test_images, test_labels, 'test')

if __name__ == '__main__':
    main()

  解析出来的图片如下所示。
在这里插入图片描述
在这里插入图片描述

数据集标签数目数据集标签数目
训练集05923测试集0980
训练集16742测试集11135
训练集25958测试集21032
训练集36131测试集31010
训练集45842测试集4982
训练集55421测试集5892
训练集65918测试集6958
训练集76265测试集71028
训练集85851测试集8974
训练集95949测试集91009
汇总6000010000

4.2 使用C++导出数据

#include "opencv2/opencv.hpp"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <filesystem>

std::vector<cv::Mat> loadMNISTImages(const std::string& path)
{
    std::ifstream file(path,std::ios::in|std::ios::binary);
    if(file.is_open())
    {
        int magic_number = 0;
        int number_of_images = 0;
        int number_of_rows = 0;
        int number_of_columns = 0;
        file.read((char*)&magic_number,sizeof(magic_number));
        file.read((char*)&number_of_images,sizeof(number_of_images));
        file.read((char*)&number_of_rows,sizeof(number_of_rows));
        file.read((char*)&number_of_columns,sizeof(number_of_columns));
        number_of_images = _byteswap_ulong(number_of_images);
        number_of_rows = _byteswap_ulong(number_of_rows);
        number_of_columns = _byteswap_ulong(number_of_columns);
        std::vector<cv::Mat> images;
        for(int i = 0; i < number_of_images; i++)
        {
            cv::Mat image(number_of_rows,number_of_columns,CV_8UC1);
            file.read((char*)image.data,number_of_rows*number_of_columns);
            images.push_back(image);
        }
        return images;
    }
    return std::vector<cv::Mat>();
}

std::vector<int> loadMNISTLabels(const std::string& path)
{
    std::ifstream file(path,std::ios::in|std::ios::binary);
    if(file.is_open())     
    {
        int magic_number = 0;
        int number_of_items = 0;
        file.read((char*)&magic_number,sizeof(magic_number));
        file.read((char*)&number_of_items,sizeof(number_of_items));
        number_of_items = _byteswap_ulong(number_of_items);
        std::vector<int> labels;
        for(int i = 0; i < number_of_items; i++)
        {
            unsigned char label = 0;
            file.read((char*)&label,sizeof(label));
            labels.push_back(label);
        }
        return labels;
    }
    return std::vector<int>();
}

void exportMNISTImages(const std::string& imagesPath, const std::string& labelsPath, const std::string& outputPath, const std::string& type)
{
    std::vector<cv::Mat> images = loadMNISTImages(imagesPath);
    std::vector<int> labels = loadMNISTLabels(labelsPath);
    std::filesystem::path output(outputPath);
    if(type == "train")
    {
        output = output / "train";
    }
    else if(type == "test")
    {
        output = output / "test";
    }
    else
        return;

    if(images.size() == labels.size())
    {
        std::filesystem::create_directory(outputPath);
        for(int i = 0; i < images.size(); i++)
        {

            std::string label = std::to_string(labels[i]);
            auto outPath = output / label;
            if(!std::filesystem::exists(outPath))
                std::filesystem::create_directories(outPath);

            std::string filename = outPath.string() + "/" + std::to_string(i) + ".png";
            cv::imwrite(filename,images[i]);
        }
    }
    return ;
}
int main(int argc, char** argv)
{
    if(argc < 6)
    {
        std::cout << "Usage: MNISTExporter <trainimagesPath> <trainlabelsPath> <testimagesPath> <testlabelsPath> <outputPath>" << std::endl;
        return 1;
    }
    auto sTrainImagesPath = std::string(argv[1]);
    auto sTrainLabelPath = std::string(argv[2]);
    auto sTestImagePath = std::string(argv[3]);
    auto sTestLabelPath = std::string(argv[4]);
    auto sOutputPath = std::string(argv[5]);
    exportMNISTImages(sTrainImagesPath,sTrainLabelPath,sOutputPath,"train");
    exportMNISTImages(sTestImagePath,sTestLabelPath,sOutputPath,"test");
    return 0;
}

5、 总结

  MNIST数据集作为一个常用的入门深度学习的数据集,该数据集提供了60000张图片用于训练集,10000张图片用于训练集。其中,0-9共10个标签,在训练集和测试集中,各个类别的数目大致均衡。

创作过程中,有参考别的作者的文章,相关知识产权归原作者所有。相关图片的知识产权归原作者所有。

博文中相关代码已经在https://github.com/freehawkzk/MNISTExport.git开源。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1815241.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

动手学深度学习31 深度学习硬件 CPU和GPU

动手学深度学习31 深度学习硬件 CPU和GPU CPU和GPU主频 QA PPT&#xff1a; https://courses.d2l.ai/zh-v2/assets/pdfs/part-2_1.pdf 视频&#xff1a; https://www.bilibili.com/video/BV1TU4y1j7Wd/?p2&spm_id_frompageDriver&vd_sourceeb04c9a33e87ceba9c9a2e5f09…

nginx ws长连接配置

nginx ws长连接配置 http根节点下配上 map $http_upgrade $connection_upgrade {default upgrade; close;}如下&#xff1a; server服务节点下&#xff0c;后端接口的代理配置 proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connec…

2. 面向对象编程推导

1. 面向过程编程 面向过程编程(Procedure-Oriented Programming, POP): 是一种关注于解决问题步骤或过程的编程范式.面向过程编程核心思想: 将复杂问题分解为一系列简单, 可执行的步骤(即过程或函数), 并按照特定的顺序依次执行这些步骤, 直到问题得到解决. 每个步骤(过程或函…

compose for desktop

then 叠加修饰符功能的作用 val reusableModifier Modifier.fillMaxWidth().background(Color.Red).padding(12.dp)// Append to your reusableModifier reusableModifier.clickable { /*...*/ }// Append your reusableModifier otherModifier.then(reusableModifier)https:…

springboot物流管理系统-计算机毕业设计源码00781

摘要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对物流管理系统等问题&#xff0c;对如何通过计…

时间处理获取交易日(考虑兼容性问题)

在获取交易日时间的处理上&#xff0c;出现了苹果14不兼容的问题&#xff0c;就这个问题记录下。 一、获取交易日的代码 封装了一个js文件&#xff0c;在untils目录下&#xff0c;先看代码&#xff0c;然后我讲下思路。 // 获取节假日数据 import { getCalendarHolidays } …

使用脚手架创建vue2项目(关闭eslint语法检查 、运行项目时自动打开网址、src文件夹简写方法)

使用脚手架创建vue2项目会默认安装的插件&#xff08;eslint) 这个插件是检查语法的。 假设我们在main.js中定义了一个变量&#xff0c;没有使用 eslint 就会检测出错误 &#xff08;事实是我们并没有写错而是eslint 给我们判断是错的&#xff0c;所以这样会很麻烦&#xff…

怎么监视员工电脑屏幕?电脑监控软件监控屏幕的六个步骤

监视员工电脑屏幕通常涉及使用专门的电脑监控软件&#xff0c;这些软件设计用于帮助企业管理人员合法合规地监督员工的工作状态、提高工作效率并确保信息安全。以下是实施员工电脑屏幕监视的一般步骤和注意事项&#xff1a; 1. 选择合适的监控软件 首先&#xff0c;选择一款适…

Idea多线程调试

在 IntelliJ IDEA 中调试多线程应用程序可能会有些复杂&#xff0c;因为多个线程可能会同时运行和交互。不过&#xff0c;IDEA 提供了一些强大的工具来帮助你进行多线程调试。以下是一些关键步骤和技巧&#xff0c;帮助你有效地调试多线程应用程序&#xff1a; 创建一个示例多线…

查分易成绩查询入口

今天我来分享一个老师超实用的小技巧&#xff0c;那就是如何用查分易来打造一个专属的成绩查询入口哦&#xff01;无论是我们勤奋的学生们&#xff0c;还是关心孩子学习的家长们&#xff0c;都可以轻松查到自己的成绩信息。来来来&#xff0c;让我来一步步教你怎么用查分易搞定…

优雅迷人的小程序 UI 风格

优雅迷人的小程序 UI 风格

基于Python的信号处理(包络谱,低通、高通、带通滤波,初级特征提取,机器学习,短时傅里叶变换)及轴承故障诊断探索

Python是一种广泛使用的解释型、高级和通用的编程语言&#xff0c;众多的开源科学计算软件包都提供了Python接口&#xff0c;如计算机视觉库OpenCV、可视化工具库VTK等。Python专用计算扩展库&#xff0c;如NumPy、SciPy、matplotlab、Pandas、scikit-learn等。 开发工具上可用…

20240612每日前端-------vue3实现聊天室(一)

先上效果图 讲讲布局设计 聊天室大致分三块&#xff1a; 左边导航右边聊天界面主界面 单独调整一下样式&#xff1a;外层friend-box先调整布局为flex&#xff0c;这样方便进行自适应布局&#xff0c;增加背景色为白色&#xff0c;设置边框圆角使得外观更加美观&#xff0c;使…

树状数组:解锁快速排名的高效利器

文章目录 引言一、快速排名问题概述二、树状数组的应用树状数组概述数据结构初始化查询排名更新排名示例代码 总结参考 引言 在大规模数据排名问题中&#xff0c;树状数组可以用来高效地实现快速排名查询和更新操作&#xff0c;特别是在处理动态变化的数据集时。使用树状数组可…

如何舒适的使用VScode

安装好VScode后通常会很不好用&#xff0c;以下配置可以让你的VScode变得好用许多。 VScode的配置流程 1、设置VScode中文2、下载C/C拓展&#xff0c;使代码可以跳转3、更改编码格式4、设置滚轮缩放5、设置字体6、设置保存自动改变格式7、vscode设置快捷代码 1、设置VScode中文…

Android studio如何导入项目

打开解压好的安装包 找到build.gradle文件 打开查看gradle版本 下载对应的gradle版本Index of /gradle/&#xff08;镜像网站&#xff09; 下载all的对应压缩包 配置gradle的环境变量 新建GRADLE_HOME 将GRADLE_HOME加入到path中 将项目在Android studio中打开进行配置 将gr…

手撕设计模式——计划生育之单例模式

1.业务需求 ​ 大家好&#xff0c;我是菠菜啊。80、90后还记得计划生育这个国策吗&#xff1f;估计同龄的小伙伴们&#xff0c;小时候常常被”只生一个好“”少生、优生“等宣传标语洗脑&#xff0c;如今国家已经放开并鼓励生育了。话说回来&#xff0c;现实生活中有计划生育&…

【Kadane】Leetcode 918. 环形子数组的最大和【中等】

环形子数组的最大和 给定一个长度为 n 的环形整数数组 nums &#xff0c;返回 nums 的非空 子数组 的最大可能和 。 环形数组 意味着数组的末端将会与开头相连呈环状。形式上&#xff0c; nums[i] 的下一个元素是 nums[(i 1) % n] &#xff0c;nums[i] 的前一个元素是 nums…

SortTable.js + vxe-table 实现多条批量排序

环境: vue3+vxe-table+sorttable.js 功能: 实现表格拖动排序,支持单条排序,多条排序 实现思路: sorttable.js官网只有单条排序的例子,网上也都是简单的使用,想要实现多条排序,就要结合着表格的复选框功能,在对其勾选的行统一计算! 最终效果: 实现代码 <template>…

PointNet论文导读

PointNet论文导读 关键点&#xff1a;网络结构输入数据特点&#xff1a;网络关键模块&#xff1a; 关键点&#xff1a; 1.设计一个新颖的网络来处理无序的点云数据&#xff1b; 2.pointnet网络可以被训练用来处理分类、部件分割和场景分割多种任务&#xff1b; 3.提供了数据…