Deep Learning with Pytorch-Train A Classifier

╰半夏微凉° 2024-05-24 03:52 227阅读 0赞

Deep Learning with Pytorch: A 60 Minute Blitz

训练一个分类器

我们已经看到了如何定义一个神经网络,计算代价值和更新这个网络的权值,你现在可能会想,

数据呢?

通常,当你处理图片、文本、声音或者视频数据的时候,你使用标准python package加载数据到 numpy array 的 python 包,然后你把array 转换成 torch.*Tensor

特别的,对于图像,我们创造了一个名为 torchvision 的包,torchvision可直接加载如Imagenet, CIFAR10, MNIST之类的常用数据集,还有一些非常常用的数据转换器,这提供了巨大的方便,避免了范例文件代码的编写

本教程我们将使用CIFAR10数据集。共有十类: ‘airplane’, ‘automobile’, ‘bird’, ‘cat’, ‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’. CIFAR10中的图片3通道,32*32大小

训练一个图片分类器

我们将依次执行以下步骤

1.使用torchvision加载并规格化CIFAR10的training和testing数据集

2.定义一个卷积神经网络CNN

3.定义代价函数 loss function

4.在training data上训练神经网络

5.在testing data 上测试神经网络

1.加载并规格化CIFAR10

使用torchvision,加载CIFAR10 so easy,(妈妈再也不用担心我的学习…)

  1. import torch
  2. import torchvision
  3. import torchvision.transforms as tfs
  4. # torchvision 数据集的输出是[0, 1]范围的PILImage图片
  5. # 我们使用归一化方法将其转化为[-1, 1]范围内的Tensor
  6. import torch
  7. import torchvision
  8. import torchvision.transforms as tfs
  9. transform = tfs.Compose([tfs.ToTensor(),
  10. tfs.Normalize((0.5, 0.5, 0.5),(0.5, 0.5, 0.5))])
  11. trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,shuffle=True, num_workers=2)
  12. testset = torchvision.datasets.CIFAR10(root='./data', train=Flase,download=True, transform=transform)
  13. testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False, num_workers=2)
  14. classes = ('plane', 'car', 'bird', 'cat', 'deer',
  15. 'dog', 'frog', 'horse', 'ship', 'truck')

让我们看一下一些训练图片

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. # functions to show an image
  4. def imshow(img):
  5. img = img / 2 + 0.5 # unnormalize
  6. npimg = img.numpy()
  7. plt.imshow(np.transpose(npimg, (1, 2, 0)))
  8. # get some random training images
  9. dataiter = iter(trainloader)
  10. images, labels = dataiter.next()
  11. # show images
  12. imshow(torchvision.utils.make_grid(images))
  13. # print labels
  14. print(' '.join('%5s' % classes[labels[j]] for j in range(4)))
2.定义一个卷积神经网络
  1. import torch.nn as nn
  2. import torch.nn.functional as F
  3. class Net(nn.Module):
  4. def __init__(self):
  5. super(Net, self).__init__()
  6. self.conv1 = nn.Conv2d(1, 6, 5) # 3 input image channel, 6 output channels, 5x5 square convolution kernel
  7. self.conv2 = nn.Conv2d(6, 16, 5)
  8. self.fc1 = nn.Linear(16*5*5, 120) # an affine operation: y = Wx + b
  9. self.fc2 = nn.Linear(120, 84)
  10. self.fc3 = nn.Linear(84, 10)
  11. def forward(self, x):
  12. x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2)) # Max pooling over a (2, 2) window
  13. x = F.max_pool2d(F.relu(self.conv2(x)), 2) # If the size is a square you can only specify a single number
  14. x = x.view(-1, self.num_flat_features(x))
  15. x = F.relu(self.fc1(x))
  16. x = F.relu(self.fc2(x))
  17. x = self.fc3(x)
  18. return x
  19. def num_flat_features(self, x):
  20. size = x.size()[1:] # all dimensions except the batch dimension
  21. num_features = 1
  22. for s in size:
  23. num_features *= s
  24. return num_features
  25. net = Net()
