赞
踩
手写数字识别是指给定一系列的手写数字图片以及对应的数字标签,构建模型进行学习,目标是对于一张新的手写数字图片能够自动识别出对应的数字。图像识别是指利用计算机对图像进行处理,通过模型对其分析和理解,得到图片文件中所写的数字。
在人工智能领域,手写数字识别被问题转换为自动分类问题。将0~9之内的10个数字分为10类,通过模型训练,实现对数字图片的分类,间接获取数字图片上的手写数字。
该项目所用到的源码以及所有源码均在GitHub以及Gitee上面开源,下载方式:
GitHub:
git clone https://github.com/guojin-yan/MNIST_demo.git
Gitee:
git clone https://gitee.com/guojin-yan/MNIST_demo.git
MNIST数据集是一个公开手手写数字识别数据集,该数据集由250个不同的人手写而成,总共有7000张手写数据集。其中训练集有6000张,测试集有1000张。每张图片大小为28x28,为处理后的灰度图,是由28x28个像素点组成。
上图为手写数字数据集中的部分图片。该数据集可以通过以下路径进行下载:MNIST (http://yann.lecun.com/exdb/mnist/) ;或者通过各种深度学习框架提供的API函数进行下载。
通过官网下载的方式需要分别下载下图中的四个链接对应的文件,下载完成后,将文件解压到本地即可。
下图为解压好的文件,该文件为处理后的二进制文件,不是现成的图片文件,不可以直接打开,需要进行处理才可以读取,后面会在详细讲解该文件的读取方式。
数据集文件主要分两种:一种是图片数据文件,一种是分类标注文件。文件为二进制文件格式。
以训练集文件为例:train-images-idx3-ubyte
,该文件为保存的二值化后的手写数字图片数据,大小为28×28×1。我们通过Matlab读取数据文件:
% 打开二进制文件
fid = fopen('train-images-idx3-ubyte', 'rb');
% 读取二进制文件,数据格式为uint8,将所有数据读取到train_images_data中
train_images_data = fread(fid, inf, 'uint8', 'l');
% 前16个数据去掉
train_images_data = train_images_data(17:end);
% 关闭文件
fclose(fid);
% 将数据矩阵转为28×28×60000
train_images = reshape(train_images_data,28,28,60000);
% 交换前两维度,不然图片是反的
train_images = permute(train_images,[2 1 3]);
% 将数据维度转为28×28×1×60000
train_X(:,:,1,:) = train_images;
经过上面读取后,我们可以获得28×28×1×60000的数据矩阵,其中28×28×1为一张图片,总共有60000张图片。
下面我们读取训练集的标注文件:train-labels-idx1-ubyte
存储了训练集的标注情况。
% 文件读取方式与上面一致
fid = fopen('dataset\train-labels-idx1-ubyte', 'rb');
train_labels = fread(fid, inf, 'uint8', 'l');
% 标注文件是从第9个开始读取,与上面图片数据的顺序一致
train_labels = train_labels(9:end);
fclose(fid);
如果我们想通过Python实现数据文件读取,首先导入以下模块:
import numpy as np
import struct
from PIL import Image
import os
下面为训练集图片数据以及标签数据读取方式:
# 根目录 home_path = 'E:\Git_space\手写数字识别\Datasets' # 图片文件地址 image_file = os.path.join(home_path, 'MNIST\\raw\\train-images-idx3-ubyte') # 数据文件大小为:28×28×1×60000+16 = 47040016 image_data_size = 47040016 # 有效文件数据为: 28×28×1×60000 = 47040000 image_data_size = str(image_data_size - 16) + 'B' # 打开文件 image_data_buffer = open(image_file, 'rb').read() # 获取图片缓冲内存数据中的图片数量、行数、列数 magic, numImages, numRows, numColumns = struct.unpack_from('>IIII', image_data_buffer, 0) # 读取图片文件的数据 image_datas = struct.unpack_from('>' + image_data_size, image_data_buffer, struct.calcsize('>IIII')) # 将图片数据转为uint8格式,转为[numImages, 1, numRows, numColumns]大小的矩阵 image_datas = np.array(image_datas).astype(np.uint8).reshape(numImages, 1, numRows, numColumns) # 标签文件地址 label_file = os.path.join(home_path, 'MNIST\\raw\\train-labels-idx1-ubyte' ) # 标签文件长:60000+8 = 60008 label_data_size = 60008 # 实际标签文件长:60000+8 = 60008 label_data_size = str(label_data_size - 8) + 'B' label_data_buffer = open(label_file, 'rb').read() magic, numLabels = struct.unpack_from('>II', label_data_buffer, 0) label_datas = struct.unpack_from('>' + label_data_size, label_data_buffer, struct.calcsize('>II')) label_datas = np.array(label_datas).astype(np.int64)
测试集读取方式类似,如有需要自行修改。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。