使用pytorch训练一个图像分类器

原教程链接点击这里

import torch
import torchvision 
import torchvision.transforms as transforms
import ssl
 
ssl._create_default_https_context = ssl._create_unverified_context#全局关闭证书验证

Note:

ssl._create_default_https_context = ssl._create_unverified_context

因为使用pytorch下载数据集会报错:证书过期,无法下载数据集,该语句设置全局关闭证书验证,注意要包含包,其他证书过期的错误也可使用该方法。

对于图像任务,torchvision,包含了处理一些基本图像数据集的方法。这些数据集包括 Imagenet, CIFAR10, MNIST 等。除了数据加载以外,torchvision 还包含了图像转换器,torchvision.datasets 和 torch.utils.data.DataLoader。torchvision包含了目前流行的数据集,模型结构和常用的图片转换工具。

torchvision.datasets: 一些加载数据的函数及常用的数据集接口;
torchvision.models:包含常用的模型结构(含预训练模型),例如AlexNet、VGG、ResNet等;
torchvision.transforms:常用的图片变换,例如裁剪、旋转等;
torchvision.utils:其他的一些有用的方法。

一. 数据

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)
testloader=torch.utils.data.DataLoader(testset,batch_size=4,shuffle=True,num_workers=2)
classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

Note:

此处我运行时的代码会报错

Traceback (most recent call last): File
"D:\anaconda\envs\pytorch\lib\multiprocessing\popen_spawn_win32.py", line 93, in init reduction.dump(process_obj, to_child) File
"D:\anaconda\envs\pytorch\lib\multiprocessing\reduction.py", line 60, in dump ForkingPickler(file, protocol).dump(obj) OSError: [Errno 22] Invalid argument 修改代码 num_workers=2 值改为0

修改代码 num_workers=2 值改为0解决,分析原因dataloader一次性创建num_worker个工作进程,可能与本人硬件有关。

torchvision.transforms.Compose()
这个类的主要作用是串联多个图片变换的操作
先由HWC转置为CHW格式;
再转为float类型;
最后,每个像素除以255。

数据标准化——transforms.normalize()
逐channel的对图像进行标准化,可以加快模型的收敛。
output = (input - mean) / std
mean:各通道的均值
std:各通道的标准差
inplace:是否原地操作

import matplotlib.pyplot as plt
import numpy as np

# 展示图像的函数
def imshow(img):
    img = img / 2 + 0.5# unnormalize
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))
    plt.show()
# 获取随机数据
dataiter = iter(trainloader)
images, labels = dataiter.next()
# 展示图像
imshow(torchvision.utils.make_grid(images))#此处图片个数与BatchSize一致
# 显示图像标签
print(' '.join('%5s' % classes[labels[j]] for j in range(4)))

在这里插入图片描述

二. 构建网络模型

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)#4*400
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x
        
net = Net()
print(net)
Net(
  (conv1): Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))
  (pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
  (fc1): Linear(in_features=400, out_features=120, bias=True)
  (fc2): Linear(in_features=120, out_features=84, bias=True)
  (fc3): Linear(in_features=84, out_features=10, bias=True)
)

三. 损失和优化器

import torch.optim as optim
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(),lr=0.001,momentum=0.9)

四. 训练

for epoch in range(2):
    running_loss = 0.0
    for i,data in enumerate(trainloader,0):#enumerate(sequence, [start=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
print('Finished Training')  
[1,  2000] loss: 2.215
[1,  4000] loss: 1.875
[1,  6000] loss: 1.698
[1,  8000] loss: 1.612
[1, 10000] loss: 1.563
[1, 12000] loss: 1.523
[2,  2000] loss: 1.473
[2,  4000] loss: 1.424
[2,  6000] loss: 1.395
[2,  8000] loss: 1.404
[2, 10000] loss: 1.382
[2, 12000] loss: 1.341
Finished Training

五. 测试集结果

dataiter = iter(testloader)
images, labels = dataiter.next()
imshow(torchvision.utils.make_grid(images))
print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))

在这里插入图片描述

oututs = net(images)
_,predicted = torch.max(outputs,1)
print('predicted:',' '.join('%5s' % classes[predicted[j]] for j in range(4)))
#join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
predicted:  ship  deer   car  frog

Note:

output = torch.max(input, dim)

输入
input是softmax函数输出的一个tensor
dim是max函数索引的维度0/1,0是每列的最大值,1是每行的最大值

输出
函数会返回两个tensor,第一个tensor是每行的最大值;第二个tensor是每行最大值的索引。

整体的准确率

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))

Accuracy of the network on the 10000 test images: 51 %

类准确率

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()#从数组的形状中删除单维度条目,即把shape中为1的维度去掉
        
        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 plane : 61 %
Accuracy of   car : 61 %
Accuracy of  bird : 39 %
Accuracy of   cat : 20 %
Accuracy of  deer : 47 %
Accuracy of   dog : 60 %
Accuracy of  frog : 55 %
Accuracy of horse : 63 %
Accuracy of  ship : 51 %
Accuracy of truck : 53 %
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 确认我们的电脑支持CUDA,然后显示CUDA信息:
print(device)

Note

output = torch.max(input, dim)
input是softmax函数输出的一个tensor
dim是max函数索引的维度0/1,0是每列的最大值,1是每行的最大值
函数会返回两个tensor,第一个tensor是每行的最大值;第二个tensor是每行最大值的索引。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值