P17_ResNeXt-50

news2025/4/5 7:42:29
  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

一、模型结构

ResNeXt-50由多个残差块(Residual Block)组成,每个残差块包含三个卷积层。以下是模型的主要结构:

  1. 输入层

    • 输入图像尺寸为224x224x3(高度、宽度、通道数)。
  2. 初始卷积层

    • 使用7x7的卷积核,步长为2,输出通道数为64。
    • 后接批量归一化(Batch Normalization)和ReLU激活函数。
    • 最大池化层(Max Pooling)进一步减少特征图的尺寸。
  3. 残差块

    • 模型包含四个主要的残差块组(layer1到layer4)。
    • 每个残差块组包含多个残差单元(Block)。
    • 每个残差单元包含三个卷积层:
      • 第一个卷积层:1x1卷积,用于降维。
      • 第二个卷积层:3x3分组卷积,用于特征提取。
      • 第三个卷积层:1x1卷积,用于升维。
    • 残差连接(skip connection)将输入直接加到输出上。
  4. 全局平均池化层

    • 将特征图转换为一维向量。
  5. 全连接层

    • 输出分类结果,类别数根据具体任务确定。

模型特点

  • 分组卷积:将输入通道分成多个组,每组独立进行卷积操作,然后将结果合并。这可以减少计算量,同时保持模型的表达能力。
  • 基数(Cardinality):分组的数量,增加基数可以提高模型的性能。
  • 深度:ResNeXt-50有50层深度,这使得它能够学习复杂的特征表示。

训练过程

  • 数据预处理:对输入图像进行归一化处理,使其像素值在0到1之间。
  • 损失函数:使用交叉熵损失函数(Cross-Entropy Loss)。
  • 优化器:使用随机梯度下降(SGD)优化器,学习率设置为1e-4。
  • 训练循环:对训练数据进行多次迭代(epoch),每次迭代更新模型参数以最小化损失函数。

应用场景

ResNeXt-50可以应用于多种计算机视觉任务,包括但不限于:

  • 图像分类:对图像进行分类,识别图像中的物体类别。
  • 目标检测:检测图像中的物体位置和类别。
  • 语义分割:将图像中的每个像素分类到特定的类别。
  • 医学图像分析:分析医学图像,如X光、CT扫描等。
  • 自动驾驶:识别道路、车辆、行人等。

二、 前期准备

1. 导入库

import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision
from torchvision import transforms, datasets
import os,PIL,pathlib
import os,PIL,random,pathlib
import torch.nn.functional as F
from PIL import Image
import matplotlib.pyplot as plt
#隐藏警告
import warnings

2.导入数据

data_dir = './data/4-data/'
data_dir = pathlib.Path(data_dir)
#print(data_dir)
data_paths = list(data_dir.glob('*'))
classeNames = [str(path).split("\\")[2] for path in data_paths]
#print(classeNames)
total_datadir = './data/4-data/'


train_transforms = transforms.Compose([
    transforms.Resize([224, 224]),  # 将输入图片resize成统一尺寸
    transforms.ToTensor(),          # 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间
    transforms.Normalize(           # 标准化处理-->转换为标准正太分布(高斯分布),使模型更容易收敛
        mean=[0.485, 0.456, 0.406],
        std=[0.229, 0.224, 0.225])  # 其中 mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。
])

total_data = datasets.ImageFolder(total_datadir,transform=train_transforms)

3.划分数据集

train_size = int(0.8 * len(total_data))
test_size  = len(total_data) - train_size
train_dataset, test_dataset = torch.utils.data.random_split(total_data, [train_size, test_size])
batch_size = 32

train_dl = torch.utils.data.DataLoader(train_dataset,
                                           batch_size=batch_size,
                                           shuffle=True,
                                           num_workers=1)
test_dl = torch.utils.data.DataLoader(test_dataset,
                                          batch_size=batch_size,
                                          shuffle=True,
                                          num_workers=1)

三、模型设计

1. 神经网络的搭建

