完整代码及解析!!手写数字识别系统(手写数字测试识别 + pytoch实现 + 完整代码及解析)

本文介绍了使用PyTorch实现手写数字识别系统的实验过程,包括网络模型LeNet5的构建、数据集的处理、模型训练与验证。实验采用MNIST数据集,通过卷积层、池化层和全连接层构建网络,训练过程中应用交叉熵损失函数和随机梯度下降优化器,最终在测试集上评估模型性能。
摘要由CSDN通过智能技术生成

基于深度学习的手写数字识别系统

一、实验目的

​ 1、任选实验环境及深度学习框架,实现手写数字识别系统;

​ 2、掌握所采用的深度血迹框架构建方式。

二、实验理论基础

1、MNIST数据集

​ MNIST 数据集来自美国国家标准与技术研究所, National Institute of Standards and Technology (NIST). 包含四个部分:

​ (1)Training set images:train-images-idx3-ubyte.gz(9.9MB,解压后47MB,包含60000个样本)

​ (2)Training set labels:train-labels-idx1-ubyte.gz(29KB,解压后60KB,包含60000个样本)

​ (3)Test set images:t10k-images-idx3-ubyte.gz(1.6MB,解压后7.8MB,包含10000个样本)

​ (4)Test set labels:t10k-labels-idx1-ubyte.gz(5KB,解压后10KB,包含10000个样本)

​ 训练集 (training set) 由来自 250 个不同人手写的数字构成, 其中 50% 是高中学生, 50% 来自人口普查局 (the Census Bureau) 的工作人员. 测试集(test set) 也是同样比例的手写数字数据。图片是以字节的形式进行存储, 我们需要把它们读取到 NumPy array 中, 以便训练和测试算法.

​ 可以建立一个Mnist文件夹,将下载的数据集放入此文件夹中,方便处理

2、数据集中训练集、验证集和测试集的作用

​ 使用了所有的原始数据去训练模型,得到的结果很可能是该模型最大程度地拟合了原始数据,亦即该模型是为了拟合所有原始数据而存在。当新的样本出现,再使用该模型进行预测,效果可能还不如只使用一部分数据训练的模型。因此,为了防止模型过拟合,对原始数据进行了三个数据集的划分。

​ (1)训练集:作用是用来拟合模型,通过设置分类器的参数,训练分类模型。后续结合验证集作用时,会选出同一参数的不同取值,拟合出多个分类器。手写数字识别系统中是用训练集中的images,进行检测,用labels与之对应,使得网络形成记忆。

​ (2)验证集:作用是当通过训练集训练出多个模型后,为了能找出效果最佳的模型,使用各个模型对验证集数据进行预测,并记录模型准确率。选出效果最佳的模型所对应的参数,即用来调整模型参数。

​ (3)测试集:通过训练集和验证集得出最优模型后,使用测试集进行模型预测。用来衡量该最优模型的性能和分类能力。即可以把测试集当做从来不存在的数据集,当已经确定模型参数后,使用测试集进行模型性能评价。在手写数字识别系统中是将测试集中的images输入网络,并将结果与labels比较,用于计算测试集准确率。

三、实验内容

1、 网络模型搭建;

​ 网络一共有7层,分别是《卷积层–池化层–卷积层–池化层–全连接层–全连接层–全连接层》;

​ (1)输入是一个单通道28*28大小的手写数字图片;

​ (2)定义卷积层1,输入通道为1,卷积核数为6,卷积核大小为5*5,池化层1,池化核大小为2*2;

​ (3)定义卷积层2,输入通道为6,卷积核数为16,卷积核大小为5*5,池化层2,池化核大小为2*2;

​ (4)全连接层1、2、3;

​ (5)定义前向传播顺序。

