课程链接:Python人工智能20个小时玩转NLP自然语言处理【黑马程序员】_哔哩哔哩_bilibili
目的:对不同的输入图像进行识别并分类。采用CIFAR10数据集,进行单分类任务
目录
总体步骤:
1、使用torchvision下载CIFAR10数据集
2、定义卷积神经网络
3、定义损失函数
4、在训练集上训练模型
5、在测试集上测试模型
一、数据集处理
1.1 下载数据集
import torch
import torchvision
import torchvision.transforms as transforms
#transforms包要将torchvision中[0,1]数据格式转化为[-1,1]的标准张量格式
#首先创建数据转换器,将参数转化为tensor需要的格式并且将数据变为[-1,1]中
transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize(0.5,0.5,0.5),(0.5,0.5,0.5)])
#数据的load与提取,数据位置放在当前代码目录下的data中,下载的是训练集train=True,并且下载好的数据用transform进行转换
trainset=torchvision.datasets.CIFAR10(root="./data",train=True,download=True,transform=transform)
#数据要DataLoader封装,便于pytorch后续操作,迭代器设置后续一次性访问四条数据,suffle=True表示数据打乱,并且多个线程加速数据读取
trainloader=torch.utils.data.DataLoader(trainset,batch_size=4,suffle=True,num_workers=2)
#测试集train=False,测试数据不需要打乱所以suffle=False
testset=torchvision.datasets.CIFAR10(root="./data",train=False,download=True,transform=transform)
testloader=torch.utils.data.DataLoader(testset,batch_size=4,suffle=False,num_workers=2)
#10个标签
classes=("plane","car","bird","cat","deer","dog","frog","horse","ship","truck")#课程中一直使用Linux ls 命令用于显示指定工作目录下的内容。如果Windows下载报错可以将num_workers设置为0
1.2 展示数据集
#展示训练集图片
import matplitlib.pyplot as plt
import numpy as np
#构建展示图片的函数,标准的数据的处理展示函数
def imshow(img)
img=img/2+0.5#规范化
npimg=img.numpy()#tensor转换为numpy
plt.imshow(np.transpose(npimg,(1,2,0)))#维度转换
plt.show()
#直接使用封装的数据迭代器trainloader的iter
dataiter=iter(trainloader)
#读取images,lables
images,lables=dataiter.next()
#以网格的形式展示图片
imshow(torchvision.utils.make_grid(images))
#以字符串的形式打印标签
print("".join("%5s"%classes[labels[j]] for j in range(4)))二、定义卷积神经网络
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)#输入3,输出6,kernel5
self.conv2=nn.Conv2d(6,16,5)
self.pool=nn.MaxPool2d(2,2)#最大化池化窗口2*2
self.fc1=nn.Linear(16*5*5,120)
self.fc2=nn.Linear(120,84)
self.fc3=nn.Linear(84,10)#分类器最终的分类结果是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)#将三维张量缩减为2维,以适配全连接层的输入
x=F.relu(self.fc1(x))
x=F.relu(self.fc2(x))
x=self.fc3(x)#经历最后一个全连接层
return x
net=Net()#类的实例化
print(net)2.2 定义损失函数与优化器
*这里采用的是交叉熵的损失函数和随机梯度下降优化器
#采用交叉熵损失函数和随机梯度下降优化器
import torch.optim as optim
criterion=nn.CrossEntropyLoss()
#多分类任务最好的损失函数:交叉熵损失函数,随机梯度下降优化器
optimizer=optim.SGD(net.parameters(),lr=0.001,momentum=0.9)#实例化类,设置学习率2.3 在训练集中训练模型
*注意梯度下降算法需要迭代式训练,即需要一个批次一个批次来
for epoch in range(2):
#数据集遍历两轮,并用loss记录损失
running_loss=0.0
for i,data in enumerate(trainloader,0):
#data取出来分成两部分,一部分是图片的张量inputs,一部分是标签labels
inputs,lable=data
#梯度清零
optimizer.zero_grad()
outputs=net(inputs)
loss=criteron(outputs,labels)#交叉熵比较output和label
#反向传播+参数更新
loss.backward()
optimizer.step()
#打印信息,观察并监督代码的运行
running_loss+=loss.item()
if(i+1)%2000==0#每隔两千轮打印一次
print('[%d,%5d] loss:%.3f'% (epoch+1,i+1,running_loss/2000))\
#打印到几个epoch,到几个轮,以及损失
running_loss=0.0
print('Finished Training')
PATH="./cifar_net,pth"#设置一个保存路径在当前文件夹下
torch.save(net.state_dict(),PATH)#保存的是状态字典
2.4 在测试集中测试模型
先仅仅测试4张图看看demo
#首先取一个批次的数据展示图片,和前面训练集中展示图片是一样的
dataiter=iter(testloader)
images,lables=dataiter.next()
#以网格的形式展示图片
imshow(torchvision.utils.make_grid(images))
#标签以字符串的形式打印
print("GroundTruth:","".join("%5s"%classes[labels[j]] for j in range(4)))
#加载图片并对测试图片进行预测
net=Net()#首先实例化类对象
net.load_state_dict(torch.load(PATH))#在原来的路径中加载这个状态字典
#代码理解是首先load一个torch的path,然后从这个torch中把状态字典load进来
outputs=net(images)
predicted=torch.max(outputs,1)#贪心算法,选取最大概率类别
#每个批次的四个值都列一遍
print("Predicted:","".join("%5"%classes[predicted[j]] for j in range(4)))对所有的测试集进行测试:
correct=0
total=0
with torch.mo_grad():#不进行卷积
for data in testloader:
images,labels=data#图片和标签
outputs=net(images)
predicted=torch.max(outputs.data,1)#1表示第一个维度
total+=labels.size(0)#看总共遍历了多少样本
correct+=(predicted==labels).sum().item()#累加成功样本个数,sum中真的按照1来加,假的为0
print("Accuracy of the network on the 10000 test images: %d%%"%(100*correct/total)
#最终以百分号形式打印
原教程中代码有-,这里不理解啥意思?也没有运行,找时间调试一下更改这里
2.5分类别测试模型准确率
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)#将图片放进网络,得到output
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]))#net.to(device)将数据和模型转换到GPU上面
小节

版权声明:本文为qq_42035862原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。