Cifar数据Lenet实战

136 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

作为刚入行的深度学习小白,我们肯定用经典的简单网络模型来练手,今天我们这里使用最经典的Lenet结合Cifar10数据来实现一个简单的分类模型,话不多说,现在开始吧。

1、准备Lenet网络

image.png

# 导入包
import torch
from torch import nn
class MyNet(nn.Module):
    def __init__(self):
        super(MyNet, self).__init__()
        # 通过 Sequential,将一系列操作封装起来
        # 原始数据是通道的,,出去是通道的,卷积核实,步长为,填空为0
        self.conv = nn.Sequential(
            # x:[b,3,32,32] > [b,6,28,28] 我们这里采用的是Cifar10数据集,这个数据集是 32*32
            nn.Conv2d(3,6,kernel_size=5,stride=1,padding=0),
            # 池化层,池化层不改变特征层,只改变数据的大小
            # [b,6,28,28] > [b,6,14,14]
            nn.AvgPool2d(kernel_size=2,stride=2,padding=0),
            # 卷积层 [b,6,14,14] > [b,16,10,10]
            nn.Conv2d(6,16,kernel_size=5,stride=1,padding=0),
            # 池化层 [b,16,10,10] > [b,16,5,5]
            nn.AvgPool2d(kernel_size=2,stride=2,padding=0),
        )
        self.fc_unit = nn.Sequential(
            nn.Linear(16*5*5,120),
            nn.ReLU(),
            nn.Linear(120,84),
            nn.ReLU(),
            nn.Linear(84,10)
        )
    def forward(self,x):
        # batchSize
        batchSize = x.size(0)
        x = self.conv(x)
        x = x.view(batchSize,-1)
        logists = self.fc_unit(x)
        return logists

这里的网络模型都是根据上面模型的参数写的,读者可以根据模型一个个对应起来,并且网络模型很简单,只有几个卷积层,最后在通过全连接层来进行分类

2、导入相关的包

# 导包

import torch
import torch.nn.functional as F
import torch.nn as nn
from torchvision import datasets
from torchvision import transforms
from torch.utils.data import DataLoader

import torch.optim as optim
from MyLenet import MyNet

# 定义batchSize
batchSize = 32

3、加载数据集

cifar_train = datasets.CIFAR10("cifar",True,transform=transforms.Compose(
    [
        transforms.Resize((32, 32)),
        transforms.ToTensor(),
    ]
),download=False)

cifar_train = DataLoader(cifar_train,batch_size=batchSize,shuffle=True)


cifar_test = datasets.CIFAR10("cifar",False,transform=transforms.Compose([
    transforms.Resize((32,32)),
    transforms.ToTensor(),
]))

cifar_test = DataLoader(cifar_test,batch_size=batchSize,shuffle=True)

4、相关实例创建

# 交叉熵损失函数
criterion = nn.CrossEntropyLoss()
#创建网络模型
model = MyNet()
# 创建优化器
optimizer = optim.SGD(model.parameters(),lr=1e-3)

这些参数很简单,基本上每个训练模型都需要创建

5、开始训练

for epoch in range(1000):
    # 训练
    model.train()
    for batchidx,(x,label) in enumerate(cifar_train):
        print("data==",x.shape)
        logists = model(x)
        #计算损失
        loss  = criterion(logists,label)
        # 梯度更新
        optimizer.zero_grad()
        # 反向传播
        loss.backward()
        # 梯度更新
        optimizer.step()

    # 进入测试阶段,不需要梯度更新,因此使用和Dropot
    model.eval()
    with torch.no_grad():
        total_correct = 0
        total_size = 0
        for x,label in cifar_test:
            logists = model(x)
            pred = logists.argmax(dim=1)
            total_correct += torch.eq(pred,label).float().sum().item()
            total_size +=x.size(0)
        acc = total_correct/total_size
        print("Test :", epoch, acc)

上面注释写的很清楚了,这里就不多说了,这么模型很简单,大家可以作为练手学习使用