class LeNet5(nn.Module):
    def __init__(self):  # 初始化函数
        super(LeNet5,self).__init__()# 多基层一般使用super
        self.conv1 = nn.Conv2d(1, 6, 5)# 定义第一个卷积层,1是通道数灰度图片,6是卷积核个数,5卷积核大小
        self.pool1 = nn.MaxPool2d(2, 2)# 池化核大小2*2,步距也为2,池化层,只改变高和宽,深度不改变
        self.conv2 = nn.Conv2d(6, 16, 5)# 输入变为6,因为通过第一个卷积层有6个卷积核,输出深度为6
        self.pool2 = nn.MaxPool2d(2, 2)
        self.fc1 = nn.Linear(16*4*4, 120) # 展开成一维的,第一层120个节点,输入16*4*4个节点
        self.fc2 = nn.Linear(120, 84) # 输入120,设置84个节点
        self.fc3 = nn.Linear(84, 10) # 输出根据训练集修改
    def forward(self,x):
        x = self.pool1(F.relu(self.conv1(x))) # input(1,28,28),output1(6,24,24) output2(6,12,12)
        x = self.pool2(F.relu(self.conv2(x))) # input(6,12,12),output1(16,8,8) output2(16,4,4)
        x = x.view(-1, 16*4*4) # -1第一个维度
        x = F.relu(self.fc1(x)) # 全连接层1及其激活函数
        x = F.relu(self.fc2(x)) # 全连接层3得到输出
        x = self.fc3(x)
        return x
2、 数据集模型搭建 ;

​ 构建数据集模型是为了在之后的训练和测试中方便对数据集的调用。

​ (1)定义Dataset类型的数据集Mnist,设置三个参数root、train、transform,其中root是需要调用的数据的储存路径,利用train是否为true,判断调用的数据为训练集还是测试集。

class Mnist(Dataset):
    def __init__(self, root, train=True, transform=None):

        # 根据是否为训练集,得到文件名前缀
        self.file_pre = 'train' if train == True else 't10k'
        self.transform = transform#定义变换函数

        # 生成对应数据集的图片和标签文件路径
        self.label_path = os.path.join(root,
                                       '%s-labels-idx1-ubyte.gz' % self.file_pre)
        self.image_path = os.path.join(root,
                                       '%s-images-idx3-ubyte.gz' % self.file_pre)

        # 读取文件数据,返回图片和标签
        self.images, self.labels = self.__read_data__(
            self.image_path,
            self.label_path)

​ (2)定义__read_data__函数,将data以流的形式读入转化成ndarray对象,ndarray对象是用于存放同类型元素的多维数组,利用reshape函数将图片以标签文件的元素个数读取,设置大小为28*28。

    def __read_data__(self, image_path, label_path):
        # 数据集读取
        with gzip.open(label_path, 'rb') as lbpath:
            labels = np.frombuffer(lbpath.read(), np.uint8,
                                   offset=8)#将data以流的形式读入转化成ndarray对象,ndarray对象是用于存放同类型元素的多维数组
        with gzip.open(image_path, 'rb') as imgpath:
            images = np.frombuffer(imgpath.read(), np.uint8,
                                   offset=16).reshape(len(labels), 28, 28)#将图片以标签文件的元素个数读取,设置大小为28*28
        return images, labels

​ (3)利用transform函数,将numpy.ndarray类型数据转化为张量。

        # 如果需要转成 tensor,(RGB,HWC)张量, 则使用 tansform
        if self.transform is not None:
            image = self.transform(np.array(image))  # 此处需要用 np.array(image),转化为数组
        return image, label     
3、 训练模型搭建;

​ (1)利用定义的Mnist数据集生成训练集,同时利用DataLoader函数,将训练集中的元素随机排序后,以batch_size=32大小返回。

