使用简化VGGnet对MNIST数据集进行训练

 

目录

1.VGGNet特点

2.注意点

3.导入数据集

4.定义简化版的VGG网络结构

5.定义训练和验证函数

6.调用函数

7.多批次训练

8.结果


  VGGNet 是由牛津大学的视觉几何组(Visual Geometry Group)在 2014 年提出的一个深度卷积神经网络。它在 ImageNet 竞赛中取得了很好的成绩。VGGNet 的主要贡献是展示了网络深度对于性能的提升有显著影响。

1.VGGNet特点

  1. 网络深度:VGGNet 有多个版本,其中最常见的是 VGG16 和 VGG19,分别包含 13 层和 16 层卷积层。
  2. 卷积核大小:VGGNet 使用 3x3 的小卷积核,这使得网络更深但参数更少。
  3. 步长和填充:卷积层使用 1x1 的步长和 1 像素的填充,保持特征图的尺寸。
  4. 池化层:每两个卷积层后跟一个 2x2 的最大池化层,步长为 2。
  5. 全连接层:在卷积层之后,VGGNet 使用几个全连接层,最后是一个 softmax 层进行分类。

2.注意点

  VGG16结构复杂,而MNIST数据集图像太小,在经过过多的池化层后,维度会简化到0然后报错,所以本代码将使用两个卷积层和两个池化层的简化版VGGnet。

3.导入数据集

import torch
from torch import nn
#导入神经网络模块
from torch.utils.data import DataLoader #数据包管理工具,打包数据
from torchvision import datasets #封装了很多与图像相关的模型,数据集
from torchvision.transforms import ToTensor

training_data = datasets.MNIST(#跳转到国数的内部源代码,pycharm 按ctrl +鼠标点击
    root="data",
    train=True,
    download=True,
    transform=ToTensor(),#张量,图片是不能直接传入神经网络模型
)

test_data = datasets.MNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor(),#Tensor是在深度学习中提出并厂泛应用的数据类型,它与深度学习框架(如PyTorch、TensorFlow) 紧密集成
)

train_dataloader = DataLoader(training_data, batch_size=64) #64张图片为一个包
test_dataloader = DataLoader(test_data, batch_size=64)

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

4.定义简化版的VGG网络结构

class VGG_MNIST(nn.Module):
    def __init__(self):
        super(VGG_MNIST, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(1, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(64, 128, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            # 可以继续添加层,但考虑到MNIST的简单性,这里就足够了
        )
        self.classifier = nn.Sequential(
            nn.Linear(128 * 7 * 7, 1024),  # 根据特征图大小调整这个值
            nn.ReLU(inplace=True),
            nn.Dropout(p=0.5),
            nn.Linear(1024, 10),
        )

    def forward(self, x):
        x = self.features(x)
        x = torch.flatten(x, 1)
        x = self.classifier(x)
        return x

model = VGG_MNIST().to(device)  # 把刚刚创建的模型传入到 Gpu

5.定义训练和验证函数

def train(dataloader, model, loss_fn, optimizer):
    model.train()  # #告诉模型要开始训练,模型中ω进行随机化操作,以及更新ω,在训练过程中,ω会被修改
    batch_size_num = 1
    for X, y in dataloader: # 其中batch为每个数据的编号
        X, y = X.to(device), y.to(device) # 把训练数据集和标签传入cpu或GPU
        pred = model.forward(X) # 自动初始化ω权值
        loss = loss_fn(pred, y) # 通过交叉熵损失函数计算损失值loss
        optimizer.zero_grad()  # 梯度值清零
        loss.backward()  # 反向传播计算得到每个参数的梯度值
        optimizer.step()  # 根据梯度更新网络参数

        loss_value = loss.item()  # item从tensor数据中提取数据出来,tensor获取损失值
        print(f"loss: {loss_value:>7f} [number:{batch_size_num}]")
        batch_size_num += 1


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():# 一个上下文管理器,关闭梯度计算。当确认不会调用Tensor.backward()的时候。这可以减少计算所用内存消耗。
        for X, y in dataloader:
            X, y = X.to(device), y.to(device)  # 数据传到GPU或者CPU中
            pred = model.forward(X)
            test_loss += loss_fn(pred, y).item() # test_loss 会自动累加每一个批次的损失值
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()

    test_loss /= num_batches  # 能来衡量模型测试的好坏。
    correct /= size  # 平均的正确率
    print(f"Test result: \n Accuracy: {(100*correct)}%,Avg loss: {test_loss}")

6.调用函数

loss_fn = nn.CrossEntropyLoss()  # 创建交叉熵损失函数对象,因为手写字识别中共有10个数字,输出会有10个结果
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

train(train_dataloader, model, loss_fn, optimizer)  # 训练1次完整的数据,多轮训练
test(test_dataloader, model, loss_fn)

7.多批次训练

epochs = 10
for t in range(epochs):
    print(f"Epoch {t+1}\n--------------------------")
    train(train_dataloader, model, loss_fn, optimizer)
print("Done!")
test(test_dataloader, model, loss_fn)

8.结果

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值