ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

卷积神经网络 实战CIFAR10-基于pytorch

2021-12-07 21:58:28  阅读:246  来源: 互联网

标签:loss nn CIFAR10 卷积 labels 0.5 pytorch train size


本文将接着展示一个3+3层的卷积神经网络模型,并给出其在cifar10上的测试效果。

上篇文章指路-> https://blog.csdn.net/m0_62001119/article/details/121757703


目录

代码展示

一、导包工作

二、数据集处理

三、可视化数据

四、搭建网络

五、训练网络

测试效果

心得

参考


代码展示

一、导包工作

import time
import numpy as np
import torch
import torchvision
from torchvision import transforms
import torchvision.datasets as datasets
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
import torch.nn as nn
import torch.optim as optim

二、数据集处理

代码如下:

# ToTensor():[0,255]->[C,H,W];Normalize: 标准化(均值+标准差);数据增强(随机翻转图片,随机调整亮度)
transform1 = transforms.Compose([
                                transforms.RandomHorizontalFlip(),
                                transforms.RandomGrayscale(),
                                transforms.ToTensor(),
                                transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
transform2 = transforms.Compose([
                                transforms.ToTensor(),
                                transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

# cifar_size: 50000+10000 32*32*3 10classes
data_train = datasets.CIFAR10('./c10data', train=True, transform=transform1, download=True)
data_test = datasets.CIFAR10('./c10data', train=False, transform=transform2, download=False)

# 定义batch, 即一次训练的样本量大小
train_batch_size = 128
test_batch_size = 128

# 对数据进行装载,利用batch _size来确认每个包的大小,用Shuffle来确认打乱数据集的顺序。
train_loader = DataLoader(data_train, batch_size=train_batch_size, shuffle=True)
test_loader = DataLoader(data_test, batch_size=test_batch_size, shuffle=False)

# 定义10个分类标签
classes = {'plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'}

三、可视化数据

代码如下:

# 可视化数据
examples = iter(test_loader)
images, labels = examples.next()
img = torchvision.utils.make_grid(images)
img = img/2 + 0.5
npimg = img.numpy()
plt.imshow(np.transpose(npimg, (1, 2, 0)))
plt.show()

图片示例: 

 


四、搭建网络

代码如下:

# 搭建CNN网络
class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()

        # 卷积层
        self.conv1 = nn.Sequential(
            # [(W-F+2P)/S + 1 ] * [(W-F+2P)/S + 1] * M
            # [b,32,32,3]->[b,32,32,64]->[b,16,16,64]
            nn.Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=1),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(64),  # Batch Normalization加速神经网络的训练
            nn.MaxPool2d(kernel_size=2, stride=2),

        )

        self.conv2 = nn.Sequential(
            # [b,16,16,64]->[b,16,16,128]->[b,8,8,128]
            nn.Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=1),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(128),
            nn.MaxPool2d(kernel_size=2, stride=2),
        )

        self.conv3 = nn.Sequential(
            # [b,8,8,128]->[b,8,8,256]->[b,4,4,256]
            nn.Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=1),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(256),
            nn.MaxPool2d(kernel_size=2, stride=2),
        )

        # 全连接层
        self.dense = nn.Sequential(
            # 线性分类器
            nn.Linear(4*4*256, 512),
            nn.ReLU(),
            nn.Dropout(p=0.5),
            nn.Linear(512, 256),
            nn.ReLU(),
            nn.Dropout(p=0.5),
            nn.Linear(256, 10),
        )

    # 前向计算
    def forward(self, x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        # print("x_shape:", x.size())
        x = x.view(x.size(0), -1)
        return self.dense(x)


model = CNN()   # 实例化模型
print(model)    # 打印模型

五、训练网络

代码如下:

# 设置训练次数
num_epochs = 25
# 定义损失函数
criterion = nn.CrossEntropyLoss()
# 定义优化方法
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 定义存储损失函数和准确率的数组
train_losses = []
train_acces = []
eval_losses = []
eval_acces = []

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

# 训练模型
print("start training...")
for epoch in range(num_epochs):

    # 记录训练开始时刻
    start_time = time.time()

    train_loss = 0
    train_acc = 0

    model.train()

    for i, data in enumerate(train_loader):
        inputs, labels = data
        # inputs, labels = inputs.to(device), labels.to(device)
        outputs = model(inputs)
        loss = criterion(outputs, labels)

        optimizer.zero_grad()   # 模型参数梯度清零
        loss.backward()    # 误差反向传递
        optimizer.step()    # 更新参数

        train_loss += loss

        _, pred = outputs.max(1)
        num_correct = (pred == labels).sum().item()
        acc = num_correct / labels.shape[0]
        train_acc += acc

    # 取平均存入
    train_losses.append(train_loss / len(train_loader))
    train_acces.append(train_acc / len(train_loader))

    # 测试集:
    eval_loss = 0
    eval_acc = 0

    # 将模型设置为测试模式
    model.eval()

    # 处理方法同上
    for i, data in enumerate(test_loader):
        inputs, labels = data
        # inputs, labels = inputs.to(device), labels.to(device)
        outputs = model(inputs)
        loss = criterion(outputs, labels)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        eval_loss += loss

        _, pred = outputs.max(1)
        num_correct = (pred == labels).sum().item()  # 记录标签正确的个数
        acc = num_correct / labels.shape[0]
        eval_acc += acc

    eval_losses.append(eval_loss / len(test_loader))
    eval_acces.append(eval_acc / len(test_loader))

    # 输出效果
    print('epoch:{},Train Loss:{:.4f},Train Acc:{:.4f},'
          'Test Loss:{:.4f},Test Acc:{:.4f}'
          .format(epoch, train_loss / len(train_loader),
                  train_acc / len(train_loader),
                  eval_loss / len(test_loader),
                  eval_acc / len(test_loader)))
    # 输出时长
    stop_time = time.time()
    print("time is:{:.4f}s".format(stop_time-start_time))
print("end training.")

测试效果

作者设置的是25个epochs,不过由于CPU计算实在太慢,于是只能先跑了个10次,最终效果还算不错。


心得

这次的神经网络比上次搭建的框架略为复杂一些,数据集由mnist转换为cifar10,数据复杂度在一定程度上有所提升。同时,这次的卷积层引入了Batch Normalization函数,旨在加速训练过程。关于该函数的详细介绍可移步至这个链接


参考

https://blog.csdn.net/v_JULY_v/article/details/51812459?utm_source=app&app_version=4.19.1&code=app_1562916241&uLinkId=usr1mkqgl919blen

标签:loss,nn,CIFAR10,卷积,labels,0.5,pytorch,train,size
来源: https://blog.csdn.net/m0_62001119/article/details/121777952

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有