# 生成训练集
train_set = Mnist(
    root=r'E:\CUDA\Dataset\Mnist',
    train=True,#训练集
    transform=transforms.Compose([#Compose方法是将多种变换组合在一起。
        transforms.ToTensor(),#函数接受PIL Image或numpy.ndarray,将其先由HWC转置为CHW格式
        transforms.Normalize((0.1037,), (0.3081,))#灰度图像,一个通道,均值和方差,标准化
    ])
)
train_loader = DataLoader(#主要用来将自定义的数据读取接口的输出或者PyTorch已有的数据读取接口的输入按照batch size封装成Tensor
    dataset=train_set,#输出的数据
    batch_size=32,
    shuffle=True)#将元素随机排序

​ (2)实化一个定义好的网络,并将网络放进GPU中,定义损失函数和优化器,用来训练网络模型。

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")#判断能否调用GPU
print(device)
# 实例化一个网络
net = LeNet5().to(device) #将网络放进GPU
# 定义损失函数和优化器
loss_function = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(
    net.parameters(),#网络参数
    lr=0.001,#学习率
    momentum=0.9#Momentum 用于加速 SGD(随机梯度下降)在某一方向上的搜索以及抑制震荡的发生。
)

​ (3)定义训练模型,设置训练10个epoch,在每个epoch中每300个batch打印一次平均损失值,,将训练好的模型保存,打印每次训练后的损失值变化曲线。

# 3 训练模型
loss_list = []#保存损失函数的值
for epoch in range(10):#训练10次
    running_loss = 0.0#误差清零?
    for batch_idx, data in enumerate(train_loader, start=0):#enumerate索引函数,start下标开始位置

        images, labels = data                       # 读取一个batch的数据
        images=images.to(device)  #将images放进GPU
        labels=labels.to(device)  #将labels放进GPU
        optimizer.zero_grad()                       # 梯度清零,初始化,如果不初始化,则梯度会叠加
        outputs = net(images)                      # 前向传播
        loss = loss_function(outputs, labels)       # 计算误差,label标准?
        loss.backward()                             # 反向传播
        optimizer.step()                            # 权重更新
        running_loss += loss.item()                 # 误差累计

        # 每300个batch 打印一次损失值
        if batch_idx % 300 == 299:#(0-299)(300-599)
            print('epoch:{} batch_idx:{} loss:{}'
                  .format(epoch+1, batch_idx+1, running_loss/300))
            loss_list.append(running_loss/300)#将新的每个平均误差加到损失函数列表后面
            running_loss = 0.0                  #误差清零
print('Finished Training.')
torch.save(net.state_dict(),"Linear.pth")#保存训练模型
# 打印损失值变化曲线
import matplotlib.pyplot as plt
plt.plot(loss_list)
plt.title('traning loss')
plt.xlabel('epochs')
plt.ylabel('loss')
plt.show()

​ (4)对训练好的网络进行测试,生成测试集的方法如同生成训练集的方法,记录通过网络预测正确的图片数和总图片数,将测试集中images、labels数据送入GPU中,images输入网络,将输出outputs与labels比较,得到预测正确的数目correct,输出测试集准确率。在测试集images中选取前10个数据,进行预测,并于对应labels比较。

# 测试
test_set = Mnist(#生成测试集
    root='E:\CUDA\Dataset\Mnist',
    train=False,
    transform=transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1037,), (0.3081,))
    ])
)
test_loader = DataLoader(
    dataset=test_set,
    batch_size=32,
    shuffle=True
)
correct = 0  # 预测正确数
total = 0    # 总图片数
for data in test_loader:
    images, labels = data
    images=images.to(device)
    labels=labels.to(device)
    outputs = net(images)
    _, predict = torch.max(outputs.data, 1)#1是指按行,0是按列,-1是指最后一个维度,一般也是按行
    total += labels.size(0)
    correct += (predict == labels).sum()
