使用CNN对cifar10数据进行预测

CIFAR-10 是由 Hinton 的学生 Alex Krizhevsky 和 Ilya Sutskever 整理的一个用于识别普适物体的小型数据集。一共包含 10 个类别的 RGB 彩色图 片:飞机( a叩lane )、汽车( automobile )、鸟类( bird )、猫( cat )、鹿( deer )、狗( dog )、蛙类( frog )、马( horse )、船( ship )和卡车( truck )。图片的尺寸为 32×32 ,数据集中一共有 50000 张训练圄片和 10000 张测试图片。

这里我们通过CNN对其进行特征的提取,训练出一个模型,再用训练出的模型对测试集进行预测,得到预测的结果

这里我们使用tensorboardX来绘制损失函数,
使用的方式是我们在代码中使用SummaryWriter来写入events文件,例如,写入的文件在E:\pythonProject1\runs\scalar下(注意这是文件夹的名字,不是文件的名字)
在cmd中输入下列命令:
tensorboard --logdir=E:\pythonProject1\runs\scalar
得到下面的界面
在这里插入图片描述
在浏览器中输入:http://localhost:6006/ 即可打开我们的tensorBoard面板,在我们已经训练结束,得到了loss曲线,展示的结果如下所示:
在这里插入图片描述

放大的Loss曲线如下所示:
在这里插入图片描述
可以看到,上述的图形会有一个波动,我们可以调节左侧的Smoothing来增加它的平滑度,使曲线平滑,如下所示:
在这里插入图片描述

其中虚线是我们原始的图像,实线是我们平滑之后的图像

同时TensorBoard还有实时刷新的功能

import torch
from torch.utils.data import DataLoader
from torchvision import datasets
import torchvision
from torch import optim
import numpy as np
from tensorboardX import SummaryWriter
import torch.nn.functional as F

torch.cuda.set_device(1)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

batch_size = 1000
cifar_train = datasets.CIFAR10(root="./data", train=True, transform=torchvision.transforms.ToTensor(), download = True)
cifar_loader = DataLoader(dataset=cifar_train, shuffle=True, batch_size=batch_size)


class CNN(torch.nn.Module):
    def __init__(self):
        super(CNN, self).__init__()

        # 3*32*32   --->   10*14*14
        self.conv1 = torch.nn.Sequential(

            torch.nn.Conv2d(in_channels=3, out_channels=10, kernel_size=5),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(kernel_size=2)
        )

        #10*14*14   --> 20*5*5
        self.conv2 = torch.nn.Sequential(
            torch.nn.Conv2d(in_channels=10,out_channels=20,kernel_size=5),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(kernel_size=2)

        )

        self.conv3 = torch.nn.Sequential(

            torch.nn.Conv2d(in_channels=20, out_channels=30,kernel_size=3),
            torch.nn.ReLU(),
        )

        self.linear = torch.nn.Linear(30*3*3, 10)



    def forward(self,x):

        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        x = x.view(batch_size, -1)
        x = self.linear(x)

        return x

model = CNN()
model = model.to(device)

writer = SummaryWriter('runs/scalar')
optimizer = optim.SGD(params=model.parameters(), lr=0.01, momentum=0.9)
criteria = torch.nn.CrossEntropyLoss()

epoch = 100

for train_epoch in range(epoch):

    Loss = 0
    for i,date in enumerate(cifar_loader, 0):

        inputs, labels = date

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

        x = model(inputs)


        loss = criteria(x, labels)
        Loss += loss.item()


        #误差反传
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

    writer.add_scalar('loss', Loss/(len(cifar_train) / batch_size), global_step=train_epoch + 1)
    #writer.add_scalar('epoch',Loss, global_step=train_epoch)
    print("Epoch {}     Loss = {}".format(train_epoch + 1, Loss/(len(cifar_train) / batch_size)))

torch.save(model.state_dict(), "CNN_CIFAR10.pth")

网络中使用了三个卷积层和两个最大池化层,最后得到一个3033的张量,将其转变为向量的性质,并添加一个全连接层,由3033维降低到我们要预测的10维

在训练完毕后,通过torch.save()将模型中的参数进行保存,然后再进行预测操作

测试模型如下所示:

import torch
from torch.utils.data import DataLoader
from torchvision import datasets
import torchvision
import matplotlib.pyplot as plt
import numpy as np
from torchvision.utils import make_grid
import torch.nn.functional as F


batch_size = 100
torch.cuda.set_device(1)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
cifar_test = datasets.CIFAR10("./data", train=False, transform=torchvision.transforms.ToTensor(), download=True)
cifar_test_loader = DataLoader(dataset=cifar_test, shuffle=True,batch_size=batch_size)


class CNN(torch.nn.Module):
    def __init__(self):
        super(CNN, self).__init__()

        # 3*32*32   --->   10*14*14
        self.conv1 = torch.nn.Sequential(

            torch.nn.Conv2d(in_channels=3, out_channels=10, kernel_size=5),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(kernel_size=2)
        )

        #10*14*14   --> 20*5*5
        self.conv2 = torch.nn.Sequential(
            torch.nn.Conv2d(in_channels=10,out_channels=20,kernel_size=5),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(kernel_size=2)

        )

        self.conv3 = torch.nn.Sequential(

            torch.nn.Conv2d(in_channels=20, out_channels=30,kernel_size=3),
            torch.nn.ReLU(),
        )

        self.linear = torch.nn.Linear(30*3*3, 10)



    def forward(self,x):

        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        x = x.view(batch_size, -1)
        x = self.linear(x)

        return x



model = CNN()
model.load_state_dict(torch.load("CNN_CIFAR10.pth"))
model = model.to(device)

correct_num = 0
total_num = len(cifar_test)

with torch.no_grad():

    total = 0
    for i, data in enumerate(cifar_test_loader):

        inputs, labels = data

       # img = inputs.reshape(batch_size, 3, 32, 32)

      #  plt.imshow(np.transpose(make_grid(img).numpy(), (1,2,0)))
      #  plt.show()

        inputs, labels = inputs.to(device), labels.to(device)
        x = model(inputs)
        _, y = torch.max(x,dim=1)

        

        correct_num += sum(y == labels)

print("Correct Rate = {}%".format(correct_num * 100 / total_num))




输出的结果为:
在这里插入图片描述
在这里我们可以得到65%的正确率在测试集上

如果我们使用训练集的样本进行测试,得到的结果如下所示:
在这里插入图片描述
在测试集上,有71%的正确率

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值