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

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

一、实验目的

​ 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)
  • 27
    点赞
  • 204
    收藏
    觉得还不错? 一键收藏
  • 22
    评论
很高兴回答您的问题。下面是基于PyTorch实现的MNIST手写数字识别代码示例: 首先,我们需要导入所需的 Python 库: ```python import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader from torchvision import datasets, transforms ``` 接着,我们可以定义一些超参数: ```python batch_size = 64 learning_rate = 0.01 epochs = 10 ``` 然后,我们可以对数据进行预处理: ```python transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) train_dataset = datasets.MNIST( root='./data', train=True, download=True, transform=transform) test_dataset = datasets.MNIST( root='./data', train=False, download=True, transform=transform) train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=True) ``` 接下来,我们可以构建模型: ```python class Net(nn.Module): def __init__(self): super().__init__() self.conv1 = nn.Conv2d(1, 32, kernel_size=5) self.conv2 = nn.Conv2d(32, 64, kernel_size=5) self.fc1 = nn.Linear(1024, 128) self.fc2 = nn.Linear(128, 10) def forward(self, x): x = nn.functional.relu(nn.functional.max_pool2d(self.conv1(x), 2)) x = nn.functional.relu(nn.functional.max_pool2d(self.conv2(x), 2)) x = x.view(-1, 1024) x = nn.functional.relu(self.fc1(x)) x = self.fc2(x) return nn.functional.log_softmax(x, dim=1) model = Net() ``` 接着,我们可以定义损失函数和优化器: ```python criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=learning_rate, momentum=0.5) ``` 最后,我们可以训练模型: ```python for epoch in range(epochs): for batch_idx, (data, target) in enumerate(train_loader): optimizer.zero_grad() output = model(data) loss = criterion(output, target) loss.backward() optimizer.step() if batch_idx % 250 == 0: print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) test_loss = 0 correct = 0 with torch.no_grad(): for data, target in test_loader: output = model(data) test_loss += criterion(output, target).item() pred = output.argmax(dim=1, keepdim=True) correct += pred.eq(target.view_as(pred)).sum().item() test_loss /= len(test_loader.dataset) print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format( test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) ``` 希望这段代码可以帮助您实现基于 PyTorch手写数字识别模型。如果您有任何问题或疑问,请随时提出。
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值