pytorch2.2——完整网络练习

本次练习使用torchvision下载 cifar10数据
步骤为:
1定义卷积神经网络
2定义损失函数
3在训练集上训练模型
4在测试集上测试模型
5更改GPU训练
# 第一步
# 导入torchvision包下载数据集
import torch
import torchvision
import torchvision.transforms as transforms
##下载数据集并对图片进行调整,因为torch数据集的输出是PILImage格式,数据域在[0,1],
# 我们需要将其转换成标准数据域[-1,1]的张量格式
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=Ture,transform=transform)
trainloader = torch.utils.data.DataLoader(trainset,batch_size=4,
                                          shuffle=True,num_workers=2)#
# 放进dataloader,分为训练集,4个小批次,打乱,使用两个线程
testset = torchvision.datasets.CIFAR10(root='./data',train=False,
                                        download=True,transform=transform)
testloader = torch.utils.data.DataLoader(testset,batch_size=4,
                                          shuffle=False,num_workers=2)#测试不用打乱
# 标签
classer=('plane','car','bird','cat',
         'deer','dog','frog','horse','ship','truck')

数据集准备完了,可以查看一下:

## 导入画图包和numpy
import matplotlib.pyplot as plt
import numpy as np
#构建展示图片的函数
def imshow(img):
    img=img/2+0.5#规整化
    npimg=img.numpy()#tensor转化为array
    plt.imshow(np.transpose(npimg,(1,2,0)))#
    plt.show()
# 从数据迭代器中读取一张照片
dataiter = iter(trainloader)#迭代器
images, labels =dataiter.next()#.next()就能读出来
#展示图片
imshow(torchvision.utils.make_grid(images))
#打印标签label
print(' '.join('%5s' % classer[labels[j]] for j in range(4)))

pytorch2.2——完整网络练习_第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
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.8)#传入所有参数,随机梯度下降,学习率0.01,冲量0.8

CPU训练模型

## 在训练集上训练模型
#采用基于梯度下降的优化算法,需要多个轮次的迭代训练
for epoch in range(3):#一轮训练多次
    running_loss=0
    for i ,data in enumerate(trainloader,0):
        #data中包含图像张量input以及标签
        input , labels =data
        #首先将优化器梯度清零
        optimizer.zero_grad()
        #输入张量引入网络,得到输出张量output
        outputs=net(input)
        #利用输出和标签计算loss损失
        loss = criterion(outputs,labels)
        #反向传播+参数更新,
        loss.backward()
        optimizer.step()
        #打印轮次和损失值
        running_loss += loss.item()
        if (i+1) % 200 ==0:
            print('[%d,%5d] loss: %.3f' %
                  (epoch +1 , i+1 ,running_loss /2000))
            running_loss =0.0
print("Finished Training")

部分结果

[3,11200] loss: 0.126
[3,11400] loss: 0.122
[3,11600] loss: 0.125
[3,11800] loss: 0.128
[3,12000] loss: 0.117
[3,12200] loss: 0.127
[3,12400] loss: 0.116
Finished Training

保存模型参数

##设定模型的保存位置
PATH="./cifar_net.pth"
# 保存模型的字典
torch.save(net.state_dict(),PATH)

跑测试集,先用一个batch测试

##在测试集上测试模型
# 第一步展示测试集中的若干图片
dataiter = iter (testloader)
image ,labels =dataiter.next()
#打印原始图片
imshow(torchvision.utils.make_grid(image))
#打印真实的标签
print("Groundtruth: "," ".join('%5s' % classer[labels[j]] for j in range(4)))

pytorch2.2——完整网络练习_第2张图片

 

## 加载模并对测试图片进行预测
# 首先实例化模型的类对象
net = Net()
# 加载训练阶段保存好的模型的状态字典(也就是参数值)
net.load_state_dict(torch.load(PATH))
#利用模型对图片进行预测
outputs=net(image)
#共有10个类别,采用模型计算出的概率最大的作为预测的类别
_,predicted = torch.max(outputs,1)
#打印预测标签的结果
print("Predicted:"," ".join("%5s" % classer[predicted[j]] for j in range(4)))

Predicted:   cat  ship  ship  ship

可以看到,第四个预测错了,下面在所有集合上进行测试

## 在全部测试集合上的表现
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("10000张测试图片的网络准确率:%d %%" %(
    100*correct/total
))

10000张测试图片的网络准确率:55 %

每个分类下准确率,这项更细致,很多函数建议查一查,或者可以把中间变量打印出来看一看,我有很多搞不懂,然后打印出来就搞懂了

## 每个分类下的准确率
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)
        # max _返回最大值,predicted返回最大值索引,1是按照行
        c= (predicted ==labels).squeeze()#sequeeze是什么?去掉维度为1的维度
        # c每次输出TF共4个一维

        for i in range(4):
            label= labels[i]
            class_correct[label] +=c[i].item()
            class_total[label]+=1
for i in range(10):
    print("%5s 的准确率为:%2d %%" %(
        classer[i],100*class_correct[i]/class_total[i]
    ))

lane 的准确率为:59 %
  car 的准确率为:51 %
 bird 的准确率为:44 %
  cat 的准确率为:26 %
 deer 的准确率为:44 %
  dog 的准确率为:36 %
 frog 的准确率为:77 %
horse 的准确率为:73 %
 ship 的准确率为:67 %
truck 的准确率为:75 %

在GPU上训练的方法

首先定义设备

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)

cuda:0##我有一块小破显卡

然后将模型和数据放进GPU(下面井号包裹住的就是重要的)

###########################333
net.to(device)
####################
## 在训练集上训练模型
#采用基于梯度下降的优化算法,需要多个轮次的迭代训练
for epoch in range(3):#一轮训练多次
    running_loss=0
    for i ,data in enumerate(trainloader,0):
        #data中包含图像张量input以及标签
##########################################################
        input , labels =data[0].to(device), data[1].to(device)
##########################################################
        #首先将优化器梯度清零
        optimizer.zero_grad()
        #输入张量引入网络,得到输出张量output
        outputs=net(input)
        #利用输出和标签计算loss损失
        loss = criterion(outputs,labels)
        #反向传播+参数更新,
        loss.backward()
        optimizer.step()
        #打印轮次和损失值
        running_loss += loss.item()
        if (i+1) % 200 ==0:
            print('[%d,%5d] loss: %.3f' %
                  (epoch +1 , i+1 ,running_loss /2000))
            running_loss =0.0
print("Finished Training")

结束

你可能感兴趣的:(深度学习,人工智能)