1 Star 4 Fork 1

Guojin Yan/手写数字识别_demo

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

手写数字识别

1. 项目简介

手写数字识别是指给定一系列的手写数字图片以及对应的数字标签,构建模型进行学习,目标是对于一张新的手写数字图片能够自动识别出对应的数字。图像识别是指利用计算机对图像进行处理,通过模型对其分析和理解,得到图片文件中所写的数字。

在人工智能领域,手写数字识别被问题转换为自动分类问题。将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

2. 数据集介绍

MNIST数据集是一个公开手手写数字识别数据集,该数据集由250个不同的人手写而成,总共有7000张手写数据集。其中训练集有6000张,测试集有1000张。每张图片大小为28x28,为处理后的灰度图,是由28x28个像素点组成。

Figure_1

上图为手写数字数据集中的部分图片。该数据集可以通过以下路径进行下载:MNIST (http://yann.lecun.com/exdb/mnist/) ;或者通过各种深度学习框架提供的API函数进行下载。

image-20220814175037775

通过官网下载的方式需要分别下载下图中的四个链接对应的文件,下载完成后,将文件解压到本地即可。

image-20220814175204076

下图为解压好的文件,该文件为处理后的二进制文件,不是现成的图片文件,不可以直接打开,需要进行处理才可以读取,后面会在Matlab训练手写数字识别模型处详细讲解该文件的读取方式。

image-20220814175308978

3. 数据集文件读取

数据集文件主要分两种:一种是图片数据文件,一种是分类标注文件。文件为二进制文件格式。

以训练集文件为例: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)

测试集读取方式类似,如有需要自行修改。

4. Python基于Pytorch框架实现模型训练

4.1 训练环境

CUDA 11.4

Pytorch 1.12.1+cu113

Python 3.9

4.2 定义数据加载器

新建一个数据加载器文件dataloader.py,用于加载训练数据,后续模型训练时通过数据加载器按批次加载训练集。

首先导入以下模块,该模块在安装torch模块后就可以使用。

import torchvision
from torch.utils.data import DataLoader

接下来定义一个class Dataloader()类,并初始化相关变量。主要设置训练集、测试集批次大小即可,后面我们直接调用Pytorch的MNIST数据集 API 接口加载数据集,所以需要定义的变量较少。

'''
    数据集加载类
    功能:
    实现数据集本地读取,并将数据集按照指定要求进行预处理;
    后续模型训练直接调用DataLoader逐步进行训练
    初始化参数:
    batch_size_train:训练集批次
    batch_size_test:测试集批次
'''
class Dataloader():
    def __init__(self,batch_size_train, batch_size_test):
        # 初始化训练集bath size
        self.batch_size_train = batch_size_train
        # 初始化测试集bath size
        self.batch_size_test = batch_size_test
   

分别定义训练集加载器train_loader()以及test_loader(),用于加载训练集以及测试集。torchvision.datasets.MNIST()是Pytorch提供的MNIST数据集加载接口API函数:'./Datasets/'为指定的数据集本地下载路径;download可以设置是否下载数据集,当指定为True且首次运行时,会将数据集下载到指定的路径下,再次运行时会检测路径下是否有该文件,如果有会直接读取,如果没有将会重新下载;transform指定的为数据处理方式,主要是将数据进行归一化以及数据类型转换处理,还可以对数据进行增强处理;batch_size指定训练时数据集加载的批次大小。

#加载训练集
def train_loader(self):
    # 调用pytorch自带的DataLoader方法加载MNIST训练集;
    # 直接使用pytorch的MNIST数据集API接口加载数据,
    # 第一次使用可以设置为True
    train_load = DataLoader(
        torchvision.datasets.MNIST('./Datasets/', train=True, download=True,
                                transform=torchvision.transforms.Compose([
                                    torchvision.transforms.ToTensor(),
                                    torchvision.transforms.Normalize(
                                        (0.1307,), (0.3081,))
                                ])),
        batch_size = self.batch_size_train, shuffle=True)
    return train_load
#加载测试集
def test_loader(self):
    # 调用pytorch自带的DataLoader方法加载MNIST测试集
    test_load = DataLoader(
        torchvision.datasets.MNIST('./Datasets/', train=False, download=True,
                                transform=torchvision.transforms.Compose([
                                    torchvision.transforms.ToTensor(),
                                    torchvision.transforms.Normalize(
                                        (0.1307,), (0.3081,))
                                ])),
        batch_size = self.batch_size_test, shuffle=True)
    return test_load

