当前位置: 首页 > article >正文

Pytorch 第六回:AlexNet卷积神经网络模型

Pytorch 第六回:AlexNet卷积神经网络模型

本次开启深度学习第六回,基于Pytorch的AlexNet卷积神经网络模型。在上回当中,我们采用深层神经网络,进行10分类;这次我们再拓展一下,采用卷积神经网络进行分类训练,分类的训练集采用CIFAR10。由于训练模型较为复杂,训练数据量较大,这里引入GPU进行数据训练。
本次学习,借助的平台是PyCharm 2024.1.3,python版本3.11 numpy版本是1.26.4,pytorch版本2.0.0+cu118

文章目录

  • Pytorch 第六回:AlexNet卷积神经网络模型
  • 前言
    • 1、 卷积层
    • 2、池化层
    • 3、全连接层
    • 4、AlexNet卷积神经网络
    • 5、CIFAR10数据集
  • 一、数据准备
    • 1、CIFAR10数据集
    • 2、数据加载器
  • 二、模型准备
    • 1、AlexNet模型准备
    • 2、损失函数和优化器定义
    • 3、引入GPU进行训练
  • 二、模型训练
    • 1、迭代训练
    • 2、训练参数保存
    • 3、输出展示
  • 小结

前言

正文开启前,先简述几个概念:

1、 卷积层

卷积层(Convolutional Layer)是卷积神经网络(Convolutional Neural Networks, CNN)的核心部分。卷积层通过卷积计算来获得数据的特征。单层卷积可用来获得图片的边缘、线条等简单特征,但多层卷积迭代,可以获得图片的复杂特征。
卷积层是通过卷积核(filter或kernel)在数据图上以固定步幅(stride)滑动,并将相应数据与卷积核的计算结果填写在新的数据图(feature map)上。
该方式可以减少参数计算量,从而避免过拟合问题。

2、池化层

在神经网络中,池化层(Pooling Layer)采用滑动的方式来完成数据的下采样。常见的池化操作有两种:最大池化(Max Pooling)和平均池化(Average Pooling)。其中,最大池化选择每个窗口内的最大值作为输出值(保留最大特征);平均池化的输出值为窗口内的平均值(平滑数据)。

3、全连接层

全连接层会将前一层的所有神经元与本层神经元进行有权重的关联,从而实现数据特征的整合和分类。

4、AlexNet卷积神经网络

AlexNet卷积神经网络是经典的卷积神经网络。在2012年的 ImageNet 大规模视觉识别竞赛当中,AlexNet卷积神经网络大放异彩,一举夺得当年分类比赛的冠军。对此感兴趣的读者可以查查资料。
注:由于数据库和硬件原因,这里我没有一比一进行复现,只是取了其大致进行演示。

5、CIFAR10数据集

CIFAR-10 数据集由 60000 张 32x32 彩色图像组成,共有10个类别。其中,有 50000 张训练图像和 10000 张测试图像。类别中包括:鹿、狗、青蛙、飞机、汽车、鸟、猫、马、船和卡车。

接下来就是思路分享,先上引用代码:

import torch
from torch import nn
import numpy as np
import time
from torchvision.datasets import CIFAR10

一、数据准备

1、CIFAR10数据集

准备CIFAR10训练数据集 train_set ,并用data_treating函数进行数据变换。若数据不存在,则需要添加下载参数(上回中提到)。

def data_treating(x):
    x = np.array(x, dtype='float32') / 255
    x = (x - 0.5) / 0.5  #
    x = x.transpose((2, 0, 1))  #
    x = torch.from_numpy(x)
    return x
train_set = CIFAR10('./data', train=True, transform=data_treating)

注:
为方便后续的数据训练,这里将图片格式从32323改变为33232。这样可以将数据理解为3个3232的数据,即3232的数据有三个通道。

2、数据加载器

使用DataLoader处理train_set数据:每个批次的样本设定为64,并做数据打乱处理。

train_data = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)

二、模型准备

1、AlexNet模型准备

在这里我是基于 nn.Sequential写了一个九层的神经网络:
其中前6层是特征提取:卷积层1->池化层1->卷积层2->池化层3->卷积层3->池化层3
(经过6层数据整合,数据从33232,转化为102411)
后三层是全连接层:用于特征的提取和分类

class AlexNet(nn.Module):
    def __init__(self):
        super().__init__()
        # 第一层3*3的卷积,输入的 channels是3,输出的channels是64,步长是1,没有padding
        self.conv1 = nn.Sequential(nn.Conv2d(3, 64,3,1),
                                   nn.ReLU(True))
        # 第二层4*4的池化,步长是2,没有填充
        self.max_pool1 = nn.MaxPool2d(4, 2)
        # 第三层3*3的卷积,输入的 channels是64,输出的channels是64,步长是1,没有填充
        self.conv2 = nn.Sequential(nn.Conv2d(64,256,3,1),
                                   nn.ReLU(True))
        # 第四层是4*4的池化,步长是2,没有填充
        self.max_pool2 = nn.MaxPool2d(4, 2)
        # 第五层3*3的卷积,输入的 channels是64,输出的channels是64,步长是1,没有填充
        self.conv3 = nn.Sequential(nn.Conv2d(256,1024,3,1),
                                   nn.ReLU(True))
        # 第六层是3*3的池化,步长是2,没有填充
        self.max_pool3 = nn.MaxPool2d(3, 2)

        # 第七层是全连接层,输入是1024,输出是256
        self.fc1 = nn.Sequential(nn.Linear(1024,256),
                                 nn.ReLU(True),
                                 nn.Dropout())

        # 第八层是全连接层,输入是256,输出是128
        self.fc2 = nn.Sequential(nn.Linear(256,128),
                                 nn.ReLU(True))
        # 第九层是全连接层,输入是128,输出是10
        self.fc3 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = self.max_pool1(x)
        x = self.conv2(x)
        x = self.max_pool2(x)
        x = self.conv3(x)
        x = self.max_pool3(x)

        # 将数据转成一维
        x = x.view(x.shape[0], -1)
        x = self.fc1(x)
        x = self.fc2(x)
        x = self.fc3(x)
        return x

