机器学习实战 | MNIST手写数字分类项目(深度学习初级)

这篇具有很好参考价值的文章主要介绍了机器学习实战 | MNIST手写数字分类项目(深度学习初级)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简介

准备写个系列博客介绍机器学习实战中的部分公开项目。首先从初级项目开始。


本文为初级项目第二篇:利用MNIST数据集训练手写数字分类。
项目原网址为:Deep Learning Project – Handwritten Digit Recognition using Python。

第一篇为:机器学习实战 | emojify 使用Python创建自己的表情符号(深度学习初级)

技术流程

项目构想:
MNIST数字分类项目,使机器能够识别手写数字。该Python项目对于计算机视觉可能非常有用。在这里,我们将使用MNIST数据集使用卷积神经网络训练模型

经过训练后,在GUI页面(gui.py程序)显示效果如下:左边是手写数字,通过鼠标手写键入;右边点击recognise会提示训练结果以及识别置信度。
机器学习实战 | MNIST手写数字分类项目(深度学习初级),Deep Learning,python 学习总结,机器学习,分类,深度学习

1. 载入依赖包和数据集

import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K

import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"

# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

print(x_train.shape, y_train.shape)

除了常规包外,同样需要提前配置KerasTensorFlow,安装命令为:

pip install keras==2.10.0
pip install TensorFlow==2.10.0

这里需要注意MNIST手写数据集导入方法,直接从Keras中加载:keras.datasets.mnist

通过mnist.load获取训练数据和测试数据,训练数据集维度为: 60000 × 28 × 28 60000 \times 28\times28 60000×28×28,测试数据集维度为: 10000 × 28 × 28 10000 \times 28\times28 10000×28×28.

2. 数据预处理

x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
input_shape = (28, 28, 1)

# convert class vectors to binary class matrices
num_classes = 10
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
  • x_train.reshape:将图像数据转换为神经网络输入,图像大小 60000 × 28 × 28 60000 \times 28\times28 60000×28×28,输出大小为 60000 × 28 × 28 × 1 60000 \times 28\times28\times1 60000×28×28×1
  • keras.utils.to_categorical:将阿拉伯数字的0-9共10个数字(类别)转换为one-shot特征,用二进制表示分类类别,比如数字0用0000表示,数字1用0001表示,数字2用0010表示。
  • x_train /= 255:将图像数据归一化,首先将数据类型转换为float32,接着将数据归一化到0~1范围内。

3. 创建卷积神经网络模型

batch_size = 128
num_classes = 10
epochs = 50

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),activation='relu',input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,optimizer=keras.optimizers.Adadelta(),metrics=['accuracy'])

该项目设计了卷积神经网络(CNN)模型,包括两层卷积层、池化层、全连接层等。

函数分析:

  • Sequential:序贯模型,与函数式模型对立。from keras.models import Sequential, 序贯模型通过一层层神经网络连接构建深度神经网络。
  • add(): 叠加网络层,参数可为conv2D卷积神经网络层,MaxPooling2D二维最大池化层,Dropout随机失活层(防止过拟合),Dense密集层(全连接FC层,在Keras层中FC层被写作Dense层),下面会详细介绍这几个层的含义和参数设置。
  • compile(): 编译神经网络结构,参数包括:loss,字符串结构,指定损失函数(包括MSE等);optimizer,表示优化方式(优化器),用于控制梯度裁剪;metrics,列表,用来衡量模型指标,表示评价指标。

网络结构介绍:

  • conv2D: 卷积神经网络层,参数包括:
  1. filters: 层深度(纵向),一般来说前期数据减少,后期数量逐渐增加,建议选择 2 N 2^N 2N作为深度,比如说:[32,64,128] => [256,512,1024];
  2. kernel_size: 决定了2D卷积窗口的宽度和高度,一般设置为 ( 1 × 1 ) (1\times1) (1×1) ( 3 × 3 ) (3\times3) (3×3) ( 5 × 5 ) (5\times5) (5×5) ( 7 × 7 ) (7\times7) (7×7).
  3. activation:激活函数,可选择为:sigmoid,tanh,relu等
  • MaxPooling2D: 池化层,本质上是采样,对输入的数据进行压缩,一般用在卷积层后,加快神经网络的训练速度。没有需要学习的参数,数据降维,用来防止过拟合现象。
  • Dropout:防过拟合层,在训练时,忽略一定数量的特征检测器,用来增加稀疏性,用伯努利分布(0-1分布)B(1,p)来随机忽略特征数量,输入参数为p的大小
  • Flatten:将多维输入数据一维化,用在卷积层到全连接层的过渡,减少参数的使用量,避免过拟合现象,无参。
  • Dense:全连接层,将特征非线性变化映射到输出空间上。

4. 训练神经网络

