• 实战:基于卷积的MNIST手写体分类


    前面实现了基于多层感知机的MNIST手写体识别,本章将实现以卷积神经网络完成的MNIST手写体识别。

    1.  数据的准备

    在本例中,依旧使用MNIST数据集,对这个数据集的数据和标签介绍,前面的章节已详细说明过了,相对于前面章节直接对数据进行“折叠”处理,这里需要显式地标注出数据的通道,代码如下:

    1. import numpy as np
    2. import einops.layers.torch as elt
    3. #载入数据
    4. x_train = np.load("../dataset/mnist/x_train.npy")
    5. y_train_label = np.load("../dataset/mnist/y_train_label.npy")
    6. x_train = np.expand_dims(x_train,axis=1)   #在指定维度上进行扩充
    7. print(x_train.shape)

    这里是对数据的修正,np.expand_dims的作用是在指定维度上进行扩充,这里在第二维(也就是PyTorch的通道维度)进行扩充,结果如下:

    (60000, 1, 28, 28)

    2.  模型的设计

    下面使用PyTorch 2.0框架对模型进行设计,在本例中将使用卷积层对数据进行处理,完整的模型如下:

    1. import torch
    2. import torch.nn as nn
    3. import numpy as np
    4. import einops.layers.torch as elt
    5. class MnistNetword(nn.Module):
    6. def __init__(self):
    7. super(MnistNetword, self).__init__()
    8. #前置的特征提取模块
    9. self.convs_stack = nn.Sequential(
    10. nn.Conv2d(1,12,kernel_size=7), #第一个卷积层
    11. nn.ReLU(),
    12. nn.Conv2d(12,24,kernel_size=5), #第二个卷积层
    13. nn.ReLU(),
    14. nn.Conv2d(24,6,kernel_size=3) #第三个卷积层
    15. )
    16. #最终分类器层
    17. self.logits_layer = nn.Linear(in_features=1536,out_features=10)
    18. def forward(self,inputs):
    19. image = inputs
    20. x = self.convs_stack(image)
    21. #elt.Rearrange的作用是对输入数据的维度进行调整,读者可以使用torch.nn.Flatten函数完成此工作
    22. x = elt.Rearrange("b c h w -> b (c h w)")(x)
    23. logits = self.logits_layer(x)
    24. return logits
    25. model = MnistNetword()
    26. torch.save(model,"model.pth")

    这里首先设定了3个卷积层作为前置的特征提取层,最后一个全连接层作为分类器层,需要注意的是,对于分类器的全连接层,输入维度需要手动计算,当然读者可以一步一步尝试打印特征提取层的结果,依次将结果作为下一层的输入维度。最后对模型进行保存。

    3.  基于卷积的MNIST分类模型

    下面进入本章的最后示例部分,也就是MNIST手写体的分类。完整的训练代码如下:

    1. import torch
    2. import torch.nn as nn
    3. import numpy as np
    4. import einops.layers.torch as elt
    5. #载入数据
    6. x_train = np.load("../dataset/mnist/x_train.npy")
    7. y_train_label = np.load("../dataset/mnist/y_train_label.npy")
    8. x_train = np.expand_dims(x_train,axis=1)
    9. print(x_train.shape)
    10. class MnistNetword(nn.Module):
    11. def __init__(self):
    12. super(MnistNetword, self).__init__()
    13. self.convs_stack = nn.Sequential(
    14. nn.Conv2d(1,12,kernel_size=7),
    15. nn.ReLU(),
    16. nn.Conv2d(12,24,kernel_size=5),
    17. nn.ReLU(),
    18. nn.Conv2d(24,6,kernel_size=3)
    19. )
    20. self.logits_layer = nn.Linear(in_features=1536,out_features=10)
    21. def forward(self,inputs):
    22. image = inputs
    23. x = self.convs_stack(image)
    24. x = elt.Rearrange("b c h w -> b (c h w)")(x)
    25. logits = self.logits_layer(x)
    26. return logits
    27. device = "cuda" if torch.cuda.is_available() else "cpu"
    28. #注意记得将model发送到GPU计算
    29. model = MnistNetword().to(device)
    30. model = torch.compile(model)
    31. loss_fn = nn.CrossEntropyLoss()
    32. optimizer = torch.optim.SGD(model.parameters(), lr=1e-4)
    33. batch_size = 128
    34. for epoch in range(42):
    35. train_num = len(x_train)//128
    36. train_loss = 0.
    37. for i in range(train_num):
    38. start = i * batch_size
    39. end = (i + 1) * batch_size
    40. x_batch = torch.tensor(x_train[start:end]).to(device)
    41. y_batch = torch.tensor(y_train_label[start:end]).to(device)
    42. pred = model(x_batch)
    43. loss = loss_fn(pred, y_batch)
    44. optimizer.zero_grad()
    45. loss.backward()
    46. optimizer.step()
    47. train_loss += loss.item() # 记录每个批次的损失值
    48. # 计算并打印损失值
    49. train_loss /= train_num
    50. accuracy = (pred.argmax(1) == y_batch).type(torch.float32).sum().item() / batch_size
    51. print("epoch:",epoch,"train_loss:", round(train_loss,2),"accuracy:",round(accuracy,2))

    在这里,我们使用了本章新定义的卷积神经网络模块作为局部特征抽取,而对于其他的损失函数以及优化函数,只使用了与前期一样的模式进行模型训练。最终结果如下所示,请读者自行验证。

    1. (60000, 1, 28, 28)
    2. epoch: 0 train_loss: 2.3 accuracy: 0.11
    3. epoch: 1 train_loss: 2.3 accuracy: 0.13
    4. epoch: 2 train_loss: 2.3 accuracy: 0.2
    5. epoch: 3 train_loss: 2.3 accuracy: 0.18
    6. epoch: 58 train_loss: 0.5 accuracy: 0.98
    7. epoch: 59 train_loss: 0.49 accuracy: 0.98
    8. epoch: 60 train_loss: 0.49 accuracy: 0.98
    9. epoch: 61 train_loss: 0.48 accuracy: 0.98
    10. epoch: 62 train_loss: 0.48 accuracy: 0.98
    11. Process finished with exit code 0

    本文节选自《PyTorch 2.0深度学习从零开始学》,本书实战案例丰富,可带领读者快速掌握深度学习算法及其常见案例。

       

  • 相关阅读:
    手机记笔记软件用哪个?
    centos7或centos8 chkconfig命令详解
    Java+JSP+MySQL基于SSM的扶贫信息管理系统-计算机毕业设计
    33. 搜索旋转排序数组
    vue大型电商项目尚品汇(后台篇)day04
    第二章 类与名称空间
    go语言 rune 类型
    Linux中安装mysql8
    POC模拟攻击利器 —— Nuclei入门(一)
    聚观早报 | 苏宁易购入驻美团外卖;今日头条接入抖音电商
  • 原文地址:https://blog.csdn.net/brucexia/article/details/132582906