现在知道怎么定义一个网络,计算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啊,不支持啊…