hist = model.fit(x_train, y_train,batch_size=batch_size,epochs=epochs,verbose=1,validation_data=(x_test, y_test))
print("The model has successfully trained")

model.save('mnist.h5')
print("Saving the model as mnist.h5")

  • model.fit:在搭建完成后,将数据送入模型进行训练。参数包括:
  1. x:训练数据输入;
  2. y:训练数据输出;
  3. batch_size: batch样本数量,即训练一次网络所用的样本数;
  4. epochs:迭代次数,即全部样本数据将被“轮”多少次,轮完训练停止;
  5. verbose:可选训练过程中信息是否输出参数,0表示不输出信息,1表示显示进度条(一般默认为1),2表示每个epoch输出一行记录;
  6. valdation_data:验证数据集。
  • model.save:保存训练模型权重

训练成功后,会在源目录下保存mnist.h5文件,即为权重文件。

5. 评价网络

score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
  • model.evaluate:评价网络,返回值是一个浮点数,表示损失值和评估指标值,输入参数为测试数据,verbose表示测试过程中信息是否输出参数,同样verbose=0表示不输出测试信息。

完整程序

train.py : 完整训练代码。

gui.py: GUI窗口,输出可互动的界面。

train.py 程序

"""
Handwrittern digit recognition
"""

"""
1. Import the libraries and load the dataset
"""
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K

import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"

# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

print(x_train.shape, y_train.shape)

"""
2. Preprocess the data
"""
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
input_shape = (28, 28, 1)

# convert class vectors to binary class matrices
num_classes = 10
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

"""
3. Create the model
"""
batch_size = 128
num_classes = 10
epochs = 50

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),activation='relu',input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,optimizer=keras.optimizers.Adadelta(),metrics=['accuracy'])

"""
4. Train the model
"""
hist = model.fit(x_train, y_train,batch_size=batch_size,epochs=epochs,verbose=1,validation_data=(x_test, y_test))
print("The model has successfully trained")

model.save('mnist.h5')
print("Saving the model as mnist.h5")

"""
5. Evaluate the model
"""
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

训练结果会保存在源目录下,生成文件名为:mnist.h5

gui.py程序

from keras.models import load_model
from tkinter import *
import tkinter as tk
import win32gui
from PIL import ImageGrab, Image
import numpy as np

model = load_model('mnist.h5')

def predict_digit(img):
    #resize image to 28x28 pixels
    img = img.resize((28, 28))
    #convert rgb to grayscale
    img = img.convert('L')
    img = np.array(img)
    #reshaping to support our model input and normalizing
    img = img.reshape(1, 28, 28, 1)
    img = img/255.0
    #predicting the class
    res = model.predict([img])[0]
    return np.argmax(res), max(res)

class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)

        self.x = self.y = 0

        # Creating elements
        self.canvas = tk.Canvas(self, width=300, height=300, bg = "white", cursor="cross")
        self.label = tk.Label(self, text="Thinking..", font=("Helvetica", 48))
        self.classify_btn = tk.Button(self, text = "Recognise", command =self.classify_handwriting)
        self.button_clear = tk.Button(self, text = "Clear", command = self.clear_all)

        # Grid structure
        self.canvas.grid(row=0, column=0, pady=2, sticky=W, )
        self.label.grid(row=0, column=1,pady=2, padx=2)
        self.classify_btn.grid(row=1, column=1, pady=2, padx=2)
        self.button_clear.grid(row=1, column=0, pady=2)

        #self.canvas.bind("<Motion>", self.start_pos)
        self.canvas.bind("<B1-Motion>", self.draw_lines)

    def clear_all(self):
        self.canvas.delete("all")

    def classify_handwriting(self):
        HWND = self.canvas.winfo_id() # get the handle of the canvas
        rect = win32gui.GetWindowRect(HWND) # get the coordinate of the canvas
        im = ImageGrab.grab(rect)

        digit, acc = predict_digit(im)
        self.label.configure(text= str(digit)+', '+ str(int(acc*100))+'%')

    def draw_lines(self, event):
        self.x = event.x
        self.y = event.y
        r=8
        self.canvas.create_oval(self.x-r, self.y-r, self.x + r, self.y + r, fill='black')

app = App()
mainloop()

gui.py程序中用了tkinter包来呈现GUI页面,具体语句这里就不再分析解释了,需要学习的话可以参考以下链接:Python GUI编程(Tkinter)

gui.py运行后,输出页面为:

机器学习实战 | MNIST手写数字分类项目(深度学习初级),Deep Learning,python 学习总结,机器学习,分类,深度学习
通过键盘在左侧手写字符,点击recognise输出识别结果。
机器学习实战 | MNIST手写数字分类项目(深度学习初级),Deep Learning,python 学习总结,机器学习,分类,深度学习


如有问题,欢迎指出和讨论。文章来源地址https://www.toymoban.com/news/detail-558426.html

