一、Pytorch实现cifar10多分类
本节以CIFAR-10作为数据集,使用PyTorch利用卷积神经网络进行分类。
1、数据集说明
CIFAR-10数据集由10个类的60000个32x32彩色图像组成,每个类有6000个图像。有50000个训练图像和10000个测试图像。
数据集分为5个训练批次和1个测试批次,每个批次有10000个图像。测试批次包含来自每个类别的恰好1000个随机选择的图像。训练批次以随机顺序选取剩余图像,但一些训练批次可能更多会选取来自一个类别的图像。总体来说,五个训练集之和包含来自每个类的正好5000张图像。
图6-27显示了数据集中涉及的10个类,以及来自每个类的10个随机图像。
2、加载数据
这里采用PyTorch提供的数据集加载工具torchvision,同时对数据进行预处理。为方便起见,我们已预先下载好数据并解压,存放在当前目录的data目录下,所以,参数dowmload=False。
import torch
import torchvision
import torchvision.transforms as transforms
transform = transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5),(0.5, 0.5, 0.5))])
trainset = torchvision.datasets.CIFAR10(root='./data', train=Ture,
download=False, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
shuffle=Ture, num_workers=2)
testset = torchvision.datasets.CIFAR10(root='./data', train=False,
download=False, transform=transform)
testloader = torch.utils.data.DataLoader(testest, batch_size=4,
shuffle=False, num_workers=2)
classes = ('plane', 'car', 'bird', 'cat',
'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
# 显示图像
def imshow(img):
img = img / 2 + 0.5 # unnormalize
npimg = img.numpy()
plt.imshow(np.transpose(npimg, (1, 2, 0)))
plt.show()
# 随机获取部分训练数据
dataiter = iter(traninloader)
# 使用for循环来迭代数据
for images, labels in dataiter:
# 显示图像
imshow(torchvision.utils.make_grid(images))
# 打印标签
print(''.join('%5s' % classes[labels[j]] for j in range(4)))
3、构建网络
import torch.nn as nn
import torch.nn.functional as F
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
class CNNNet(nn.Module):
def __init__(self):
super(CNNNet,self).__init__()
self.conv1 = nn.Conv2d(in_channels=3,out_channels=16,kernel_size=5,stride=1)
self.pool1 = nn.MaxPool2d(kernel_size=2,stride=2)
self.conv2 = nn.Conv2d(in_channels=16,out_channels=36,kernel_size=3,stride=1)
self.pool2 = nn.MaxPool2d(kernel_size=2,stride=2)
self.fc1 = nn.Linear(1296,128)
self.fc2 = nn.Linear(128,10)
def forward(self.x):
x=self.pool1(F.relu(self.conv1(x)))
x=self.pool2(F.relu(self.conv2(x)))
#print(x.shape)
x=x.view(-1,36*6*6)
x=F.relu(self.fc2(F.relu(self.fc1(x))))
return x
net = CNNNet()
net=net.to(device)
print("net have {} paramerters in total".format(sum(x.numel() for x in net.parameters())))
import torch.optim as optim
LR=0.001
critreion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
#optimizer = optim Adam(net.parameters(). lr=LR)
print(net)
#取模型中的前四层
nn.Sequential(*list(net.children())[:4])
4、训练模型
for epoch in range(10):
running_loss = 0.0
for i, data in enumerate(traninloader, 0):
# 获取训练数据
inputs, labels = data
inputs, labels = inputs.to(device),labls.to(device)
# 权重参数梯度清零
optimizer.zero_grad()
# 正向及反向传播
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
# 显示损失值
running_loss += loss.item()
if i % 2000 == 1999: # print every 2000 mini-batches
print('[%d, %5d] loss: %.3f' %(epoch + 1, i + 1, running_loss / 2000))
running_loss = 0.0
print('Finshed Tranining')