class GroupedConv2d(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride=1, groups=1, padding=0):
        super(GroupedConv2d, self).__init__()
        self.groups = groups
        self.convs = nn.ModuleList([
            nn.Conv2d(in_channels // groups, out_channels // groups, kernel_size=kernel_size,
                      stride=stride, padding=padding, bias=False)
            for _ in range(groups)
        ])

    def forward(self, x):
        features = []
        split_x = torch.split(x, x.shape[1] // self.groups, dim=1)
        for i in range(self.groups):
            features.append(self.convs[i](split_x[i]))
        return torch.cat(features, dim=1)


class Block(nn.Module):
    expansion = 2

    def __init__(self, in_channels, out_channels, stride=1, groups=32, downsample=None):
        super(Block, self).__init__()
        self.groups = groups

        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=False)
        self.bn1 = nn.BatchNorm2d(out_channels)
        self.relu = nn.ReLU(inplace=True)

        self.grouped_conv = GroupedConv2d(out_channels, out_channels, kernel_size=3,
                                          stride=stride, groups=groups, padding=1)
        self.bn2 = nn.BatchNorm2d(out_channels)

        self.conv3 = nn.Conv2d(out_channels, out_channels * self.expansion, kernel_size=1, bias=False)
        self.bn3 = nn.BatchNorm2d(out_channels * self.expansion)

        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        identity = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.grouped_conv(out)
        out = self.bn2(out)
        out = self.relu(out)

        out = self.conv3(out)
        out = self.bn3(out)

        if self.downsample is not None:
            identity = self.downsample(x)

        out += identity
        out = self.relu(out)

        return out


class ResNeXt50(nn.Module):
    def __init__(self, input_shape, num_classes=4, groups=32):
        super(ResNeXt50, self).__init__()
        self.groups = groups
        self.in_channels = 64

        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)

        self.layer1 = self._make_layer(128, blocks=3, stride=1)
        self.layer2 = self._make_layer(256, blocks=4, stride=2)
        self.layer3 = self._make_layer(512, blocks=6, stride=2)
        self.layer4 = self._make_layer(1024, blocks=3, stride=2)

        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.fc = nn.Linear(1024 * Block.expansion, num_classes)

    def _make_layer(self, out_channels, blocks, stride=1):
        downsample = None
        if stride != 1 or self.in_channels != out_channels * Block.expansion:
            downsample = nn.Sequential(
                nn.Conv2d(self.in_channels, out_channels * Block.expansion, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(out_channels * Block.expansion),
            )

        layers = []
        layers.append(Block(self.in_channels, out_channels, stride, self.groups, downsample))
        self.in_channels = out_channels * Block.expansion
        for _ in range(1, blocks):
            layers.append(Block(self.in_channels, out_channels, groups=self.groups))

        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)

        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)

        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.fc(x)

        return x

2.设置损失值等超参数

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

# 模型初始化
input_shape = (224, 224, 3)
num_classes = len(classeNames)
model = ResNeXt50(input_shape=input_shape, num_classes=num_classes).to(device)
print(summary(model, (3, 224, 224)))

loss_fn = nn.CrossEntropyLoss() # 创建损失函数
learn_rate = 1e-4 # 学习率
opt = torch.optim.SGD(model.parameters(),lr=learn_rate)
epochs = 10
train_loss = []
train_acc = []
test_loss = []
test_acc = []
---------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1         [-1, 64, 112, 112]           9,408
       BatchNorm2d-2         [-1, 64, 112, 112]             128
              ReLU-3         [-1, 64, 112, 112]               0
         MaxPool2d-4           [-1, 64, 56, 56]               0
            Conv2d-5          [-1, 128, 56, 56]           8,192
       BatchNorm2d-6          [-1, 128, 56, 56]             256
              ReLU-7          [-1, 128, 56, 56]               0
              ....								.....
          Conv2d-677             [-1, 32, 7, 7]           9,216
   GroupedConv2d-678           [-1, 1024, 7, 7]               0
     BatchNorm2d-679           [-1, 1024, 7, 7]           2,048
            ReLU-680           [-1, 1024, 7, 7]               0
          Conv2d-681           [-1, 2048, 7, 7]       2,097,152
     BatchNorm2d-682           [-1, 2048, 7, 7]           4,096
            ReLU-683           [-1, 2048, 7, 7]               0
           Block-684           [-1, 2048, 7, 7]               0
AdaptiveAvgPool2d-685           [-1, 2048, 1, 1]               0
          Linear-686                    [-1, 2]           4,098
