目录
任务详情
训练设置
网络模型
损失函数
优化器
训练步骤
具体代码
导入环境
导入数据
加载数据
创建网络
损失函数
优化器
开始训练
利用CIFAR10数据集,基于pytorch环境,训练一个10个类别的小样本分类器
CIFAR-10 是由 Hinton 的学生 Alex Krizhevsky 和 Ilya Sutskever 整理的一个用于识别普适物体的小型数据集。一共包含 10 个类别的 RGB 彩色图片:飞机( airplane )、汽车( automobile )、鸟类( bird )、猫( cat )、鹿( deer )、狗( dog )、蛙类( frog )、马( horse )、船( ship )和卡车( truck )。图片的大小为 32×32 ,数据集中一共有 50000 张训练图片和 10000 张测试图片。 CIFAR-10 的图片样例如图所示:
采用mini-batch训练模式,batch_size = 64
LeNet-5是识别图片中手写数字的经典网络模型,网络结构简单,我们将其简单改一下用于解决小样本分类问题,在自己的笔记本上面训练也不会花太多时间,适合新手入门,可以短时间感受到深度学习的魅力。
网络结构图
各层参数
输入大小(32,32,3)
输出大小(10,1)
注:卷积层参数(输入通道、输出通道、卷积核大小、步长、padding)
为交叉熵损失函数:
优化器为随机梯度下降,学习率取0.01
基本步骤和关键代码如下:
# 准备数据--torchvision.datasets.CIFAR10
# 加载数据--torch.utils.data.DataLoader
# 准备模型--class FewShot(nn.Module)
# 设置损失函数--loss_fun = nn.CrossEntropyLoss()
# 设置优化器--optimier = torch.optim.SGD(few_shot.parameters(), lr=learning_rate)
# 开始训练--保存训练模型--torch.save(few_shot, "few_show_{}".format(epoch))
# 最后验证--torch.load("few_show_9")
# 结果聚合展示--writer = SummaryWriter("logs")
import torch.utils.data
import torchvision
from torch import nn
from torch.utils.tensorboard import SummaryWriter
可能的问题:如果显示导入的包有问题,那多半是版本问题,可以直接删除再重新下载,一般能解决。
data_train = torchvision.datasets.CIFAR10("./dataset", train=True, transform=torchvision.transforms.ToTensor(),
download=True)
data_test = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor(),
download=True)
data_train_size = len(data_train)
data_test_size = len(data_test)
print("------训练集大小{}------".format(data_train_size))
print("------测试集大小{}------".format(data_test_size))
输出
Files already downloaded and verified
Files already downloaded and verified
------训练集大小50000------
------测试集大小10000------
可能的问题:数据集下载问题,可以直接去官网下载,复制到dataset文件夹下
官方链接:https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
dataloader_train = torch.utils.data.DataLoader(data_train, batch_size=64)
dataloader_test = torch.utils.data.DataLoader(data_test, batch_size=64)
class FewShot(nn.Module):
def __init__(self) -> None:
super().__init__()
self.model = nn.Sequential(
nn.Conv2d(3, 32, 5, 1, padding="same"),
nn.MaxPool2d(2),
nn.Conv2d(32, 32, 5, 1, padding="same"),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, 5, 1, padding="same"),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64 * 4 * 4, 64),
nn.Linear(64, 10)
)
def forward(self, x):
x = self.model(x)
return x
few_shot = FewShot()
# 损失函数
loss_fun = nn.CrossEntropyLoss()
# 优化器
learning_rate = 1e-2
optimier = torch.optim.SGD(few_shot.parameters(), lr=learning_rate)
# 训练轮数
Epoch = 10
# 记录训练次数
train_step = 0
test_step = 0
writer = SummaryWriter("logs")
# 训练
for epoch in range(Epoch):
print("------第{}轮训练开始------".format(epoch + 1))
# 训练步骤
few_shot.train()
train_accuracy = 0
for data in dataloader_train:
imgs, label = data
output = few_shot(imgs)
loss = loss_fun(output, label)
# 优化器优化模型
optimier.zero_grad()
loss.backward()
optimier.step()
train_step += 1
accuracy = (output.argmax(1) == label).sum()
train_accuracy += accuracy
if train_step % 100 == 0:
writer.add_scalar("train_loss", loss.item(), train_step)
print("第{}次训练,LOSS值为:{}".format(train_step, loss.item()))
# 测试
few_shot.eval()
loss_test = 0
test_accuracy = 0
with torch.no_grad():
for data in dataloader_test:
imgs, label = data
output = few_shot(imgs)
loss = loss_fun(output, label)
loss_test += loss.item()
accuracy = (output.argmax(1) == label).sum()
test_accuracy += accuracy
test_step += 1
print("第{}轮测试,LOSS值为:{}".format(epoch + 1, loss_test))
writer.add_scalar("test_loss", loss_test, test_step)
print("第{}轮训练,准确率为:{}".format(epoch + 1, train_accuracy / data_train_size))
print("第{}轮测试,准确率为:{}".format(epoch + 1, test_accuracy / data_test_size))
writer.add_scalar("train_accuracy", train_accuracy / data_train_size, test_step)
writer.add_scalar("test_accuracy", test_accuracy / data_test_size, test_step)
# 模型保存
torch.save(few_shot, "few_show_{}".format(epoch))
print("模型已保存")
writer.close()
输出
------第1轮训练开始------
第100次训练,LOSS值为:2.2882776260375977
第200次训练,LOSS值为:2.279031276702881
第300次训练,LOSS值为:2.2478630542755127
第400次训练,LOSS值为:2.1656196117401123
第500次训练,LOSS值为:2.0335943698883057
第600次训练,LOSS值为:2.0050065517425537
第700次训练,LOSS值为:1.9842586517333984
第1轮测试,LOSS值为:312.4123376607895
第1轮训练,准确率为:0.20824000239372253
第1轮测试,准确率为:0.2888000011444092
模型已保存
------第2轮训练开始------
第800次训练,LOSS值为:1.8589787483215332
第900次训练,LOSS值为:1.8078399896621704
第1000次训练,LOSS值为:1.8957090377807617
第1100次训练,LOSS值为:1.9878970384597778
...
结果
第10轮测试,LOSS值为:194.56879448890686
第10轮训练,准确率为:0.5988600254058838
第10轮测试,准确率为:0.5544000267982483
查看日志
tensorboard --logdir="logs"
输出
还可以测试自己的图片
用PIL导数图片、用torch.load("few_show_9")倒数训练好的模型就可以了。