• 卷积神经网络初体验——使用pytorch搭建CNN


    〇、基本流程

    加载数据->搭建模型->训练->测试

    一、加载数据

    通过使用torch.utils.data.DataLoader和torchvision.datasets两个模块可以很方便地去获取常用数据集(手写数字MNIST、分类CIFAR),以及将其加载进来。

    1.加载内置数据集

    
    
     import torch
    from torch.utils.data import DataLoader
    from torchvision import datasets
    from torchvision import transforms

     1 train_loader = torch.utils.data.DataLoader(
     2     torchvision.datasets.MNIST('mnist_data', train=True, download=True,
     3                                transform=torchvision.transforms.Compose([
     4                                    torchvision.transforms.ToTensor(),
     5                                    torchvision.transforms.Normalize(
     6                                        (0.1307,), (0.3081,))
     7                                ])),
     8     batch_size=batch_size, shuffle=True)
     9 # train 是否为训练集,         download 数据集不存在时是否下载数据集
    10 # ToTensor() 转换成tensor格式,Normalize() 归一化,将数据作(data-mean)/std
    11 # batch_size 加载一批数量,    shuffle 是否打散数据

    2.加载自定义数据集

    用torchvision.datasets.ImageFolder加载图片数据集

    二、搭建模型

    一个模型可以表示为python的一个类,这个类要继承torch.nn.modules.Module,并且实现forward( )方法

     1 class Lenet5(nn.Module):
     2     """
     3     for CIFAR10
     4     """
     5     def __init__(self):
     6         super(Lenet5, self).__init__()
     7 
     8         # 两层卷积
     9         self.conv_unit = nn.Sequential(
    10             
    11             # 3表示input,可以理解为图片的通道数量,即我的卷积核一次要到几个tensor去作卷积
    12             # 6表示有多少个卷积核
    13             # stride表示卷积核移动步长,padding表示边缘扩充
    14             nn.Conv2d(3, 6, kernel_size=5, stride=1, padding=0),    # 卷积
    15             nn.AvgPool2d(kernel_size=2, stride=2, padding=0),      # 池化
    16 
    17             nn.Conv2d(6, 16, kernel_size=5, stride=1, padding=0),
    18             nn.AvgPool2d(kernel_size=2, stride=2, padding=0)
    19         )
    20 
    21         # 3层全连接层
    22         self.fc_unit = nn.Sequential(
    23             nn.Linear(16*5*5, 120),
    24             nn.ReLU(),
    25             nn.Linear(120, 84),
    26             nn.ReLU(),
    27             nn.Linear(84, 10)
    28         )
    31 
    32 
    33     def forward(self, x):                # 数据从此进来,经过定义好的各层网络,最终输出
    34         batchsz = x.size(0)
    35         x = self.conv_unit(x)
    36         x = x.view(batchsz, 16*5*5)          # 经过卷积层后,对数据维度作处理,以适应全连接层
    37         logits = self.fc_unit(x)
    38         return logits

    三、训练

    训练过程可以认为是对参数优化的过程,通过输入数据,得到输出,计算损失(误差),再经过误差反向传播得到梯度信息,以更新参数。

     1     # 实例模型、配置损失函数、优化器
     2     device = torch.device('cuda')                       # 转为GPU上执行
     3     model = Lenet5().to(device)                         # 实例化模型
     4     criteon = nn.CrossEntropyLoss().to(device)          # 损失函数
     5     optimizer = optim.Adam(model.parameters(), lr=1e-3) # 优化器
     6     print(model)
     7 
     8     # 训练
     9     for epoch in range(1000):                   # 迭代1000次
    10         model.train()                           # 模型切换为训练模式
    11         for batchidx, (x, label) in enumerate(cifar_train):
    12             x, label = x.to(device), label.to(device)
    13             logist = model(x)                   # 得到模型的输出
    14             loss = criteon(logist, label)       # 计算损失
    15             optimizer.zero_grad()               # 旧梯度清零
    16             loss.backward()                     # 误差反向传播
    17             optimizer.step()                    # 梯度更新
    18 
    19         print(epoch, loss.item())

    四、测试

    当模型训练完毕后,进行数据测试。

     1      model.eval()                 # 切换为验证模式
     2         with torch.no_grad():            # 不进行梯度更新
     3             total_correct = 0                   # 记录正确的数据量
     4             total_num = 0                       # 记录总数据量
     5             for x, label in cifar_test:
     6                 x, label = x.to(device), label.to(device)
     7                 logist = model(x)               # 获得模型输出
     8                 pred = logist.argmax(dim=1)     # 取值最大的下标,在这里恰好对应图片标签
     9                 
    10                 # eq(pred, label)表示比较预测值和实际标签
    11                 total_correct += torch.eq(pred, label).float().sum().item()
    12                 total_num += x.size(0)
    13             acc = total_correct / total_num     # 计算正确率

    五、其他

    1、保存与加载模型

    即当模型训练好之后,将模型保存,下一次可以直接使用。

    1 torch.save(model.state_dict(), 'best.mdl')      # 保存模型
    2 
    3 model.load_state_dict(torch.load('best.mdl'))   # 加载模型
  • 相关阅读:
    第九周PSP
    c++的继承方式
    matlab的应用
    beta发布的评论
    本周psp
    历年作品点评
    JSON解析数据
    每周工作量及代码统计(第七周)
    词频统计(WEB)版
    评论alpha发布
  • 原文地址:https://www.cnblogs.com/Drajun/p/13689765.html
Copyright © 2020-2023  润新知