print('测试集准确率 {}%'.format(100*correct // total))
#检测网络
test_output=net(images[:10])#在测试集中选择10张图片输入网络,得到结果
pred_y = torch.max(test_output, 1)[1].data#对得到的结果进行预测
print(pred_y, 'prediction numbe')#输出预测结果
print(labels[:10], 'real number')#输出真实结果
4、 验证模型搭建;

​ (1)调用训练好的网络,生成测试集,从测试集images数据中选取前10个图片输入网络,将预测结果和真实结果输出,并将这10个images数据绘制出来进行比较。

net=LeNet5()
net.load_state_dict(torch.load("Linear.pth"))#调用训练好的网络
test_set = Mnist(#生成测试集
    root='E:\CUDA\Dataset\Mnist',
    train=False,
    transform=transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1037,), (0.3081,))
    ])
)
test_loader = DataLoader(
    dataset=test_set,
    batch_size=32,
    shuffle=True)
for data in test_loader:
    images, labels = data
#检测网络
test_output=net(images[:10])#在测试集中选择10张图片输入网络,得到结果
pred_y = torch.max(test_output, 1)[1].data#对得到的结果进行预测
print(pred_y, 'prediction numbe')#输出预测结果
print(labels[:10], 'real number')#输出真实结果
def plt_image(image):#定义一个函数,将需要预测的手写数字图画出来
    n = 10
    plt.figure(figsize=(10,4))
    for i in range(n):
        ax = plt.subplot(2,5,i+1)
        plt.imshow(images[i].reshape(28,28))
        plt.gray()
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
    plt.show()
plt_image(images)

​ (2)测试自己手动设计的手写数字

I = Image.open('7.jpg')
L = I.convert('L')#转化为二值图像
plt.imshow(L, cmap='gray')
transform=transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1037,), (0.3081,))
])
im = transform(L)  # [C, H, W]
im = torch.unsqueeze(im, dim=0)  # [N, C, H, W],扩展维度
with torch.no_grad():
    outputs = net(im)
    _, predict = torch.max(outputs.data, 1)
    print(predict)

四、附件

1、实验环境

​ (1)编程语言:python 3.6.12

​ (2)编程环境:spyder

​ (3)深度学习框架:pytorch 1.7.0

​ (4)系统环境:64位Windows系统

2、实验源码
(1)数据集模块data.py
import os
import numpy as np
from torch.utils.data import Dataset
import gzip
import matplotlib.pyplot as plt#绘图库

class Mnist(Dataset):
    def __init__(self, root, train=True, transform=None):
        # 根据是否为训练集,得到文件名前缀
        self.file_pre = 'train' if train == True else 't10k'
        self.transform = transform#定义变换函数
        # 生成对应数据集的图片和标签文件路径
        self.label_path = os.path.join(root,
                                       '%s-labels-idx1-ubyte.gz' % self.file_pre)
        self.image_path = os.path.join(root,
                                       '%s-images-idx3-ubyte.gz' % self.file_pre)
        
        # 读取文件数据,返回图片和标签
        self.images, self.labels = self.__read_data__(
            self.image_path,
            self.label_path)

    def __read_data__(self, image_path, label_path):
        # 数据集读取
        with gzip.open(label_path, 'rb') as lbpath:
            labels = np.frombuffer(lbpath.read(), np.uint8,
                                   offset=8)#将data以流的形式读入转化成ndarray对象,ndarray对象是用于存放同类型元素的多维数组
        with gzip.open(image_path, 'rb') as imgpath:
            images = np.frombuffer(imgpath.read(), np.uint8,
                                   offset=16).reshape(len(labels), 28, 28)#将图片以标签文件的元素个数读取,设置大小为28*28
        return images, labels

    def __getitem__(self, index):#迭代使用?使用Minist()会调用_getitem_
        image, label = self.images[index], int(self.labels[index])

        # 如果需要转成 tensor,(RGB,HWC)张量, 则使用 tansform
        if self.transform is not None:
            image = self.transform(np.array(image))  # 此处需要用 np.array(image),转化为数组
        return image, label

    def __len__(self):#获取元素个数
        return len(self.labels)