3. 定义代价函数 ( Loss Function ) 和优化器 ( Optimizer )

使用 Classification Cross-Entropy 和 SGD

  1. import torch.optim as optim
  2. criterion = nn.CrossEntropyLoss()
  3. optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
4. 训练这个网络

现在事情开始变得有趣,我们只需一遍一遍地迭代数据并将数据输入网络来优化即可。

  1. for epoch in range(2): # Loop over the data set multiple times
  2. running_loss = 0.0
  3. for i, data in enumerate(trainloader, 0):
  4. # get the inputs
  5. inputs, labels = data
  6. # zero the parameter gradients
  7. optimizer.zero_grad()
  8. # forward + backward + optimize
  9. outputs = net(inputs)
  10. loss = criterion(outputs, labels)
  11. loss.backward()
  12. optimizer.step()
  13. # print statoistics
  14. running_loss += loss.item()
  15. if i % 2000 == 1999: # print every 2000 mini-batches
  16. print('[%d, %d] loss: %.3f' %
  17. (epoch + 1, i + 1, running_loss / 2000))
  18. running_loss = 0.0
  19. print('Finished Training.')
5. 在Testing Data上测试网络

我们已经在training data上训练两遍网络,但是我们需要检查网络是否学到了什么没有

我们通过比较网络输出的类标签和Ground-Truth比较来检查网络,如果预测正确,我们就把样本加入正确预测的列表中

第一步,先展示一下从testing set获得的一些照片

  1. dataiter = iter(testloader)
  2. images, labels = dataiter.next()
  3. # print images
  4. imshow(torchvision.utils.make_grid(images))
  5. print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))
  6. # GroundTruth: cat ship ship plane

现在让我们看看神经网络认为上面的样本是什么

  1. outputs = net(Variable(images))
  2. # the outputs are energies for the 10 classes.
  3. # Higher the energy for a class, the more the network
  4. # thinks that the image is of the particular class
  5. # So, Let's get the index of the highest energy
  6. _, predicted = torch.max(outputs.data, 1)
  7. print('print')
  8. # 训练结果
  9. [1, 2000] loss: 2.195
  10. [1, 4000] loss: 1.789
  11. [1, 6000] loss: 1.633
  12. [1, 8000] loss: 1.534
  13. [1, 10000] loss: 1.511
  14. [1, 12000] loss: 1.433
  15. [2, 2000] loss: 1.387
  16. [2, 4000] loss: 1.368
  17. [2, 6000] loss: 1.338
  18. [2, 8000] loss: 1.307
  19. [2, 10000] loss: 1.273
  20. [2, 12000] loss: 1.281
  21. Finished Training.
  22. predicted: horse bird plane truck

训练的结果非常好
让我们看一下网络在整个testing data上表现如何

  1. corret = 0
  2. total = 0
  3. with torch.no_grad():
  4. for data in testloader:
  5. images, lables = data
  6. outputs = net(images)
  7. _, predicts = torch.max(outputs.data, 1)
  8. total += labels.size(0)
  9. corret += (predicted == labels).sum().iterm()
  10. print('Accuracy of the network on the 10000 test images: %d %%'
  11. % 100 * corret / total)

训练的结果要比随机好, 要从十个中选择一个的话准确率大概只有10%

那么它究竟在哪些类别表现良好, 哪些类别表现不好呢?

  1. class_correct = list(0. for i in range(10))
  2. class_total = list(0. for i in range(10))
  3. for data in testloader:
  4. images, labels = data
  5. outputs = net(Variable(images))
  6. _, predicted = torch.max(outputs.data, 1)
  7. c = (predicted == labels).squeeze()
  8. for i in range(4):
  9. label = labels[i]
  10. class_correct[label] += c[i].item()
  11. class_total[label] += 1
  12. for i in range(10):
  13. prit('Accucary of %5s : %2d %%' %
  14. classes[i], 100 * class_correct[i]/class_total[i])

发表评论

表情:
评论列表 (有 0 条评论,227人围观)

还没有评论,来说两句吧...

相关阅读