4.3 定义网络(net,py)

接下来定义训练网络,要实现后面我们的网络能够很好的识别我们的手写数字,在此处就要定义一个比较好的网络,下面的网络是我参考的网上一些人所做的模型定义的。

首先导入一下模块:torch.nn 模块下定义了各种我们常见的网络层以及网络结构,直接调用该模块进行网络构建;torch.nn.functional模块是定义了各种激活函数的模块。

import torch.nn as nn
import torch.nn.functional as F

我们将网络定义到Net类中,继承``nn.Module`''类模板。在初始化时定义一些在前向传播中所用到的网络层,方便再后面直接使用。

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        '''定义相关的计算层'''
        # 定义一个卷积核为1×10的卷积层
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        # 定义一个卷积核为10×20的卷积层
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        # 定义一个二维的Dropout2层,防止模型训练时过拟合
        self.conv2_drop = nn.Dropout2d()
        # 定义全连接层
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)

我们在此处模拟网络的前向传播,定义一个简单的网络,有两步卷积运算以及两步全连接组成。卷积运算有卷积->池化->激活三步组成,其中为了防止网络出现过拟合,增加了Dropout层。

    def forward(self, x):
        # 一次卷积运算
        x = self.conv1(x)
        x = F.max_pool2d(x, 2)
        x = F.relu(x)
        # 二次卷积运算
        x = self.conv2(x)
        x = self.conv2_drop(x)
        x = F.max_pool2d(x,2)
        x = F.relu(x)
        # 设置数据长度
        x = x.view(-1, 320)
        # 一次全连接
        x = self.fc1(x)
        x = F.relu(x)
        x = F.dropout(x, training=self.training)
        # 二次全连接
        x = self.fc2(x)
        # 分类模型调用分类结果处理函数
        return F.log_softmax(x) 

以下模型结构图为训练完成的模型转为ONNX模型的结构图。

image-20220816213329067

4.4 定义训练器(trainer.py)

训练器主要是将构建好的模型以及训练集进行训练,实现对训练过程数据的记录以及训练模型的保存。在此处我们将其封装到trainer.py文件中Trainer()类中。

首先导入以下模块:

from torch.utils.tensorboard import SummaryWriter
import torch
import torch.nn as nn
import torch.optim as optim
import time

tensorboard是一个外部插件,用于保存训练过程的数据并进行可视化显示,在使用时需要自行安装,他不在Pytorch软件包中。

接下来就是创建Trainer()类,在该类的初始化方法中,我们主要实现了对一些成员变量进行赋值,并且初始化后面训练的相关成员变量。

class Trainer():
    def __init__(self, network, learning_rate, log_interval):
        # 初始化网络
        self.network = network
        # 初始化学习率
        self.learning_rate = learning_rate
        # 初始化优化器
        self.optimizer = optim.SGD(network.parameters(), lr=learning_rate)
        # 初始化日志打印间隔
        self.log_interval = log_interval
        # 初始化损失函数
        self.loss_fn = nn.CrossEntropyLoss()
        # 当CUDA可用时,开启CUDA加速
        if torch.cuda.is_available():
              self.loss_fn =   self.loss_fn.cuda()
        # 初始化tensorboard日志保存接口
        self.writer = SummaryWriter("Python/logs_train")
        # 初始准确率
        self.accuracy = 0

下面为模型训练方法,主要实现模型训练、模型测试、日志保存与打印、模型保存与打印等功能。具体过程可以根据代码解释进行理解。

    def tarin(self, epoch, train_loader, test_loader):
        # 训练和测试的总步数
        total_train_step = 0
        total_test_step = 0
        # 获取当前时间
        now =  time.localtime()
        # 创建日志
        log_text=open("Python/logs_train/{}.txt".format(time.strftime("%Y_%m_%d_%H_%M", now)),mode='w')
        log_text.write("模型训练时间:{}".format(time.strftime("%Y-%m-%d %H:%M:%S", now)))
        log_text.write('\r\n')
        for i in range(epoch):
            # 模型训练
            print("--------第{}轮训练开始--------".format(i))
            log_text.writelines("--------第{}轮训练开始--------".format(i))
            log_text.write('\r\n')
            self.network.train()
            '''
                模型训练步骤:
                1.在DataLoader中读取bath_size个数据,包括模型输入和目标输出
                2.带入到网络中计算
                3.带入损失函数,计算损失
                4.模型反向传播
                5.执行单个优化步骤
                6.重复上面过程,反复训练
            '''
            for batch_idx, (data, target) in enumerate(train_loader):
                self.optimizer.zero_grad()
                # 当可以使用CUDA加速时,将data、target转为CUDA格式
                if torch.cuda.is_available():
                    data = data.cuda()
                    target = target.cuda()
                # 带入网络计算,前向传播
                output = self.network(data)
                # 带入损失函数计算
                loss = self.loss_fn(output,target)
                # 反向传播
                loss.backward()
                # 执行单个优化步骤
                self.optimizer.step()
                total_train_step +=1
                if batch_idx % self.log_interval == 0:
                    # 打印训练过程日志
                    print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                        i, batch_idx * len(data), len(train_loader.dataset),
                            100. * batch_idx / len(train_loader), loss.item()))
                    # 写入txt日志文件
                    log_text.writelines('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                        i, batch_idx * len(data), len(train_loader.dataset),
                            100. * batch_idx / len(train_loader), loss.item()))
                    log_text.write('\r\n')
                    # 将训练结果写入tensorboard日志中
                    self.writer.add_scalar("train_loss",loss.item(),total_train_step)
            #模型测试
            print("--------第{}轮测试开始--------".format(i))
            log_text.write("--------第{}轮测试开始--------".format(i))
            log_text.write('\r\n')
            total_test_loss = 0
            total_accuracy = 0
            accuracy = 0
            with torch.no_grad():# with以下的代码不会更改
                for batch_idx, (data, target) in enumerate(test_loader):
                    # 当可以使用CUDA加速时,将data、target转为CUDA格式
                    if torch.cuda.is_available():
                        data = data.cuda()
                        target = target.cuda()
                    # 带入模型计算
                    outputs = self.network(data)
                    # 带入损失函数计算下损失
                    loss = self.loss_fn(outputs,target)
                    # 计算总损失
                    total_test_loss = total_test_loss + loss.item()
                    # 计算准确率
                    accuracy = (outputs.argmax(1) == target).sum()
                    # 总的准确率
                    total_accuracy = total_accuracy + accuracy
            accuracy = total_accuracy / len(test_loader.dataset)
            # 保存结果最好的模型
            if(self.accuracy < accuracy):
                torch.save(self.network, "Python/best_model.pth".format(i))
                print("best_model.pth 保存成功")
                log_text.writelines("best_model.pth 保存成功")
                log_text.write('\r\n')
            self.accuracy = accuracy

            print("整体测试集上的Loss:{}".format(total_test_loss))
            print("整体测试集上的正确率:{}".format(self.accuracy))
            log_text.writelines("整体测试集上的Loss:{}".format(total_test_loss))
            log_text.write('\r\n')
            log_text.writelines("整体测试集上的正确率:{}".format(self.accuracy))
            log_text.write('\r\n')
            self.writer.add_scalar("test_loss",total_test_loss,total_test_step)
            self.writer.add_scalar("test_accuracy",total_accuracy / len(test_loader.dataset),total_test_step)
            total_test_step = total_test_step + 1

            # 保存该轮模型
            torch.save(self.network, "Python/model_{}.pth".format(i))
            # torch.save(self.optimizer.state_dict(), "optimizer_{}.pth".format(i))
            print("第{}轮模型保存成功".format(i+1))
            log_text.writelines("第{}轮模型保存成功".format(i)) 
        print("----------模型训练结束-----------")     
        log_text.writelines("----------模型训练结束-----------")
        log_text.write('\r\n')
        log_text.close()

4.5 模型训练(main_MNIST.py)

前面我们已经定义好了训练所使用的相关模块,下面我们我们调用相应的依赖项以及文件进行模型的训练。

首先导入相关的模块:

import torch
import matplotlib.pyplot as plt

接下来引入我们前面构建的类:

from dataloader import Dataloader
from net import Net
from trainer import Trainer

然后定义模型训练的相关设置参数:

'''---------设置相关训练参数---------'''
n_epochs = 1             # 训练轮次
batch_size_train = 8   # 训练集batchSize
batch_size_test = 8  # 测试集batchSize
learning_rate = 0.01    # 学习率
momentum = 0.5          # 动量、冲量
log_interval = 100       # 日志打印间隔次数
random_seed = 1         # 随机种子数

读取本地训练集以及测试集:

'''---------初始化训练集和测试集---------'''
# CPU和GPU设置随机种子
torch.manual_seed(random_seed)
# 初始化数据加载
dataloader = Dataloader(batch_size_train = batch_size_train, batch_size_test = batch_size_test)
# 定义训练集加载器
train_loader = dataloader.train_loader()
# 定义测试集加载器
test_loader = dataloader.test_loader()

我们可以读取数据集中的几张图片,来查看我们所要使用的数据集:

'''---------查看数据集---------'''
examples = enumerate(test_loader)
batch_idx, (example_data, example_targets) = next(examples)

fig = plt.figure()
print(example_data[0][0].size())
for i in range(6):
    plt.subplot(2,3,i+1)
    plt.tight_layout()
    plt.imshow(example_data[i][0], cmap='gray', interpolation='none')
    plt.title("Ground Truth: {}".format(example_targets[i]))
    plt.xticks([])
    plt.yticks([])
plt.show()

最后我们定义网络,并将其网络训练器中进行训练。

# 定义网络
network = Net()
# 设置工作模式
if torch.cuda.is_available():
    network = network.cuda()
# 加载模型训练器
trainer = Trainer(network, learning_rate, log_interval)
# 开始模型训练
trainer.tarin(epoch = n_epochs, train_loader = train_loader, test_loader = test_loader)

模型训练完后,模型文件保存到 Python文件夹下,日志文件保存到 Python/logs_train文件夹下。

5. Matlab深度学习模型训练

5.1 构建神经网络

我们首先构建我们训练所使用的网络,Matlab支持可视化构建神经网络,使用起来十分容易。

首先在APP中找到深度网络设计器,进去后新建一个网络文件。

image-20220819165358385

深度网络设计器功能页面如下图所示:

左侧为网络层库,这里包含我们在深度学上常见的所有网络,卷积网络层、序列网络层等,后面在使用的时候直接拖拽到中间的工作区即可。

中间是网络构建区域,在左侧拖拽进来的网络,我们根据顺序将其用连接线连接起来,只需要点住网络层下部输出点拖拽到下一层网络的上部输入点即可。

右侧为网络节层属性设置区域,一些网络层需要修改对应的参数以达到不同的效果。针对不同的网络层需要设置的参数可以查阅Matlab帮助手册。

image-20220819170031595

设计完网络后,点击生成代码,将代码导入到代码区。

image-20220819170203897

将导出的网络copy到function lgraph = Net()方法中

<img alt="image-20220819185351830">

下面是封装的一个网络结构生成的方法,可以通过替换tempLayers参数,来更换新的网络。

function lgraph = Net()
lgraph = layerGraph();
tempLayers = [
%% 第一种网络结构

%     imageInputLayer([28 28 1],"Name","imageinput")
%     convolution2dLayer([1 10],5,"Name","conv_1","Padding","same")
%     batchNormalizationLayer
%     maxPooling2dLayer([2 2],"Name","maxpool_1","Padding","same")
%     reluLayer("Name","relu_1")
%     convolution2dLayer([10 20],5,"Name","conv_2","Padding","same")
%     batchNormalizationLayer
%     dropoutLayer(0.5,"Name","dropout")
%     
%     maxPooling2dLayer([2 2],"Name","maxpool_2","Padding","same")
%     reluLayer("Name","relu_2")
%     fullyConnectedLayer(320,"Name","fc_1")
%     batchNormalizationLayer
%     fullyConnectedLayer(50,"Name","fc_2")
%     reluLayer("Name","relu_3")
%     dropoutLayer(0.5,"Name","dropout_2")
%     fullyConnectedLayer(10,"Name","fc")
%     softmaxLayer("Name","softmax")
%     classificationLayer("Name","classoutput")

%% 第二种网络结构

%     imageInputLayer([28 28 1])
%     
%     convolution2dLayer(3,8,'Padding','same')
%     batchNormalizationLayer
%     reluLayer
%     
%     maxPooling2dLayer(2,'Stride',2)
%     
%     convolution2dLayer(3,16,'Padding','same')
%     batchNormalizationLayer
%     reluLayer
%     
%     maxPooling2dLayer(2,'Stride',2)
%     
%     convolution2dLayer(3,32,'Padding','same')
%     batchNormalizationLayer
%     reluLayer
%     
%     fullyConnectedLayer(10)
%     softmaxLayer
%     classificationLayer

%% 第三种网络结构

    imageInputLayer([28 28 1])
    
    convolution2dLayer(5,10,"Name","conv_1","Padding","same")
    batchNormalizationLayer
    maxPooling2dLayer([2 2],"Name","maxpool_1","Padding","same")
    reluLayer("Name","relu_1")
    convolution2dLayer(5,20,"Name","conv_2","Padding","same")
    batchNormalizationLayer
    dropoutLayer(0.5,"Name","dropout_1")
    maxPooling2dLayer([2 2],"Name","maxpool_2","Padding","same")
    reluLayer("Name","relu_2")

    fullyConnectedLayer(50,"Name","fc_1")
    reluLayer("Name","relu_3")
    dropoutLayer(0.5,"Name","dropout_2")
    fullyConnectedLayer(10,"Name","fc_2")
    softmaxLayer("Name","softmax")
    classificationLayer("Name","classoutput")
    ];
lgraph = addLayers(lgraph,tempLayers);

% 清理辅助变量
clear tempLayers;

end

5.2 构建数据读取器

前面我们已经讲过手写数字数据集图片与标签的读取方式,在此处我们构建一个数据集加载方法,将数据集文件读取出来,后面我们在训练时使用。

%% 数据加载器方法
% 返回
function [train_X, train_Y,test_X, test_Y] = Dataloader()
fid = fopen('dataset\t10k-labels-idx1-ubyte', 'rb');
% 读取测试集标签
test_labels = fread(fid, inf, 'uint8', 'l');
test_labels = test_labels(9:end);
fclose(fid);
test_Y = categorical(test_labels);
% 读取训练集标签
fid = fopen('dataset\train-labels-idx1-ubyte', 'rb');
train_labels = fread(fid, inf, 'uint8', 'l');
train_labels = train_labels(9:end);
fclose(fid);
train_Y = categorical(train_labels);

% 读取训练集图像数据
fid = fopen('dataset\train-images-idx3-ubyte', 'rb');
train_images_data = fread(fid, inf, 'uint8', 'l');
train_images_data = train_images_data(17:end);
train_images_data = mapminmax(train_images_data',0,1)';
fclose(fid);
train_images = reshape(train_images_data,28,28,60000);
train_images = permute(train_images,[2 1 3]);
train_X(:,:,1,:) = train_images;

% 读取测试集图像数据
fid = fopen('dataset\t10k-images-idx3-ubyte', 'rb');
test_images_data = fread(fid, inf, 'uint8', 'l');
test_images_data = test_images_data(17:end);
fclose(fid);
test_images = reshape(test_images_data,28,28,10000);
test_images = permute(test_images,[2 1 3]);
test_X(:,:,1,:) = test_images;
end

5.3 网络训练

首先读取数据集,直接调用我们前面构建的数据集读取方法:

%% 获取数据集
[train_X, train_Y, test_X, test_Y] = Dataloader();

然后读取我们定义的网络

%% 定义网络
layers = Net();

接下来定义相关的训练参数

%% 设置网络训练配置
max_epochs = 3; % 训练轮次
min_batchSize = 8; % 分块尺寸
options = trainingOptions('adam', ...   % 求解器设定为ADAM,亚当(Adam)是神经网络算法的优化求解器
    'ExecutionEnvironment','gpu', ...   % 选择运行设备,gpu or cpu
    'MaxEpochs',max_epochs, ...         % 最大训练周期数
    'GradientThreshold',1, ...          % 梯度临界点,防止梯度爆炸
    'InitialLearnRate',0.01, ...       % 初始学习率
    'LearnRateSchedule','piecewise', ...
    'MiniBatchSize',min_batchSize, ...  % 分块尺寸
    'LearnRateDropPeriod',10, ...      % 学习率下降开始次数
    'LearnRateDropFactor',0.2, ...      % 200轮之后乘以0.2开始降低学习率
    'Verbose',0, ...
    'Plots','training-progress' ...     % 绘制训练过程
    );

最后训练网络

%% 网络训练
%doTraining = false;
doTraining = true;
if doTraining
    net = trainNetwork(train_X,train_Y,layers,options);
else
    load('MNIST_clas.mat','net');
end

%% 模型保存
save('MNIST_clas.mat','net')

网络训练开始后,由于我们设置了绘制训练过程,因此会出现训练季度图。该图主要提供给我们了训练过程的准确率以及损失大小,可以及时观察我们网络是否合理以及是否继续训练。

<img alt="image-20220819204057193">

以上就是在 Matlab深度学习模型训练过程

空文件

简介

整理的手写数字识别项目Pytorch以及matlab实现,给初学者使用案例。 展开 收起
Python 等 2 种语言
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/guojin-yan/MNIST_demo.git
git@gitee.com:guojin-yan/MNIST_demo.git
guojin-yan
MNIST_demo
手写数字识别_demo
master

搜索帮助