- Deep-Learning-with-PyTorch-1.2 使
- Pytorch学习记录-使用Pytorch进行深度学习,使用案例
- Pytorch学习记录-使用Pytorch进行深度学习,迁移学习
- Pytorch学习记录-使用Pytorch进行深度学习,数据加载
- Pytorch学习记录-使用Pytorch进行深度学习,保存和加
- Pytorch学习记录-使用Pytorch进行深度学习,60分钟
- 给大家推荐:五个Python小项目,Github上的人气很高的
- 给大家推荐:五个Python小项目,Github上的人气很高的
- 给大家推荐:五个Python小项目,Github上的人气很高的
- 使用PyTorch进行深度学习
使用Pytorch进行深度学习,60分钟闪电战
本次课程的目标:
- 从更高水平理解Pytorch的Tensor(张量)和神经网络
- 训练一个小的图像分类神经网络
注意确定已经安装了torch和torchvision
训练一个分类器
上一节粗略地看到如何定义神经网络、计算损失、更新网络权重数据,但是,数据呢?
数据
通常来说,当你需要处理图片、文字、音频或视频数据时,你可以使用标准python包加载数据到numpy中,然后将这些数据转为torch.*Tensor。
- 图像使用Pillow或是OpenCV
- 音频使用scipy或是librosa
- 文本使用NLTP或是Spacy
为了可视化,Pytorch提供一个包torchvision,它包含常用数据集(Imagenet、CIFAR10、MNIST等)的加载,同时还有转换图像用的工具。
在这个教程中,使用CIFAR10数据集,包括‘飞机’‘汽车’‘鸟’‘猫’‘鹿’‘狗’‘青蛙’等分类。 其中的图片为33232(3通道颜色,32*32像素大小)。
CIFAR10example
训练一个图像分类器
这里使用CNN,包括以下步骤
- 使用torchvision加载和归一CIFAR10训练和测试数据集
- 定义一个CNN
- 定义一个损失函数
- 在训练集上训练网络
- 在测试集上测试网络
下面一步一步来实现。这里要关注的时对网络的定义、对数据的加载。
1. 加载和归一CIRAR10数据
加载数据很简单,同样数据要从网上下载,和很久以前处理MNIST数据一样,只是这次我在学校,直接下载了。速度会比较慢。
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=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True, num_workers=2)
testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(testset, 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
# functions to show an image
def imshow(img):
img = img / 2 + 0.5 # unnormalize
npimg = img.numpy()
plt.imshow(np.transpose(npimg, (1, 2, 0)))
plt.show()
if __name__ == '__main__':
# get some random training images
dataiter = iter(trainloader)
images, labels = dataiter.next()
# show images
imshow(torchvision.utils.make_grid(images))
# print labels
print(' '.join('%5s' % classes[labels[j]] for j in range(4)))
cat ship ship plane
2. 定义一个CNN(卷积神经网络)
从前面定义神经网络部分复制神经网络并修改它以获取3通道图像(而不是定义的1通道图像)。
import 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
3. 定义损失函数和优化函数
直接使用随机梯度下降SGD
net=Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
4. 训练网络
忙了大半天,可以训练了
# 在这里只进行两次迭代
for epoch in range(2):
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i % 2000 == 1999:
print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 2000))
running_loss = 0.0
[1, 2000] loss: 2.249
[1, 4000] loss: 1.973
[1, 6000] loss: 1.739
[1, 8000] loss: 1.622
[1, 10000] loss: 1.565
[1, 12000] loss: 1.512
[2, 2000] loss: 1.439
[2, 4000] loss: 1.406
[2, 6000] loss: 1.375
[2, 8000] loss: 1.381
[2, 10000] loss: 1.348
[2, 12000] loss: 1.290
可以看到损失数值是在降低。
5. 测试网络
# 调用之前的方法,打印图片
imshow(torchvision.utils.make_grid(images))
print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))
outputs = net(images)
_, predicted = torch.max(outputs, 1)
print('Predicted: ', ' '.join('%5s' % classes[predicted[j]] for j in range(4)))
GroundTruth: cat ship ship plane
Predicted: bird car ship plane
Accuracy of the network on the 10000 test images: 54 %
可以看到,预测四个,只对了两个……这个是和迭代次数太少有关系。
再看一下整体的正确率和各类型的正确率
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))
class_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]))
Accuracy of the network on the 10000 test images: 54 %
Accuracy of plane : 57 %
Accuracy of car : 64 %
Accuracy of bird : 40 %
Accuracy of cat : 36 %
Accuracy of deer : 33 %
Accuracy of dog : 33 %
Accuracy of frog : 76 %
Accuracy of horse : 64 %
Accuracy of ship : 69 %
Accuracy of truck : 64 %
整体正确率为54%,各类的正确率不一样。
网友评论