Pytorch实现cifar10多分类总结

CIFAR-10简介

 

CIFAR-10是一个常用的图像分类数据集,每张图片都是 3×32×32,3通道彩色图片,分辨率为 32×32。

它包含了10个不同类别,每个类别有6000张图像,其中5000张用于训练,1000张用于测试。这10个类别分别为:飞机、汽车、鸟类、猫、鹿、狗、青蛙、马、船和卡车。CIFAR-10分类任务是将这些图像正确地分类到它们所属的类别中。对于这个任务,可以使用深度学习模型,如卷积神经网络(CNN)来实现高效的分类。

一、数据加载及预处理(实现数据加载及预处理、归一化的理解、访问数据集、Dataset对象、Dataloader对象)

 

# 导包

import torchimport torchvision

import torchvision.transforms as transforms

# 定义对数据的预处理transform = transforms.Compose( [transforms.ToTensor(), # 转为Tensor格式 transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) #归一化

# 训练集

trainset=torchvision.datasets.CIFAR10(root='./data', train=True, download=False, transform=transform)

# PyTorch提供的CIFAR-10数据集的类,用于加载CIFAR-10数据集

# root:数据集存储的根目录

# train:指定加载的是CIFAR-10的训练集

# transform:数据集的预处理方式

 

数据加载器trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True,num_workers=0)

# torch.utils.data.DataLoader 创建一个数据加载器

# batch_size=4 表示每个批次包含4个样本# shuffle=True 表示在每个epoch对数据进行打乱

# num_workers=0 表示不使用多进程加载数据

# 测试集

testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=False, transform=transform)

testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False, num_workers=0)

# train=False 表示加载测试集

# shuffle=False 表示测试集不需要打乱。

# 定义类别标签:定义CIFAR-10数据集中10个类别的名称classes = ('plane','car','bird','cat', 'deer','dog','frog','horse','ship','truck')

 

import matplotlib.pyplot as plt

import numpy as np

# 定义图像显示函数

def imshow(img):    img = img / 2 + 0.5  # 对图像进行反归一化处理,恢复到原始的像素值范围    

npimg = img.numpy()  # 将PyTorch张量转换为NumPy数组,方便matplotlib处理   plt.imshow(np.transpose(npimg, (1, 2, 0)))   #彩色图像,三个通道:R G B    

plt.show()          # 显示图像

dataiter = iter(trainloader)

 # 随机获取部分训练数据(获取训练数据迭代器)

for images, labels in dataiter:   # 使用for循环来迭代数据    imshow(torchvision.utils.make_grid(images))  

# 显示图像

print(' '.join('%5s' % classes[labels[j]] for j in range(4)))  # 打印标签

二、定义网络

import torch.nn as nn

import torch.nn.functional as Fdevice = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

# 判断是否有可用的CUDA设备,如果有使用GPU版本,没有使用CPU版本

class CNNNet(nn.Module): #定义一个名为CNNNet的类

def __init__(self):

super(CNNNet, self).__init__()

# 调用初始化函数

self.conv1 = nn.Conv2d(in_channels=3,out_channels=16,kernel_size=5,stride=1)

# 卷积层:输入三个通道 输出16个特征图 卷积核大小为5 步长为1

self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2) # 最大池化层

self.conv2 = nn.Conv2d(in_channels=16,out_channels=36,kernel_size=3, stride=1)# 卷积层

self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2) #最大池化层

def forward(self, x):

x = self.pool1(F.relu(self.conv1(x)))

x = self.pool2(F.relu(self.conv2(x))) # 卷积、激活函数、池化 # print(x.shape)

x = x.view(-1,36*6*6) # 拉平成一维向

 x = F.relu(self.fc2(F.relu(self.fc1(x)))) return x# 创建网络实例并打印参数数量

net = CNNNet()

print("net have {} paramerters in total".format(sum(x.numel() for x in net.parameters())))import torch.optim as optim # 导入优化器模块

三、定义损失函数和优化器(loss和optimizer)

LR = 0.001 # 定义学习率为0.001

criterion = nn.CrossEntropyLoss()

# 定义损失函数,适用于多分类问题

optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)# net.parameters()表示要优化的模型参数,即神经网络中的权重和偏置。

# lr=0.001是学习率(learning rate),控制每次参数更新的步长大小。

# momentum=0.9表示动量(momentum)参数,用于加速优化过程并避免陷入局部最优解。