到了这里,关于机器学习实战 | MNIST手写数字分类项目(深度学习初级)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MNIST手写数字辨识-cnn网路 (机器学习中的hello world,加油)

    用PyTorch实现MNIST手写数字识别(非常详细) - 知乎 (zhihu.com) 参考来源(这篇文章非常适合入门来看,每个细节都讲解得很到位) 一、模块函数用法-查漏补缺: 1.关于torch.nn.functional.max_pool2d()的用法: 上述示例中,输入张量 input 经过最大池化操作后,使用了 kernel_size=2 和 strid

    2024年02月09日
    浏览(25)
  • 机器学习第一周:用卷积神经网络实现Mnist手写数字识别(付基础知识解释)

    MNIST 数据集是一个手写数字识别数据集,包含了 60000 张训练图像和 10000 张测试图像,每张图像都是 28x28 像素的灰度图像。 在这个代码中,我们首先使用了 numpy 库中的 np.random.seed() 方法来设置随机种子,以确保结果可重复。 然后,我们使用了 Keras 中的 mnist.load_data() 方法来

    2024年02月08日
    浏览(29)
  • 实战:基于卷积的MNIST手写体分类

    前面实现了基于多层感知机的MNIST手写体识别,本章将实现以卷积神经网络完成的MNIST手写体识别。 1.  数据的准备 在本例中,依旧使用MNIST数据集,对这个数据集的数据和标签介绍,前面的章节已详细说明过了,相对于前面章节直接对数据进行“折叠”处理,这里需要显式地

    2024年02月10日
    浏览(25)
  • Keras-4-深度学习用于计算机视觉-卷积神经网络对 MNIST 数字进行分类:

    本篇学习记录主要包括:《Python深度学习》的第5章(深度学习用于计算机视觉)的第1节(卷积神经网络简介)内容。 相关知识点: 密集层 (Dense层、全连接层) 和 卷积层的区别在于: Dense层从输入特征空间中学到的是全局模式;而卷积层学到的是局部模式 (学到的是卷积核大

    2024年02月11日
    浏览(33)
  • 基于PyTorch的MNIST手写体分类实战

    第2章对MNIST数据做了介绍,描述了其构成方式及其数据的特征和标签的含义等。了解这些有助于编写合适的程序来对MNIST数据集进行分析和识别。本节将使用同样的数据集完成对其进行分类的任务。 3.1.1  数据图像的获取与标签的说明 MNIST数据集的详细介绍在第2章中已经完成

    2024年02月08日
    浏览(26)
  • 深度学习笔记(七)——基于Iris/MNIST数据集构建基础的分类网络算法实战

    文中程序以Tensorflow-2.6.0为例 部分概念包含笔者个人理解,如有遗漏或错误,欢迎评论或私信指正。 截图和程序部分引用自北京大学机器学习公开课 在神经网络的构建过程中,都避不开以下几个步骤: 导入网络和依赖模块 原始数据处理和清洗 加载训练和测试数据 构建网络

    2024年01月18日
    浏览(21)
  • 卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

    前言 若将图像数据输入全连接层,可能会导致丧失一些位置信息 卷积神经网络将图像按照原有的空间结构保存,不会丧失位置信息。 卷积运算: 1.以单通道为例: 将将input中选中的部分与kernel进行数乘 : 以上图为例对应元素相乘结果为211,并将结果填入output矩阵的左上角

    2024年02月04日
    浏览(44)
  • 人工智能TensorFlow MNIST手写数字识别——实战篇

    上期文章TensorFlow手写数字-训练篇,我们训练了我们的神经网络,本期使用上次训练的模型,来识别手写数字(本期构建TensorFlow神经网络代码为上期文章分享代码) http://scs.ryerson.ca/~aharley/vis/conv/ 0、插入第三方库 1、图片处理函数

    2024年02月15日
    浏览(43)
  • 清华青年AI自强作业hw3_1:用线性回归模型拟合MNIST手写数字分类

    一起学AI系列博客:目录索引 hw3_1:用线性回归模型拟合MNIST手写数字分类 初步体验Tensorflow编程环境 体会用回归模型网络拟合效果 尝试后发现hw3_1/hw3_3的参考代码为TF1.x框架代码,升级到TF2.x框架多为不便(升级踩坑记录),于是采用TF2.x中的keras框架重新写了一遍。 思路分析

    2024年02月10日
    浏览(30)
  • 【深度学习实战—1】:基于Keras的手写数字识别(非常详细、代码开源)

    ✨博客主页:王乐予🎈 ✨年轻人要:Living for the moment(活在当下)!💪 🏆推荐专栏:【图像处理】【千锤百炼Python】【深度学习】【排序算法】    本来想着多更新一些关于深度学习的文章,但这方面知识专业度很高,如果作者本身都掌握不好,又怎么能写出好文章分享

    2024年02月07日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包