if __name__ == '__main__':
    # 生成实例
    train_set = Mnist(
        root=r'E:\CUDA\Dataset\Mnist',#MNIST数据集路径
        train=False,
    )
    # 取一组数据并展示
    (data, label) = train_set[0]#第一组数据
    plt.imshow(data.reshape(28, 28), cmap='gray')#灰色图像
    plt.title('label is :{}'.format(label))
    plt.show()
(2)网络模型模块model.py
import torch.nn as nn
import torch.nn.functional as F

class LeNet5(nn.Module):
    def __init__(self):  # 初始化函数
        super(LeNet5,self).__init__()# 多基层一般使用super
        self.conv1 = nn.Conv2d(1, 6, 5)# 定义第一个卷积层,1是通道数灰度图片,6是卷积核个数,5卷积核大小
        self.pool1 = nn.MaxPool2d(2, 2)# 池化核大小2*2,步距也为2,池化层,只改变高和宽,深度不改变
        self.conv2 = nn.Conv2d(6, 16, 5)# 输入变为6,因为通过第一个卷积层有6个卷积核,输出深度为6
        self.pool2 = nn.MaxPool2d(2, 2)
        self.fc1 = nn.Linear(16*4*4, 120) # 展开成一维的,第一层120个节点,输入16*4*4个节点
        self.fc2 = nn.Linear(120, 84) # 输入120,设置84个节点
        self.fc3 = nn.Linear(84, 10) # 输出根据训练集修改
    
    def forward(self,x):
        x = self.pool1(F.relu(self.conv1(x))) # input(1,28,28),output1(6,24,24) output2(6,12,12)
        x = self.pool2(F.relu(self.conv2(x))) # input(6,12,12),output1(16,8,8) output2(16,4,4)
        x = x.view(-1, 16*4*4) # -1第一个维度
        x = F.relu(self.fc1(x)) # 全连接层1及其激活函数
        x = F.relu(self.fc2(x)) # 全连接层3得到输出
        x = self.fc3(x)
        return x

if __name__ == '__main__':
    net = LeNet5()
    print(net)
(3)训练模块train.py
import torch
import torchvision.transforms as transforms
import torch.optim as optim#优化器
from torch.utils.data import DataLoader
from data import Mnist
from model import LeNet5

# 生成训练集
train_set = Mnist(
    root=r'E:\CUDA\Dataset\Mnist',
    train=True,#训练集
    transform=transforms.Compose([#Compose方法是将多种变换组合在一起。
        transforms.ToTensor(),#函数接受PIL Image或numpy.ndarray,将其先由HWC转置为CHW格式
        transforms.Normalize((0.1037,), (0.3081,))#灰度图像,一个通道,均值和方差,标准化
    ])
)
train_loader = DataLoader(#主要用来将自定义的数据读取接口的输出或者PyTorch已有的数据读取接口的输入按照batch size封装成Tensor
    dataset=train_set,#输出的数据
    batch_size=32,
    shuffle=True#将元素随机排序
)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")#判断能否调用GPU
print(device)
# 实例化一个网络
net = LeNet5().to(device) #将网络放进GPU

# 定义损失函数和优化器
loss_function = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(
    net.parameters(),#网络参数
    lr=0.001,#学习率
    momentum=0.9#Momentum 用于加速 SGD(随机梯度下降)在某一方向上的搜索以及抑制震荡的发生。
)

# 3 训练模型
loss_list = []#保存损失函数的值
for epoch in range(10):#训练10次
    running_loss = 0.0#误差清零?
    for batch_idx, data in enumerate(train_loader, start=0):#enumerate索引函数,start下标开始位置

        images, labels = data                       # 读取一个batch的数据
        images=images.to(device)  #将images放进GPU
        labels=labels.to(device)  #将labels放进GPU
        optimizer.zero_grad()                       # 梯度清零,初始化,如果不初始化,则梯度会叠加
        outputs = net(images)                      # 前向传播
        loss = loss_function(outputs, labels)       # 计算误差,label标准?
        loss.backward()                             # 反向传播
        optimizer.step()                            # 权重更新
        running_loss += loss.item()                 # 误差累计

        # 每300个batch 打印一次损失值
        if batch_idx % 300 == 299:#(0-299)(300-599)
            print('epoch:{} batch_idx:{} loss:{}'
                  .format(epoch+1, batch_idx+1, running_loss/300))
            loss_list.append(running_loss/300)#将新的每个平均误差加到损失函数列表后面
            running_loss = 0.0                  #误差清零