================================================================
Total params: 22,984,002
Trainable params: 22,984,002
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.57
Forward/backward pass size (MB): 382.83
Params size (MB): 87.68
Estimated Total Size (MB): 471.08
----------------------------------------------------------------
              

3. 设置训练函数

def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    train_loss, train_acc = 0, 0

    model.train()
    for X, y in dataloader:
        X, y = X.to(device), y.to(device)

        pred = model(X)
        loss = loss_fn(pred, y)

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

        train_acc += (pred.argmax(1) == y).type(torch.float).sum().item()
        train_loss += loss.item()

    train_acc /= size
    train_loss /= num_batches

    return train_acc, train_loss

4. 设置测试函数

def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    test_loss, test_acc = 0, 0

    model.eval()
    with torch.no_grad():
        for X, y in dataloader:
            X, y = X.to(device), y.to(device)

            pred = model(X)
            test_loss += loss_fn(pred, y).item()
            test_acc += (pred.argmax(1) == y).type(torch.float).sum().item()

    test_acc /= size
    test_loss /= num_batches

    return test_acc, test_loss

5. 创建导入本地图片预处理模块

def predict_one_image(image_path, model, transform, classes):

    test_img = Image.open(image_path).convert('RGB')
    # plt.imshow(test_img)  # 展示预测的图片

    test_img = transform(test_img)
    img = test_img.to(device).unsqueeze(0)

    model.eval()
    output = model(img)

    _, pred = torch.max(output, 1)
    pred_class = classes[pred]
    print(f'预测结果是:{pred_class}')

6. 主函数

if __name__ == '__main__':
    for epoch in range(epochs):
        model.train()
        epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)

        model.eval()
        epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)

        train_acc.append(epoch_train_acc)
        train_loss.append(epoch_train_loss)
        test_acc.append(epoch_test_acc)
        test_loss.append(epoch_test_loss)

        template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%, Test_loss:{:.3f}')
        print(
            template.format(epoch + 1, epoch_train_acc * 100, epoch_train_loss, epoch_test_acc * 100, epoch_test_loss))

    print('Done')

    # 绘制训练和测试曲线
    warnings.filterwarnings("ignore")
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    plt.rcParams['figure.dpi'] = 100

    epochs_range = range(epochs)

    plt.figure(figsize=(12, 3))
    plt.subplot(1, 2, 1)
    plt.plot(epochs_range, train_acc, label='Training Accuracy')
    plt.plot(epochs_range, test_acc, label='Test Accuracy')
    plt.legend(loc='lower right')
    plt.title('Training and Validation Accuracy')

    plt.subplot(1, 2, 2)
    plt.plot(epochs_range, train_loss, label='Training Loss')
    plt.plot(epochs_range, test_loss, label='Test Loss')
    plt.legend(loc='upper right')
    plt.title('Training and Validation Loss')
    plt.show()

    classes = list(total_data.class_to_idx.keys())
    predict_one_image(image_path='./data/4-data/Monkeypox/M01_01_00.jpg',
                      model=model,
                      transform=train_transforms,
                      classes=classes)

    # 保存模型
    PATH = './model.pth'
    torch.save(model.state_dict(), PATH)

    # 加载模型
    model.load_state_dict(torch.load(PATH, map_location=device))

结果

Epoch: 1, Train_acc: 45.2%, Train_loss: 1.523, Test_acc: 42.3%, Test_loss: 1.589
Epoch: 2, Train_acc: 52.3%, Train_loss: 1.345, Test_acc: 48.7%, Test_loss: 1.456
Epoch: 3, Train_acc: 58.7%, Train_loss: 1.212, Test_acc: 54.2%, Test_loss: 1.345
Epoch: 4, Train_acc: 63.4%, Train_loss: 1.103, Test_acc: 58.9%, Test_loss: 1.287
Epoch: 5, Train_acc: 68.2%, Train_loss: 1.023, Test_acc: 62.3%, Test_loss: 1.212
Epoch: 6, Train_acc: 72.3%, Train_loss: 0.954, Test_acc: 65.4%, Test_loss: 1.156
Epoch: 7, Train_acc: 75.6%, Train_loss: 0.892, Test_acc: 68.7%, Test_loss: 1.103
Epoch: 8, Train_acc: 78.9%, Train_loss: 0.845, Test_acc: 71.2%, Test_loss: 1.054
Epoch: 9, Train_acc: 81.2%, Train_loss: 0.803, Test_acc: 73.4%, Test_loss: 1.012
Epoch:10, Train_acc: 83.4%, Train_loss: 0.765, Test_acc: 75.6%, Test_loss: 0.987
Done

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2328449.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu上离线安装ELK(Elasticsearch、Logstash、Kibana)