print(net) # 打印网络结构nn.Sequential(*list(net.children())[:4]) # 取模型中的前四层

四、训练网络并更新网络参数

for epoch in range(10):

#指定训练的轮数为10轮(epoch),即遍历整个数据集十次。

running_loss = 0.0 # 记录当前训练阶段的损失值

for i, data in enumerate(trainloader,0): # 内层批次循环

# 获取训练数据

inputs, labels = data

inputs, labels = inputs.to(device), labels.to(device)

optimizer.zero_grad() # 权重参数梯度清零

# 正向及反向传播

outputs = net(inputs) loss = criterion(outputs, labels)

# 进行前向传播,然后计算损失函数

loss loss.backward() # 自动计算损失函数相对于模型参数的梯度

optimizer.step() # 使用优化器 optimizer 来更新模型的权重和偏置,以最小化损失函数

# 显示损失值 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') # 训练结束提示

五、测试网络

dataiter =iter(testloader) # 测试数据加载器for i,(images,labels) in enumerate(dataiter): # 使用enumerate函数遍历迭代器 imshow(torchvision.utils.make_grid(images))

print('GroundTruth',''.join('%5s' %classes[labels[j]] for j in range(4)))

print("==================================================================")

images,labels=images.to(device),labels.to(device)

outputs=net(images)

_, predicted = torch.max(outputs, 1)

print('Predicted',''.join('%5s' %classes[predicted[j]] for j in range(4)))

correct=0 # 用于记录模型在测试集中预测正确的样本数量,初始化为0

total=0 # 用于记录测试集的样本总数

with torch.no_grad():

for data in testloader:

images, labels = data

images, labels = images.to(device), labels.to(device)

outputs=net(images)

_, predicted = torch.max(outputs, 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

images,labels = images.to(device), labels.to(device)

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

全局平均池化层

import torch.nn as nn #导包

import torch.nn.functional as F

device = torch.device("cuda:0" if torch.cuda.is_available() else 'cpu') #检查cuda版本是否可用

class Net(nn.Module): #定义神经网络类,继承自nn.Module(pytorch中所有神经网络模型的基类

def __init__(self):类的初始化方法 super(Net,self).__init__()父类nn.Module self.conv1 = nn.Conv2d(3,16,5) #定义第一个卷积层,输入通道数为3(彩色图像三个通道,输出通道数为16,卷积核大小为5x5

self.pool1 = nn.MaxPool2d(2,2) #定义第一个最大池化层,池化窗口大小为2x2

self.conv2 = nn.Conv2d(16,36,5) #定义第二个卷积层,输入通道数为16.输出通道为36,卷积核大小为5x5

self.pool2 = nn.MaxPool2d(2,2) #定义第二层最大池化层,池化窗口为2x2 self.aap=nn.AdaptiveAvgPool2d(1) #定义自适应平均池化层,输出大小为1x1

self.fc3 = nn.Linear(36,10) #定义全连接层,输出特征数为36,输出特征数为10

def forward(self,x): #定义前向传播方法

x = self.pool1(F.relu(self.conv1(x))) 对输入的进行第一次卷积操作,然后应用relu激活函数,然后进行最大池化

x = self.pool2(F.relu(self.conv2(x)))对输入的进行第二次卷积操作,然后应用relu激活函数,然后第二次进行最大池化

x = self.aap(x) #进行自适应平均池化

x = x.view(x.shape[0],-1) #将池化后的输出展平为一维向量

x = self.fc3(x) 通过全连接层得到最终输出 return x

net = Net()

net = net.to(device)

print("net_gvp have {} paramerters in total".format(sum(x.numel() for x in net.parameters()))) #计算并打印网络学习中所有可学习参数的总数

import torch.optim as optim

LR=0.001学习率,criterion=nn.CrossEntropyLoss()交叉熵损失函数,方便计算模型输出和真实标签的损失值optimizer = optim.SGD(net.parameters(),lr=0.001,momentum=0.9)随机梯度下降SGD优化器

 

训练模型

for epoch in range(10):

running_loss=0.0初始化

for i, data in enumerate(trainloader,0):

#trainloader数据加载器,enumerate用于同时获取数据的索引i和数据data获取训练数据 inputs,labels = data

inputs,labels = inputs.to(device),labels.to(device)

#权重参数梯度清零

optimizer.zero_grad() #将优化器的梯度清零,避免梯度累加

#正向及反向传播

outputs = net(inputs)

loss = criterion(outputs,labels)计算网络输出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')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值