深度学习----卷积神经网络实现数字识别

一、准备工作

导入库,导入数据集,划分训练批次数量,规定训练硬件(这部分

python 复制代码
import torch
from torch import nn  # 导入神经网络模块
from torch.utils.data import DataLoader  # 数据包管理工具,打包数据
from torchvision import datasets  # 封装了很多与图像相关的模型,和数据集
from torchvision.transforms import ToTensor  # 将其他数据类型转化为张量

train_data = datasets.MNIST(
    root='data',
    train=True,  # 是否读取下载后数据中的训练集
    download=True,  # 如果之前下载过则不用下载
    transform=ToTensor()
)
test_data = datasets.MNIST(
    root='data',
    train=False,
    download=True,
    transform=ToTensor()
)

train_dataloader = DataLoader(train_data,batch_size=256)#是一个类,现在初始化了,但没开始打包,训练开始才打包
test_dataloader = DataLoader(test_data,batch_size=256)

device = 'cuda' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else 'cpu'
print(f'Using {device} device')

二、定义神经网络(重点)

这部分比较重要,我分开讲

1、类定义与继承

python 复制代码
class CNN(nn.Module):

这里定义了一个名为CNN的类,它继承自 PyTorch 的nn.Module类。nn.Module是 PyTorch 中所有神经网络模块的基类,通过继承它,我们可以利用 PyTorch 提供的各种功能,如参数管理、设备迁移等。

2、初始化方法

python 复制代码
def __init__(self):
    super().__init__()

这是类的构造函数,super().__init__()调用了父类nn.Module的构造函数,确保父类得到正确初始化。

3、网络层定义

  • 第一个卷积块(conv1)
python 复制代码
self.conv1 = nn.Sequential(
    nn.Conv2d(
        in_channels=1,      # 输入通道数,1表示灰度图像
        out_channels=16,    # 输出通道数/卷积核数量
        kernel_size=5,      # 卷积核大小5×5
        stride=1,           # 步长为1
        padding=2,          # 填充为2,保持特征图大小不变
    ),
    nn.ReLU(),               # ReLU激活函数
    nn.MaxPool2d(kernel_size=2),  # 2×2最大池化
)

这个卷积块接收 1 通道的输入,通过 16 个 5×5 的卷积核进行卷积操作,然后经过 ReLU 激活和 2×2 的最大池化。

  • 第二个卷积块(conv2)
python 复制代码
self.conv2 = nn.Sequential(
    nn.Conv2d(16,32,5,1,2),  # 16→32通道,5×5卷积核
    nn.ReLU(),
    nn.Conv2d(32,32,5,1,2),  # 32→32通道,5×5卷积核
    nn.ReLU(),
    nn.Conv2d(32,32,5,1,2),  # 32→32通道,5×5卷积核
    nn.ReLU(),
    nn.Conv2d(32,64,5,1,2),  # 32→64通道,5×5卷积核
    nn.ReLU(),
    nn.Conv2d(64,64,5,1,2),  # 64→64通道,5×5卷积核
    nn.ReLU(),
    nn.MaxPool2d(kernel_size=2),  # 2×2最大池化
)

这个卷积块包含多个卷积层,逐步增加通道数,并在最后进行一次最大池化。

  • 第三个卷积块(conv3)

    self.conv3 = nn.Sequential(
    nn.Conv2d(64,64,5,1,2), # 64→64通道,5×5卷积核
    nn.ReLU(),
    )

这是一个简单的卷积块,保持通道数不变。

  • 全连接层(out)

    self.out = nn.Linear(6477,10)

这是网络的输出层,将卷积得到的特征图展平后映射到 10 个输出(可能对应 10 类分类问题)。

4、前向传播方法

python 复制代码
def forward(self, x):
    x = self.conv1(x)    # 通过第一个卷积块
    x = self.conv2(x)    # 通过第二个卷积块
    x = self.conv3(x)    # 通过第三个卷积块
    x = x.view(x.size(0),-1)  # 展平特征图,保留批次维度
    output = self.out(x)  # 通过全连接层得到输出
    return output

forward方法定义了数据在网络中的流动路径,即前向传播过程。x.view(x.size(0),-1)将卷积操作得到的多维特征图展平成一维向量,以便输入到全连接层。

5、模型实例化

python 复制代码
model = CNN().to(device)

创建 CNN 类的实例,并将模型迁移到指定的设备(CPU 或 GPU)上。

完整代码:

python 复制代码
 定义神经网络,通过类的继承
class CNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Sequential(#容器,添加网络层
            nn.Conv2d(
                in_channels=1,
                out_channels = 16,
                kernel_size = 5,
                stride = 1,
                padding = 2,
            ),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size = 2),
        )
        self.conv2 = nn.Sequential(  # 容器,添加网络层
            nn.Conv2d(16,32,5,1,2),
            nn.ReLU(),
            nn.Conv2d(32, 32, 5, 1, 2),
            nn.ReLU(),
            nn.Conv2d(32, 32, 5, 1, 2),
            nn.ReLU(),
            nn.Conv2d(32,64,5,1,2),
            nn.ReLU(),
            nn.Conv2d(64, 64, 5, 1, 2),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2),)
        self.conv3 = nn.Sequential(
            nn.Conv2d(64,64,5,1,2),
            nn.ReLU(),
        )
        self.out = nn.Linear(64*7*7,10)



    def forward(self, x):  # 前向传播
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        x = x.view(x.size(0),-1)
        output = self.out(x)
        return output