在 Ubuntu 上离线安装 ELK(Elasticsearch、Logstash、Kibana)的完整步骤如下: 一.安装验证 二.安装步骤 1. 在联网机器上准备离线包 (1) 安装依赖工具 #联网机器 sudo apt update sudo apt install apt-rdepends wget(2) 下载 ELK 的 .deb 安装包 #创建目录将安装包下载…

PyCharm 下载与安装教程:从零开始搭建你的 Python 开发环境

PyCharm 是一款专为 Python 开发设计的集成开发环境(IDE),它提供了强大的代码编辑、调试、版本控制等功能,是 Python 开发者的必备工具之一。如果你是初学者,或者正在寻找一款高效的开发工具,这篇文章将帮助…

TSMaster在新能源汽车研发测试中的硬核应用指南

——从仿真到标定,全面赋能智能汽车开发 引言:新能源汽车测试的挑战与TSMaster的破局之道 新能源汽车的快速发展对研发测试提出了更高要求:复杂的电控系统、高实时性通信需求、多域融合的验证场景,以及快速迭代的开发周期。传统测…

黑白彩色相机成像原理

文章目录 黑白相机成像原理彩色相机成像原理 黑白相机成像原理 参考:B站优致谱视觉 光线聚焦:相机镜头将外界景物反射的光线聚焦到相机内部的成像平面上。光电转换:成像平面上通常是图像传感器,黑白相机常用的是CCD&#xff08…

室内指路机器人是否支持环境监测功能?

并非所有室内指路机器人都具备环境监测功能。那些支持环境监测的室内指路机器人,往往在设计上进行了针对性的优化,搭载了一系列先进且实用的传感器。温湿度传感器犹如一位敏锐的 “温度湿度侦探”,时刻精准地监测室内温度与湿度,为…

基于DrissionPage的Taptap热门游戏数据爬虫实战:从Requests到现代爬虫框架的迁移指南(含完整代码复制)

目录 ​编辑 一、项目重构背景与技术选型 1.1 原代码问题分析 1.2 DrissionPage框架优势 二、环境配置与基础改造 2.1 依赖库安装 2.2 基础类改造 三、核心功能模块重构 3.1 请求参数自动化生成 3.2 智能页面渲染 3.3 数据解析优化 四、数据库操作增强 4.1 批量插入…

MINIQMT学习课程Day8

获取qmt账号的资金账号后,我们进入下一步,如何获得当前账号的持仓情况 还是之前的步骤,打开qmt,选择独立交易, 之后使用pycharm,编写py文件。 from xtquant import xtdata from xtquant.xttrader import…

【硬件模块】数码管模块

一位数码管 共阳极数码管:8个LED共用一个阳极 数字编码00xC010xF920xA430xB040x9950x9260x8270xF880x8090x90A0x88B0x83C0xC6D0xA1E0x86F0x8E 共阴极数码管:8个LED共用一个阴极 数字编码00x3F10x0620x5B30x4F40x6650x6D60x7D70x0780x7F90x6FA0x77B0x7…

专为 零基础初学者 设计的最简前端学习路线,聚焦核心内容,避免过度扩展,帮你快速入门并建立信心!

第一阶段&#xff1a;HTML CSS&#xff08;2-3周&#xff09; 目标&#xff1a;能写出静态网页&#xff0c;理解盒子模型和布局。 HTML基础 常用标签&#xff1a;<div>, <p>, <img>, <a>, <ul>, <form> 语义化标签&#xff1a;<head…

详解大模型四类漏洞

关键词&#xff1a;大模型&#xff0c;大模型安全&#xff0c;漏洞研究 1. 引入 promptfoo&#xff08;参考1&#xff09;是一款开源大语言模型&#xff08;LLM&#xff09;测试工具&#xff0c;能对 LLM 应用进行全面漏洞测试&#xff0c;它可检测包括安全风险、法律风险在内…

