现在知道怎么定义一个网络,计算loss更新权重了。
What about data?
通常来说处理的数据有图片,文本,声音和视频,python有专门的库加载这些数据成numpy的array格式。然后转成torch.Tensor.
- 对于图片,可以使用 Pillow,OpenCV 等
- 声音的话,可以用 scipy,librosa
- 文本信息可以使用 原生的 Python或Cython,或者 NLKT 和 SpyCy
特别是视频,Torch 有专门的包 torchvision,他为像 Imagenet,CIFAR10,MNIST等这样的数据集提供加载器,也提供图片的数据转换,torchvison.datasets 和 torch.utils.data.DataLoader .
这样提供了很大的便利,避免重复造轮子。
这小节使用 CIFAR10 数据集。这是一个包含,飞机,汽车,鸟,猫,鹿,狗,青蛙,马,船,卡车,十种类型图片。 CIFAR-10 图片是统一的 32 x 32 大小,包含 RGB 三个通道。
训练一个图片分类器
我们需要做以下几布:
- 利用 torchvision 加载格式化 CIFAR-10 测试集和训练集
- 定义一个卷积神经网络
- 定义一个 loss 函数
- 利用训练集训练网络
- 利用测试集进行测试
1.加载、标准化 CIFAR-10
1 | import torch |
torchvision 输出的数据是 [0,1] PILImage 图片,我们需要转换成 标准化的 Tensor [-1,1]格式。
1 | transform = transforms.Compose( |
OUT:
Files already downloaded and verified
Files already downloaded and verified
这部分数据是从网上下载下来的,但我根本下载不了,所以从kaggle下载放在./data 文件夹下。
先看看图片吧。1
2
3
4
5
6
7
8
9
10
11
12
13
14import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
def imshow(img):
img = img / 2 + 0.5
npimg = img.numpy()
plt.imshow(np.transpose(npimg,(1,2,0)))
dataiter = iter(trainloader)
images, labels = dataiter.next()
imshow(torchvision.utils.make_grid(images))
print(" ".join('%5s' % classes[labels[j]] for j in range(4)))
OUT:
frog dog dog truck
2.定义一个卷积神经网络
把上一小节那个卷积神经网络复制过来,将输入通道改成三。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net,self).__init__()
self.conv1 = nn.Conv2d(3,6,5)
self.pool = nn.MaxPool2d(2,2)
self.conv2 = nn.Conv2d(6,16,5)
self.fc1 = nn.Linear(16*5*5,120)
self.fc2 = nn.Linear(120,84)
self.fc3 = nn.Linear(84,10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1,16*5*5)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
net = Net()
3.定义 loss 函数和优化器
利用交叉熵loss 和 SGD.1
2
3
4import torch.optim as optim
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(),lr = 0.001,momentum = 0.9)
4.训练网络
现在开始好玩了。先简单跑一下数据。
1 | for epoch in range(2): |
5.利用测试集测试网络
现在已经利用训练集训练了两次,我们需要测试集检查一下是否学到了什么东西。1
2
3
4
5dataiter = iter(testloader)
images,labels = dataiter.next()
imshow(torchvision.utils.make_grid(images))
print('GroundTruth: ',' '.join('%5s' % classes[labels[j]] for j in range(4)))
OUT:
GroundTruth: cat ship ship plane
看神经网络能不能认出来
1 | outputs = net(images) |
输出是一个10个类别的权重。哪个权重高,他会认为更可能是那个。1
2
3_,predicted = torch.max(outputs,1)
print('Predicted: ',' '.join('%5s' % classes[predicted[j]]
for j in rang(4)))
OUT:
Predicted: dog car truck ship
好吧…
大概看下在每个种类上的表现吧1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs, 1)
c = (predicted == labels).squeeze()
for i in range(4):
label = labels[i]
class_correct[label] += c[i].item()
class_total[label] += 1
for i in range(10):
print('Accuracy of %5s : %2d %%' % (
classes[i], 100 * class_correct[i] / class_total[i]))
OUT:
Accuracy of plane : 73 %
Accuracy of car : 44 %
Accuracy of bird : 45 %
Accuracy of cat : 32 %
Accuracy of deer : 26 %
Accuracy of dog : 42 %
Accuracy of frog : 61 %
Accuracy of horse : 75 %
Accuracy of ship : 43 %
Accuracy of truck : 78 %
6.在GPU上训练
这个嘛,额,不存在的,GT740M啊,不支持啊…