采用SVM实现实现MNIST手写体分类,数据下载链接在http://yann.lecun.com/exdb/mnist/上。上传源码和实现结果,语言不限。

基于OpenCV的MNIST手写体分类

    • 简介
    • 实验要求
    • 实验环境
    • OpenCV的配置
    • 总体概览
    • 在python中绘制
    • 开始上手OpenCV
    • 查看完整内容

简介

MNIST 数据集来自美国国家标准与技术研究所, National Institute of Standards and Technology (NIST).
训练集 (training set) 由来自 250 个不同人手写的数字构成, 其中 50% 是高中学生, 50% 来自人口普查局 (the Census Bureau) 的工作人员. 测试集(test set) 也是同样比例的手写数字数据.
它的训练集有6万项数据,而测试集有1万项数据(其中前5000个来自最初NIST项目的训练集,后5000个来自最初NIST项目的测试集)。在官方网站上,这些数据以4个gz压缩包的方式提供下载:

实验要求

采用SVM实现实现MNIST手写体分类,数据下载链接在官方网站上;上传源码和实现结果,语言不限

实验环境

  • Pycharm 2019.3 BETA
  • Win10 1909
  • Python 3.7.0
  • OpenCV 4.1.1
  • VS 2019

OpenCV的配置

本次实验我选择使用C++的OpenCV实现。所以需要先配置OpenCV环境

在windows下配置OpenCV是一个技术活,这里引用一下本专业最强的达哥博客,他的博客把windows下配置OpenCV讲解的很详细。

点击这里去配置OpenCV

OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库。

总体概览

  • train-images-idx3-ubyte.gz: training set images (9912422 bytes)

  • train-labels-idx1-ubyte.gz: training set labels (28881 bytes)

  • t10k-images-idx3-ubyte.gz: test set images (1648877 bytes)

  • t10k-labels-idx1-ubyte.gz: test set labels (4542 bytes)

采用SVM实现实现MNIST手写体分类,数据下载链接在http://yann.lecun.com/exdb/mnist/上。上传源码和实现结果,语言不限。_第1张图片

The data is stored in a very simple file format designed for storing vectors and multidimensional matrices. General info on this format is given at the end of this page, but you don’t need to read that to use the data files.
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.

如上图,这些数据的格式还是比较简单的,上面文件中的所有的数字都是按照MSB(大端)的方式存储的。值得注意的的是,intel处理器是little-endian的。所以在intel处理器上或者其它的little-endian处理器上,必须要进行相应的翻转处理。也就是大端转小端

那么什么是大小端?

最标准的解释可以是Wiki百科自己学习一下。点击这里去Wiki。可能需要科学访问,或者你可以自行百度&谷歌。
采用SVM实现实现MNIST手写体分类,数据下载链接在http://yann.lecun.com/exdb/mnist/上。上传源码和实现结果,语言不限。_第2张图片

但是我还是“断章取义”一下:
例如,一个多位的整数,按照存储地址从低到高排序的字节中,如果该整数的最低有效字节(类似于最低有效位)在最高有效字节的前面,则称小端序;反之则称大端序。

MNIST网站上对数据集TRAINING SET LABEL FILE (train-labels-idx1-ubyte)的介绍如下:

[offset] [type]          [value]          [description]
0000     32 bit integer  0x00000801(2049) magic number (MSB first)
0004     32 bit integer  60000            number of items
0008     unsigned byte   ??               label
0009     unsigned byte   ??               label
........
xxxx     unsigned byte   ??               label
The labels values are 0 to 9.

其实MNIST网站上对上面很多的东西解释的很清楚了。大家最好自行研读一下英文文档。

我这里还是稍微讲一下。或者说翻译一下。

这四个文件采用了IDX的文件格式,一种平铺直叙的方式:

magic number

size in dimension 0

size in dimension 1

size in dimension 2

.....

size in dimension N

data

其中magic number为4字节,前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)

第4字节的含义表示维度的数量(dimensions): 1 表示一维(比如vectors), 2 表示二维( 比如matrices),3表示三维(比如numpy表示的图像,高,宽,通道数)。

训练集和测试集的标签文件的格式(train-labels-idx1-ubyte和t10k-labels-idx1-ubyte)格式:

  • 1.前4个字节(第0~3个字节)是魔数2049(int型,0x00000801, 大端);

  • 2.再往后4个字节(第4~7个字节)是标签的个数:60000或10000;

  • 3.再往后每1个字节是一个无符号型的数,值为0~9。

训练集和测试集的图像文件的格式(train-images-idx3-ubyte和t10k-images-idx3-ubyte)格式比label复杂些:

  • 1.前4个字节(第0~3个字节)是魔数2051(int型,0x00000803, 大端);

  • 2.再往后4个字节(第4~7个字节)是图像的个数:60000或10000(第1个维度);

  • 3.再往后4个字节(第8~11个字节)是图像在高度上由多少个像素组成(第2个维度,高28个像素);

  • 4.再往后4个字节(第12~15个字节)是图像在宽度上由多少个像素组成(第3个维度,宽28个像素);

  • 5.再往后是一个三维数组,表示10000个或60000个分辨率28x28的灰度图像,一句话来说就是10000x28x28个像素,每个像素的值为0~255(0是背景,为白色;255是黑色)。

在python中绘制

先来直观看一下数据集是什么样的吧。

新建一个Pycharm工程,输入以下源码:

# coded by Stefan
# 2019.11.12
import struct
import numpy as np
import matplotlib.pyplot as plt
# 博客地址 https://stefancharles.xyz/
def load_mnist():
    labels_path = 'D:\\py\\mnist\\data\\train-labels.idx1-ubyte'
    images_path = 'D:\\py\\mnist\\data\\train-images.idx3-ubyte'
    with open(labels_path, 'rb') as lbpath:
        magic, n = struct.unpack('>II',
                                 lbpath.read(8))
        labels = np.fromfile(lbpath,
                             dtype=np.uint8)

    with open(images_path, 'rb') as imgpath:
        magic, num, rows, cols = struct.unpack('>IIII',
                                               imgpath.read(16))
        images = np.fromfile(imgpath,
                             dtype=np.uint8).reshape(len(labels), 784)

    return images, labels

fig, ax = plt.subplots(
    nrows=2,
    ncols=5,
    sharex=True,
    sharey=True, )

X_train,y_train = load_mnist()
ax = ax.flatten()
for i in range(10):
    img = X_train[y_train == i][0].reshape(28, 28)
    ax[i].imshow(img, cmap='Greys', interpolation='nearest')

ax[0].set_xticks([])
ax[0].set_yticks([])
plt.tight_layout()
plt.show()

怎么导包,导包失败的这些问题我就不再说了,相信你已经轻车熟路了。

需要把上面的代码的绝对路径换成你下载MNIST数据集的解压后的路径。

运行上面的代码,我们现在应该可以看到一个 2*5 的图片, 里面分别是 0-9 单个数字的图片.

当然还能显示很多数据集中的图片,这里不再赘述。有兴趣的同学可以自己研究。

开始上手OpenCV

我主要需要写三个函数,一个训练函数,一个用测试集的测试函数,一个随机的测试函数。

查看完整内容

查看完整内容
请移步我的个人博客:
点击这里去Stefan的博客

你可能感兴趣的:(模式识别)