print('Finished Training.')

torch.save(net.state_dict(),"Linear.pth")#保存训练模型

# 打印损失值变化曲线
import matplotlib.pyplot as plt
plt.plot(loss_list)
plt.title('traning loss')
plt.xlabel('epochs')
plt.ylabel('loss')
plt.show()

# 测试
test_set = Mnist(#生成测试集
    root='E:\CUDA\Dataset\Mnist',
    train=False,
    transform=transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1037,), (0.3081,))
    ])
)
test_loader = DataLoader(
    dataset=test_set,
    batch_size=32,
    shuffle=True
)
correct = 0  # 预测正确数
total = 0    # 总图片数
for data in test_loader:
    images, labels = data
    images=images.to(device)
    labels=labels.to(device)
    outputs = net(images)
    _, predict = torch.max(outputs.data, 1)#1是指按行,0是按列,-1是指最后一个维度,一般也是按行
    total += labels.size(0)
    correct += (predict == labels).sum()

print('测试集准确率 {}%'.format(100*correct // total))

#检测网络
test_output=net(images[:10])#在测试集中选择10张图片输入网络,得到结果
pred_y = torch.max(test_output, 1)[1].data#对得到的结果进行预测
print(pred_y, 'prediction numbe')#输出预测结果
print(labels[:10], 'real number')#输出真实结果
(4)测试模块test.py
import torch
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
from data import Mnist
from model import LeNet5
import matplotlib.pyplot as plt

net=LeNet5()
net.load_state_dict(torch.load("Linear.pth"))#调用训练好的网络

#检测网络
test_set = Mnist(#生成测试集
    root='E:\CUDA\Dataset\Mnist',
    train=False,
    transform=transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1037,), (0.3081,))
    ])
)
test_loader = DataLoader(
    dataset=test_set,
    batch_size=32,
    shuffle=True
)

for data in test_loader:
    images, labels = data
    
test_output=net(images[:10])#在测试集中选择10张图片输入网络,得到结果
pred_y = torch.max(test_output, 1)[1].data#对得到的结果进行预测
print(pred_y, 'prediction numbe')#输出预测结果
print(labels[:10], 'real number')#输出真实结果

def plt_image(image):#定义一个函数,将需要预测的手写数字图画出来
    n = 10
    plt.figure(figsize=(10,4))
    for i in range(n):
        ax = plt.subplot(2,5,i+1)
        plt.imshow(images[i].reshape(28,28))
        plt.gray()
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
    plt.show()
plt_image(images)

# 测试自己手动设计的手写数字
from PIL import Image
I = Image.open('2.jpg')
L = I.convert('L')#转化为二值图像
plt.imshow(L, cmap='gray')

transform=transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1037,), (0.3081,))
])    
im = transform(L)  # [C, H, W]
im = torch.unsqueeze(im, dim=0)  # [N, C, H, W],扩展维度
with torch.no_grad():
    outputs = net(im)
    _, predict = torch.max(outputs.data, 1)
    print(predict)