注:
数据经过卷积和池化时,数据特征会整合(我理解为数据缩小,通道数增加),当数据处理量(特征图 Featuere Map)为通道数11时,是无法再继续数据卷积或池化的。由于篇幅考虑,这里不展示特征图的变换过程。

2、损失函数和优化器定义

定义了交叉熵损失函数;采用SGD优化器来进行梯度下降的计算,学习率设定为0.1。

Loss_f = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(classify_AlexNet.parameters(), lr=1e-1)

3、引入GPU进行训练

引入GPU进行训练有三步:
第一步:模型需要转换成GPU类型(模型准备时)

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
classify_AlexNet = AlexNet().to(device)

第二步:训练数据需要转换成GPU类型(模型训练时)

x_data = x_data.to(device)
y_data = y_data.to(device)

第三步:损失数据需要转换成GPU类型(模型训练时)

loss_train = Loss_f(y_predict, y_data).to(device)

二、模型训练

1、迭代训练

这里先进行20次迭代训练:

time1 = time.time()
for k in range(20):
    train_loss = 0
    train_acc = 0
    classify_AlexNet.train()  # 将模型设为测试模式
    for x_data, y_data in train_data:
        x_data = x_data.to(device)
        y_data = y_data.to(device)
        # 前向传播
        y_predict = classify_AlexNet(x_data)
        loss_train = Loss_f(y_predict, y_data).to(device)
        # 反向传播
        optimizer.zero_grad()  # 梯度清零
        loss_train.backward()  # 计算梯度
        optimizer.step()  # 使用优化器更新参数
        # 记录误差
        train_loss += loss_train
        # 计算分类的准确率
        _, pred = y_predict.max(1)
        train_correct = (pred == y_data).sum().item() / x_data.shape[0]
        train_acc += train_correct

    time_consume = time.time() - time1
    print('epoch:{},TrainLoss:{:.6f},TrainAcc:{:.6f},consume time:{:.3f}s'.format(k,
                                                                                  train_loss / len(train_data),
                                                                                  train_acc / len(train_data),
                                                                                  time_consume))

2、训练参数保存

由于训练时间较长,因此需要及时保存模型训练参数

torch.save(classify_AlexNet.state_dict(), 'classify_AlexNet_params.pth')

3、输出展示

epoch:0,TrainLoss:1.985443,TrainAcc:0.246284,consume time:44.312s
epoch:4,TrainLoss:0.895071,TrainAcc:0.688619,consume time:222.402s
epoch:8,TrainLoss:0.506490,TrainAcc:0.824009,consume time:398.314s
epoch:12,TrainLoss:0.269190,TrainAcc:0.908008,consume time:577.844s
epoch:16,TrainLoss:0.163928,TrainAcc:0.944953,consume time:757.611s
epoch:19,TrainLoss:0.104389,TrainAcc:0.964774,consume time:894.066s

从训练结果看,通过20次迭代训练,AlexNet网络模型对于训练数据可以得到一个比好的训练精度。
注:
对于模型的测试,可以参考第五回下半部分进行完成。由于代码改变量较小,这里就不再进行单独分享。

小结

1、数据准备:准备Pytorch自带的CIFAR10数据集;
2、模型准备:准备AlexNet网络模型,损失函数和优化器。需要注意引入GPU参入训练;
3、数据训练:20次迭代训练AlexNet网络模型。


http://www.kler.cn/a/569694.html

相关文章:

  • 使用sam-vit-base 模型在caltech256 数据集上实现图片召回
  • FPGA开发,使用Deepseek V3还是R1(5):temperature设置
  • MySQL中的行级锁
  • Linux内核配置与构建原理
  • P8654 [蓝桥杯 2017 国 C] 合根植物---并查集!!!
  • 力扣1462. 课程表 IV
  • SpringSecurity的配置
  • AIGC(生成式AI)试用 26 -- 跟着清华教程学习 - DeepSeek与AI幻觉
  • 数字人技术再超越,TANGO 可生成与音频匹配的全身手势视频
  • Ubuntu20.04下各类常用软件及库安装汇总(联想Y9000P24款)
  • AI产品经理W1D4埋点设计数据采集
  • java关键字-instanceof
  • 具身智能(Embodied AI)的物理交互基准测试:构建真实世界的智能体评估体系
  • 奇妙跨界:将前端概念融入整数操作
  • Python 爬虫 – BeautifulSoup
  • Linux常见基本指令(二)
  • 批量提取 Word 文档中的页面
  • php序列化与反序列化
  • 迷你世界脚本世界接口:World
  • 矩阵 trick 系列 题解