CIFAR-10.(Canadian Institute for Advanced Research)是由 Alex Krizhevsky、Vinod Nair 与 Geoffrey Hinton 收集的一个用于图像识别的数据集,60000个32*32的彩色图像,50000个training data,10000个 test data 有10类,飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船、卡车,每类6000张图。与MNIST相比,色彩、颜色噪点较多,同一类物体大小不一、角度不同、颜色不同。

 先要对该数据集进行分类

步骤如下
1.使用torchvision加载并预处理CIFAR-10数据集、
2.定义网络
3.定义损失函数和优化器
4.训练网络并更新网络参数
5.测试网络

 1 import torchvision as tv            #里面含有许多数据集
 2 import torch
 3 import torchvision.transforms as transforms    #实现图片变换处理的包
 4 from torchvision.transforms import ToPILImage
 5
 6 #使用torchvision加载并预处理CIFAR10数据集
 7 show = ToPILImage()         #可以把Tensor转成Image,方便进行可视化
 8 transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize(mean = (0.5,0.5,0.5),std = (0.5,0.5,0.5))])#把数据变为tensor并且归一化range [0, 255] -> [0.0,1.0]
 9 trainset = tv.datasets.CIFAR10(root='data1/',train = True,download=True,transform=transform)
10 trainloader = torch.utils.data.DataLoader(trainset,batch_size=4,shuffle=True,num_workers=0)
11 testset = tv.datasets.CIFAR10('data1/',train=False,download=True,transform=transform)
12 testloader = torch.utils.data.DataLoader(testset,batch_size=4,shuffle=True,num_workers=0)
13 classes = ('plane','car','bird','cat','deer','dog','frog','horse','ship','truck')
14 (data,label) = trainset[100]
15 print(classes[label])#输出ship
16 show((data+1)/2).resize((100,100))
17 dataiter = iter(trainloader)
18 images, labels = dataiter.next()
19 print(' '.join('%11s'%classes[labels[j]] for j in range(4)))
20 show(tv.utils.make_grid((images+1)/2)).resize((400,100))#make_grid的作用是将若干幅图像拼成一幅图像
21
22 #定义网络
23 import torch.nn as nn
24 import torch.nn.functional as F
25 class Net(nn.Module):
26     def __init__(self):
27         super(Net,self).__init__()
28         self.conv1 = nn.Conv2d(3,6,5)
29         self.conv2 = nn.Conv2d(6,16,5)
30         self.fc1 = nn.Linear(16*5*5,120)
31         self.fc2 = nn.Linear(120,84)
32         self.fc3 = nn.Linear(84,10)
33     def forward(self,x):
34         x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
35         x = F.max_pool2d(F.relu(self.conv2(x)),2)
36         x = x.view(x.size()[0],-1)
37         x = F.relu(self.fc1(x))
38         x = F.relu(self.fc2(x))
39         x = self.fc3(x)
40         return  x
41
42 net = Net()
43 print(net)
44
45 #定义损失函数和优化器
46 from torch import optim
47 criterion  = nn.CrossEntropyLoss()#定义交叉熵损失函数
48 optimizer = optim.SGD(net.parameters(),lr = 0.001,momentum=0.9)
49
50 #训练网络
51 from torch.autograd  import Variable
52 for epoch in range(2):
53     running_loss = 0.0
54     for i, data in enumerate(trainloader, 0):#enumerate将其组成一个索引序列,利用它可以同时获得索引和值,enumerate还可以接收第二个参数,用于指定索引起始值
55         inputs, labels = data
56         inputs, labels = Variable(inputs), Variable(labels)
57         optimizer.zero_grad()
58         outputs = net(inputs)
59         loss  = criterion(outputs, labels)
60         loss.backward()
61         optimizer.step()
62         running_loss += loss.item()
63         if i % 2000 ==1999:
64             print('[%d, %5d] loss: %.3f'%(epoch+1,i+1,running_loss/2000))
65             running_loss = 0.0
66 print("----------finished training---------")
67 dataiter = iter(testloader)
68 images, labels = dataiter.next()
69 print('实际的label: ',' '.join('%08s'%classes[labels[j]] for j in range(4)))
70 show(tv.utils.make_grid(images/2 - 0.5)).resize((400,100))#?????
71 outputs = net(Variable(images))
72 _, predicted = torch.max(outputs.data,1)#返回最大值和其索引
73 print('预测结果:',' '.join('%5s'%classes[predicted[j]] for j in range(4)))
74 correct = 0
75 total = 0
76 for data in testloader:
77     images, labels = data
78     outputs = net(Variable(images))
79     _, predicted = torch.max(outputs.data, 1)
80     total +=labels.size(0)
81     correct +=(predicted == labels).sum()
82 print('10000张测试集中的准确率为: %d %%'%(100*correct/total))
83 if torch.cuda.is_available():
84     net.cuda()
85     images = images.cuda()
86     labels = labels.cuda()
87     output = net(Variable(images))
88     loss = criterion(output, Variable(labels))

学习率太大会很难逼近最优值,所以要注意在数据集小的情况下学习率尽量小一些,epoch尽量大一些。

这个例子是陈云的深度学习pytorch框架书上的一个demo,运行该代码需要注意的是数据集的下载问题,因为运行程序很可能数据集下载很慢或者直接下载失败,因此推荐使用迅雷根据指定网址直接下载,半分钟就可以下载好。

02-12 10:52