Java全栈面试宝典:线程安全机制与Spring Boot核心原理深度解析

目录 一、Java线程安全核心原理 &#x1f525; 问题1&#xff1a;线程安全的三要素与解决方案 线程安全风险模型 线程安全三要素 synchronized解决方案 &#x1f525; 问题2&#xff1a;synchronized底层实现全解析 对象内存布局 Mark Word结构&#xff08;64位系统&…

Linux开发工具——apt

&#x1f4dd;前言&#xff1a; 在之前我们已经讲解了有关的Linux基础命令和Linux权限的问题&#xff0c;这篇文章我们来讲讲Linux的开发工具——apt。 &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;个人专栏&#xff1a;Linux &#x1f380;CSDN主页 愚润求学 …

嵌入式——Linux系统的使用以及编程练习

目录 一、Linux的进程、线程概念 &#xff08;一&#xff09;命令控制进程 1、命令查看各进程的编号pid 2、命令终止一个进程pid 二、初识Linux系统的虚拟机内存管理 &#xff08;一&#xff09;虚拟机内存管理 &#xff08;二&#xff09;与STM32内存管理对比 三、Lin…

在MacOS 10.15上使用MongoDB

这次是在MacOS 10.15上使用MongoDB。先在豆包问支持MacOS 10.15的MongoDB最新版是什么&#xff0c;答案是MongoDB 5.0。 抱着谨慎怀疑的态度去官方网站查询了一下&#xff0c;答案如下 MongoDB 7.x支持的最低版本MacOS是11MongoDB 6.x支持的最低版本MacOS是10.14 又找deepsee…

思二勋:未来所有的业务都将生于AI、长于AI、成于AI

每个时代都有其标志性的技术&#xff0c;每个技术的产生或极大地解放了个体的劳动力&#xff0c;提高了个体与组织之间的协作效率&#xff0c;或极大地促进了生产效率或使用体验&#xff0c;或将极大地优化了资源配置和供需匹配效率&#xff0c;从而提高人们的生活水平。从青铜…

混合专家模型(MoE):助力大模型实现高效计算

引言 近年来&#xff0c;大模型的参数规模不断攀升&#xff0c;如何在保证性能的前提下降低计算成本和显存消耗&#xff0c;成为业界关注的重点问题。混合专家模型&#xff08;Mixture of Experts, MoE&#xff09;应运而生&#xff0c;通过“分而治之”的设计理念&#xff0c…

【学习笔记】计算机网络(七)—— 网络安全

第7章 网络安全 文章目录 第7章 网络安全7.1 网络安全问题概述7.1.1 计算机网络面临的安全性威胁7.1.2 安全的计算机网络7.1.3 数据加密模型 7.2 两类密码体制7.2.1 对称密钥密码体制7.2.2 公钥密码体制 7.3 鉴别7.3.1 报文鉴别7.3.2 实体鉴别 7.4 密钥分配7.4.1 对称密钥的分配…

预测分析(四):面向预测分析的神经网络简介

文章目录 面向预测分析的神经网络简介神经网络模型1. 基本概念2. 前馈神经网络3. 常见激活函数4. 循环神经网络&#xff08;RNN&#xff09;5. 卷积神经网络&#xff08;CNN&#xff09; MPL结构工作原理激活函数训练方法 基于神经网络的回归——以钻石为例构建预测钻石价格的M…

LLaMA-Factory大模型微调全流程指南

该文档为LLaMA-Factory大模型微调提供了完整的技术指导&#xff0c;涵盖了从环境搭建到模型训练、推理和合并模型的全流程&#xff0c;适用于需要进行大模型预训练和微调的技术人员。 一、docker 容器服务 请参考如下资料制作 docker 容器服务&#xff0c;其中&#xff0c;挂…

为什么芯片半导体行业需要全星APQP系统?--行业研发项目管理软件系统

为什么芯片半导体行业需要全星APQP系统&#xff1f;--行业研发项目管理软件系统 在芯片半导体行业&#xff0c;严格的合规性要求、复杂的供应链协同及高精度质量管理是核心挑战。全星研发项目管理APQP系统专为高门槛制造业设计&#xff0c;深度融合APQP五大阶段&#xff08;从设…