本文已参与「新人创作礼」活动,一起开启掘金创作之路。
作为刚入行的深度学习小白,我们肯定用经典的简单网络模型来练手,今天我们这里使用最经典的Lenet结合Cifar10数据来实现一个简单的分类模型,话不多说,现在开始吧。
1、准备Lenet网络
# 导入包
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)
上面注释写的很清楚了,这里就不多说了,这么模型很简单,大家可以作为练手学习使用