### 回答1: minist手写数字识别pytorch是一种基于PyTorch框架的手写数字识别模型。该模型可以识别到9的手写数字,并且在训练集和测试集上都有很好的表现。它的实现过程包括数据预处理、模型构建、模型训练和模型测试等步骤。通过使用PyTorch框架,可以方便地实现深度学习模型,并且可以利用GPU加速训练过程,提高模型的训练效率。 ### 回答2: 在现代机器学习的技术中,手写数字识别是一个相对简单的问题。然而,它的理论和技术都是非常有价值的。这个问题的目标是给机器一个图像,让它预测图像上的数字。这个任务对于许多现实世界的应用非常有用,例如自动识别支票或信用卡上的数字等。 Minist手写数字识别是一个流行的经典问题,它的目标是识别0-9的手写数字。这项任务已经在经典计算机视觉算法的研究中经常出现,被广泛使用,并且是许多机器学习算法和模型的基础。在这里,我们将使用PyTorch实现这个任务。 首先,需要下载Minist数据集并准备数据。Minist数据集包含了70,000张28x28的灰度图像,每张图像代表了0到9之间的一个数字。数据集被分成了两个部分:60,000张图像用于训练,剩下的10,000张图像用于测试。 我们将使用PyTorch来构建一个卷积神经网络(CNN)来解决这个问题。这个CNN包括两个卷积层和两个全连接层。卷积层用于提取图像特征,它们通过卷积和池化操作将图像转换为低维的特征表示。全连接层则将这些特征映射到数字标签。 在训练CNN之前,我们需要对图像进行预处理和标准化。然后,我们将定义损失函数,优化器和学习率计划,以便在训练期间或在测试期间为CNN提供足够的准确性。 最后,我们将使用测试数据集来评估CNN的性能。为了更好的评估模型的性能,我们还可以使用k-fold交叉验证技术,以确保我们的CNN是健壮和可靠的。 总而言之,使用PyTorch实现Minist手写数字识别是一个非常有趣和有收获的挑战。它不仅可以帮助我们了解机器学习中的经典问题,还可以帮助我们掌握深度学习技术和PyTorch的应用。 ### 回答3: Minist手写数字识别深度学习领域中一个经典的问题。它的主要目标是通过机器学习的方法识别并分类手写数字。传统的机器学习方法使用手动设计的特征,但这种方法在处理高维、非线性数据时效果不理想。近年来,深度学习的发展使得自动学习特征成为可能,从而为Minist手写数字识别提供了新的解决方案。 在深度学习领域中,PyTorch是一种非常流行的框架,具有很强的灵活性和扩展性,被广泛用于各种机器学习问题的解决。PyTorch可以支持多种神经网络模型,包括卷积神经网络(CNN),循环神经网络(RNN)等。在Minist手写数字识别中,最常用的是CNN模型,因为CNN模型具有非常好的图像处理能力。而PyTorch中的CNN模型则可以通过简单的代码实现,下面是一个简单的CNN模型的代码: class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 10, kernel_size=5) self.conv2 = nn.Conv2d(10, 20, kernel_size=5) self.fc1 = nn.Linear(320, 50) self.fc2 = nn.Linear(50, 10) def forward(self, x): x = F.relu(F.max_pool2d(self.conv1(x), 2)) x = F.relu(F.max_pool2d(self.conv2(x), 2)) x = x.view(-1, 320) x = F.relu(self.fc1(x)) x = self.fc2(x) return F.log_softmax(x, dim=1) 这个CNN模型包括两个卷积层(conv1和conv2)和两个全连接层(fc1和fc2)。其中,卷积层和全连接层都是通过PyTorch中的类来定义的。在forward()函数中,卷积和像素池化操作被串连在一起,用于从图像中提取特征。这些特征被展平并传递到全连接层中进行分类。 在PyTorch中,使用Minist手写数字数据集进行训练非常简单,因为PyTorch内置了MNIST数据集,并且提供了数据加载和预处理函数。使用该数据集可以轻松地训练CNN模型并进行手写数字识别。 综上所述,基于PyTorch实现Minist手写数字识别的CNN模型是一种相对容易的方法。使用PyTorch的灵活性和扩展性,可以定义并训练高性能的模型,并且可以通过各种方式来提高模型的准确性。该模型还可以与其他深度学习技术结合使用,例如迁移学习和增强学习,以进一步提高性能。
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值