爆改YOLOv8| 利用ResNet18、34、50、101替换yolo主干网络

1,本文介绍

ResNet(深度残差网络)通过引入“快捷连接”来解决深层神经网络训练中的梯度消失问题。这些快捷连接允许网络的输入直接跳过中间的层,直接传递到后面的层,从而使得网络能够专注于学习输入与输出之间的残差(即差异),而非直接学习复杂的函数映射。这种设计方式使得网络在需要时可以简单地实现恒等映射,简化了训练过程,缓解了深层网络训练中的困难。因此,ResNet 能够有效地训练非常深的网络结构,并在多个视觉识别任务上取得显著的性能提升。

关于ResNet的详细介绍可以看论文:https://arxiv.org/pdf/1512.03385.pdf

本文将讲解如何将ResNet融合进yolov8

话不多说,上代码!

2, 将ResNet融合进yolov8

2.1 步骤一

首先找到如下的目录'ultralytics/nn',然后在这个目录下创建一个'Addmodules'文件夹,然后在这个目录下创建一个ResNet.py文件,文件名字可以根据你自己的习惯起,然后将ResNet的核心代码复制进去。

from collections import OrderedDict
import torch.nn as nn
import torch.nn.functional as F
 
class ConvNormLayer(nn.Module):
    def __init__(self,
                 ch_in,
                 ch_out,
                 filter_size,
                 stride,
                 groups=1,
                 act=None):
        super(ConvNormLayer, self).__init__()
        self.act = act
        self.conv = nn.Conv2d(
            in_channels=ch_in,
            out_channels=ch_out,
            kernel_size=filter_size,
            stride=stride,
            padding=(filter_size - 1) // 2,
            groups=groups)
 
        self.norm = nn.BatchNorm2d(ch_out)
 
 
    def forward(self, inputs):
 
        out = self.conv(inputs)
        out = self.norm(out)
        if self.act:
            out = getattr(F, self.act)(out)
        return out
 
 
class SELayer(nn.Module):
    def __init__(self, ch, reduction_ratio=16):
        super(SELayer, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.fc = nn.Sequential(
            nn.Linear(ch, ch // reduction_ratio, bias=False),
            nn.ReLU(inplace=True),
            nn.Linear(ch // reduction_ratio, ch, bias=False),
            nn.Sigmoid()
        )
 
    def forward(self, x):
        b, c, _, _ = x.size()
        y = self.avg_pool(x).view(b, c)
        y = self.fc(y).view(b, c, 1, 1)
        return x * y.expand_as(x)
 
 
 
class BasicBlock(nn.Module):
    expansion = 1
    def __init__(self,
                 ch_in,
                 ch_out,
                 stride,
                 shortcut,
                 act='relu',
                 variant='b',
                 att=False):
        super(BasicBlock, self).__init__()
        self.shortcut = shortcut
        if not shortcut:
            if variant == 'd' and stride == 2:
                self.short = nn.Sequential()
                self.short.add_sublayer(
                    'pool',
                    nn.AvgPool2d(
                        kernel_size=2, stride=2, padding=0, ceil_mode=True))
                self.short.add_sublayer(
                    'conv',
                    ConvNormLayer(
                        ch_in=ch_in,
                        ch_out=ch_out,
                        filter_size=1,
   
### 替换 YOLOv5 主干网络ResNet 的实现方法 YOLOv5 是一种高效的目标检测框架,其主干网络负责提取图像特征。为了提高性能或适应特定场景需求,可以将默认的主干网络替换为其他预训练模型,例如 ResNet。 #### 修步骤说明 1. **导入必要的库并加载 ResNet 模型** 使用 `torchvision.models` 加载所需的 ResNet 预训练模型。可以选择不同版本的 ResNet(如 ResNet-18ResNet-34 或 ResNet-50)。以下是加载 ResNet-50 并移除最后全连接层的代码示例[^2]。 ```python import torch from torchvision import models backbone = models.resnet50(pretrained=True) del backbone.fc # 删除最后一层全连接层 ``` 2. **修配置文件 (`.yaml`)** 在 YOLOv5 中,网络架构由 `.yaml` 文件定义。需要编辑该文件以适配新的主干网络结构。假设原配置文件路径为 `models/yolov5s.yaml`,可以在其中指定自定义主干网络的部分。以下是一个简单的 YAML 示例: ```yaml nc: 80 # 类别数 depth_multiple: 0.33 # 深度倍率 width_multiple: 0.50 # 宽度倍率 backbone: - [focus, [3, 64, 3]] # 原始 Focus 层可被删除或保留作为输入处理部分 - [-1, resnet_backbone] # 自定义 ResNet 背骨网络入口 head: - [conv, [256, 3, 1]] - [upsample, [None, 2, 'nearest']] ... ``` 这里新增了一个名为 `resnet_backbone` 的组件来表示 ResNet 结构。 3. **集成 ResNetYOLOv5 架构中** 创建一个新的 Python 文件用于扩展 YOLOv5 的模块类。通过继承现有的基类并将 ResNet 插入到适当位置完成此操作。下面展示如何构建此类逻辑: ```python class CustomBackbone(torch.nn.Module): def __init__(self, model_name='resnet50', pretrained=True): super(CustomBackbone, self).__init__() base_model = getattr(models, model_name)(pretrained=pretrained) # 提取所需层数量 children = list(base_model.children()) self.feature_extractor = torch.nn.Sequential(*children[:-2]) # 移除全局平均池化和分类头 def forward(self, x): return self.feature_extractor(x) # 将新背骨注册至模型工厂函数 from models.common import ModelFactory @ModelFactory.register('resnet_backbone') def create_resnet_backbone(cfg, ch_in, ch_out): return CustomBackbone(model_name='resnet50', pretrained=True) ``` 4. **调整超参数与重新训练** 更主干网络可能影响整体收敛性和效果表现,因此建议微调学习率和其他优化器设置。同时确保数据增强策略适合当前任务特性[^3]。 --- ### 性能考量与注意事项 当采用更深层次或者更大规模的基础网络时,计算资源消耗会显著增加。这可能导致推理时间延长以及内存占用过高问题。所以在实际应用前需权衡速度与准确性之间的关系。 ```python if __name__ == "__main__": device = torch.device("cuda" if torch.cuda.is_available() else "cpu") custom_yolo = Model(cfg="path/to/custom_yaml_file.yaml", ch=3, nc=80).to(device) input_tensor = torch.randn((1, 3, 640, 640)).to(device) output = custom_yolo(input_tensor) print(output.shape) # 输出形状验证 ```
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值