model = CNN().to(device)

三、模型的训练

这一段和上一个博客的步骤一样这里就不多做讲解了

不了解的直接看

深度学习----由手写数字识别案例来认识PyTorch框架-CSDN博客

python 复制代码
def train(dataloader, model, loss_fn, optimizer):
    model.train()  # 开启模型训练模式,像 Dropout、BatchNorm 层会在训练/测试时表现不同,需此设置
    batch_size_num = 1  # 用于计数当前处理到第几个 batch
    for X, y in dataloader:  # 从数据加载器中逐个取出 batch 的数据(特征 X、标签 y )
        X, y = X.to(device), y.to(device)  # 把数据和标签放到指定计算设备(CPU/GPU)
        pred = model(X)  # 将数据输入模型,得到预测结果(模型自动做前向传播计算 )
        loss = loss_fn(pred, y)  # 用损失函数计算预测结果和真实标签的损失
        # 以下是反向传播更新参数的标准流程
        optimizer.zero_grad()  # 清空优化器里参数的梯度,避免梯度累加影响计算
        loss.backward()  # 反向传播,计算参数的梯度
        optimizer.step()  # 根据梯度,更新模型参数

        loss = loss.item()  # 取出损失张量的数值(脱离计算图 )
        # 打印当前 batch 的损失和 batch 编号
        if batch_size_num % 100 == 0:
            print(f"loss:{loss:>7f}  [number:{batch_size_num}")
        batch_size_num += 1  # batch 计数加一


def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    model.eval()
    test_loss,correct = 0,0
    with torch.no_grad():
        for X , y in dataloader:
            X ,y = X.to(device),y.to(device)
            pred = model.forward(X)#.forward可以被省略
            test_loss += loss_fn(pred,y).item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
            a = (pred.argmax(1) == y)
            b = (pred.argmax(1) == y).type(torch.float)
    test_loss /= num_batches
    correct /= size
    print(f"test result: \n Accuracy: {(100*correct)}%,Avg loss:{test_loss}")



# print(list(model.parameters()))
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(),lr=0.001)#换优化器可以提高准确率,Adam,SGD等

# train(train_dataloader,model,loss_fn,optimizer)
# test(test_dataloader,model,loss_fn)
#

epochs = 10
for t in range(epochs):
    print(f"轮次:{t+1}\n----------------------------")
    train(train_dataloader,model,loss_fn,optimizer)
print("Done")
test(test_dataloader,model,loss_fn)
相关推荐
小鸡吃米…5 小时前
机器学习 - K - 中心聚类
人工智能·机器学习·聚类
好奇龙猫6 小时前
【AI学习-comfyUI学习-第三十节-第三十一节-FLUX-SD放大工作流+FLUX图生图工作流-各个部分学习】
人工智能·学习
沈浩(种子思维作者)6 小时前
真的能精准医疗吗?癌症能提前发现吗?
人工智能·python·网络安全·健康医疗·量子计算
minhuan6 小时前
大模型应用:大模型越大越好?模型参数量与效果的边际效益分析.51
人工智能·大模型参数评估·边际效益分析·大模型参数选择
Cherry的跨界思维6 小时前
28、AI测试环境搭建与全栈工具实战:从本地到云平台的完整指南
java·人工智能·vue3·ai测试·ai全栈·测试全栈·ai测试全栈
MM_MS6 小时前
Halcon变量控制类型、数据类型转换、字符串格式化、元组操作
开发语言·人工智能·深度学习·算法·目标检测·计算机视觉·视觉检测
ASF1231415sd6 小时前
【基于YOLOv10n-CSP-PTB的大豆花朵检测与识别系统详解】
人工智能·yolo·目标跟踪
水如烟7 小时前
孤能子视角:“意识“的阶段性回顾,“感质“假说
人工智能
Carl_奕然7 小时前
【数据挖掘】数据挖掘必会技能之:A/B测试
人工智能·python·数据挖掘·数据分析
旅途中的宽~7 小时前
《European Radiology》:2024血管瘤分割—基于MRI T1序列的分割算法
人工智能·计算机视觉·mri·sci一区top·血管瘤·t1