掘金 人工智能 05月30日 16:18
Pytorch实现mnist手写数字识别
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文记录了使用PyTorch框架实现MNIST手写数字识别项目的过程。项目基于卷积神经网络,对28x28像素的MNIST手写数字图像进行训练和测试。文章详细介绍了数据预处理、模型构建、训练过程、损失函数选择、优化器设置以及模型评估等环节。通过设置超参数、划分数据集、定义训练和测试函数,最终实现了对手写数字的有效识别,并可视化了训练过程中的准确率和损失变化。

🖼️ **数据准备与预处理**: 采用torchvision库下载MNIST数据集,并使用ToTensor()函数将图像数据转换为Tensor类型。数据集被划分为训练集和测试集,并使用DataLoader进行批量加载,设置batch_size为32,shuffle为True,用于训练集的打乱。

🧠 **模型构建**: 使用卷积神经网络(CNN)进行手写数字识别。网络结构包括卷积层、池化层和全连接层。卷积层1的核函数为3x3,池化层1的核函数为2x2。

⚙️ **训练过程**: 定义了train()函数,用于训练模型,其中包括前向传播、计算损失、反向传播和优化器更新。设置学习率为1e-2,优化器选择SGD。训练循环5轮,每轮都进行训练和测试,并记录训练和测试的准确率和损失。

📊 **结果评估与可视化**: 定义了test()函数,用于评估模型在测试集上的性能。使用matplotlib库可视化了训练过程中的准确率和损失变化,包括训练集和测试集。结果显示了模型在训练过程中的收敛情况。

这是用的卷积神经网络,每张图片大小为28乘28,一个batch为32。卷积层1,卷积层1的核函数为3乘3的矩阵,这样一张图片就经过卷积层1后就为26乘26大小,池化层1核函数为22的矩阵,2626的经过池化层1就变成了13乘13了。

运行截图

#引入库函数

import torchimport torch.nn as nnimport matplotlib.pyplot as pltimport torchvision

#设置硬件设备,如果有GPU则使用,没有则使用cpu

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")device

#从torch下载数据集

train_ds = torchvision.datasets.MNIST('data',                                       train=True,                                       transform=torchvision.transforms.ToTensor(), # 将数据类型转化为Tensor                                      download=True)                                      test_ds  = torchvision.datasets.MNIST('data',                                       train=False,                                       transform=torchvision.transforms.ToTensor(), # 将数据类型转化为Tensor                                      download=True)

#划分测试集、训练集

batch_size = 32train_dl = torch.utils.data.DataLoader(train_ds,                                        batch_size=batch_size,                                        shuffle=True)test_dl  = torch.utils.data.DataLoader(test_ds,                                        batch_size=batch_size)

#设置超参数

learn_rate = 1e-2 # 学习率opt        = torch.optim.SGD(model.parameters(),lr=learn_rate)

#使用面向对象定义训练的过程

def train(dataloader, model, loss_fn, optimizer):    size = len(dataloader.dataset)  # 训练集的大小,一共60000张图片    num_batches = len(dataloader)   # 批次数目,1875(60000/32)    train_loss, train_acc = 0, 0  # 初始化训练损失和正确率        for X, y in dataloader:  # 获取图片及其标签        X, y = X.to(device), y.to(device)                # 计算预测误差        pred = model(X)          # 网络输出        loss = loss_fn(pred, y)  # 计算网络输出和真实值之间的差距,targets为真实值,计算二者差值即为损失                # 反向传播        optimizer.zero_grad()  # grad属性归零        loss.backward()        # 反向传播        optimizer.step()       # 每一步自动更新                # 记录acc与loss        train_acc  += (pred.argmax(1) == y).type(torch.float).sum().item()        train_loss += loss.item()                train_acc  /= size    train_loss /= num_batches    return train_acc, train_loss

#编写测试函数

    size        = len(dataloader.dataset)  # 测试集的大小,一共10000张图片    num_batches = len(dataloader)          # 批次数目,313(10000/32=312.5,向上取整)    test_loss, test_acc = 0, 0        # 当不进行训练时,停止梯度更新,节省计算内存消耗    with torch.no_grad():        for imgs, target in dataloader:            imgs, target = imgs.to(device), target.to(device)                        # 计算loss            target_pred = model(imgs)            loss        = loss_fn(target_pred, target)                        test_loss += loss.item()            test_acc  += (target_pred.argmax(1) == target).type(torch.float).sum().item()    test_acc  /= size    test_loss /= num_batches    return test_acc, test_loss

#训练5轮,将训练的参数带入写的面向对象的训练方法

epochs     = 5train_loss = []train_acc  = []test_loss  = []test_acc   = []for epoch in range(epochs):    model.train()    epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)        model.eval()    epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)        train_acc.append(epoch_train_acc)    train_loss.append(epoch_train_loss)    test_acc.append(epoch_test_acc)    test_loss.append(epoch_test_loss)        template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%,Test_loss:{:.3f}')    print(template.format(epoch+1, epoch_train_acc*100, epoch_train_loss, epoch_test_acc*100, epoch_test_loss))print('Done')

#训练结果可视化

import matplotlib.pyplot as plt#隐藏警告import warningswarnings.filterwarnings("ignore")               #忽略警告信息plt.rcParams['font.sans-serif']    = ['SimHei'] # 用来正常显示中文标签plt.rcParams['axes.unicode_minus'] = False      # 用来正常显示负号plt.rcParams['figure.dpi']         = 100        #分辨率from datetime import datetimecurrent_time = datetime.now() # 获取当前时间epochs_range = range(epochs)plt.figure(figsize=(12, 3))plt.subplot(1, 2, 1)plt.plot(epochs_range, train_acc, label='Training Accuracy')plt.plot(epochs_range, test_acc, label='Test Accuracy')plt.legend(loc='lower right')plt.title('Training and Validation Accuracy')plt.xlabel(current_time) # 打卡请带上时间戳,否则代码截图无效plt.subplot(1, 2, 2)plt.plot(epochs_range, train_loss, label='Training Loss')plt.plot(epochs_range, test_loss, label='Test Loss')plt.legend(loc='upper right')plt.title('Training and Validation Loss')plt.show()

#训练截图

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

PyTorch MNIST 卷积神经网络 手写数字识别
相关文章