#导入模块
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))])#normalize对三个通道分别设置(均值)(标准差)
print("1")
#训练集
#数据集下载到本地
trainset=torchvision.datasets.CIFAR10(root="./image_data",train=True,download=False,transform=transform)
print("2")
#数据集加载
trainloader=torch.utils.data.DataLoader(trainset,batch_size=4,shuffle=True,num_workers=2)
print("3")
#测试集
testset=torchvision.datasets.CIFAR10(root="./image_data",train=False,download=False,transform=transform)
testloader=torch.utils.data.DataLoader(testset,batch_size=4,shuffle=True,num_workers=2)
#10个类别
classes = ('plane', 'car', 'bird', 'cat',
'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
import matplotlib.pyplot as plt
import numpy as np
#可视化查看图片
def imshow(img):
print(img.size())#输出[3,32,128]3代表三通道,32表示一幅图片的尺寸,128表示4张图片连在了一块显示
img = img / 2 + 0.5 # unnormalize(因为用matplotlib作图RGB图像值要在0-1之间)
npimg = img.numpy()
plt.imshow(np.transpose(npimg, (1, 2, 0)))#数据维度切换,用matplotlib作图,第三个维度是通道数
plt.imshow(npimg)
plt.show()
#设置一个迭代器
iteration=iter(trainloader)#用训练集
images,labels=iteration.next()#每次产生一个mini_batch
#查看一下图片
# imshow(torchvision.utils.make_grid(images))
labels
for i in range(4):
print("第",i,"副图片的标签是:",classes[labels[i]])
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.conv2=nn.Conv2d(6,16,5)
self.f1=nn.Linear(16*5*5,128)
self.f2=nn.Linear(128,64)
self.f3=nn.Linear(64,10)
def forward(self,x):
x=F.max_pool2d(F.relu(self.conv1(x)),(2,2))
x=F.max_pool2d(F.relu(self.conv2(x)),(2,2))
x=x.view(-1,self.num_reshapes(x))
x=F.relu(self.f1(x))
x=F.relu(self.f2(x))
x=self.f3(x)
return x
#维度转换函数
def num_reshapes(self,x):
size=x.size()[1:]
num_counts=1
for i in size:
num_counts*=i
return num_counts
#实例化网络
net=Net()
out=net(images)
out#输出的是一个mini_batch的结果[4,10] 对四幅图片最后得出的一维向量 用于分类
#定义损失函数
loss_function=nn.CrossEntropyLoss()
#定义优化器
optimizer=torch.optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
loss_list=[]
for epoch in range(2): # loop over the dataset multiple times
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
#获得训练集数据和标签
#input是[4,3,32,32]维度格式的,4是mini_batch,3是通道,32*32是尺寸,labels是[3,6,4,9]分别对应mini_batch中每张图片的分类
inputs, labels = data
# 梯度清零
optimizer.zero_grad()
# 前向传播得到结果
outputs = net(inputs)
#得到损失值
loss = loss_function(outputs, labels)
#反向传播
loss.backward()
#梯度更新到每一步
optimizer.step()
# print statistics
running_loss += loss.item()
if i % 2000 == 1999: # print every 2000 mini-batches
loss_list.append(running_loss/2000)
print('[%d, %5d] loss: %.3f' %
(epoch + 1, i + 1, running_loss / 2000))
running_loss = 0.0
print('Finished Training')
#画loss曲线
import matplotlib.pyplot as plt
plt.plot([i for i in range(12)],loss_list,"red")
plt.xlabel("epoch")
plt.ylabel("loss")
plt.show()
import numpy as np
#在整个数据集上来预测模型的效果
correct=0#记录预测正确的
total=0#总的图像数目
with torch.no_grad():
for i,data in enumerate(testloader,0):
total+=4
#数据和标签
images,labels=data
#正向传播得到输出值
outputs=net(images)
#得到最大分类值和对应的索引
max_value,class_index=torch.max(input=outputs,dim=1)#维度为1
#对预测标签和原始标签列表 求对应位置相同的有多少值 即分类正确的
a=np.array(class_index)
b=np.array(labels)
correct+=sum(a==b)
print("total:",total,"correct:",correct,"正确率:",100*correct/total,"%")