【改进YOLOv8】融合Gold-YOLO的车辆未礼让行人检测系统

1.研究背景与意义

项目参考AAAI Association for the Advancement of Artificial Intelligence

研究背景与意义

随着交通工具的普及和道路交通量的增加,交通安全问题日益凸显。尤其是车辆未礼让行人的情况频繁发生,给行人的生命安全带来了严重威胁。因此,开发一种高效准确的车辆未礼让行人检测系统具有重要的现实意义。

近年来,深度学习技术在计算机视觉领域取得了巨大的突破,特别是目标检测方面。目标检测是计算机视觉中的一个重要任务,其目的是在图像或视频中准确地定位和识别出感兴趣的目标。YOLO(You Only Look Once)是一种流行的目标检测算法,其具有快速、准确和端到端的特点,被广泛应用于各种实际场景中。

然而,传统的YOLO算法在车辆未礼让行人检测方面存在一些局限性。首先,YOLO算法在目标尺度变化和遮挡情况下的检测效果较差。其次,YOLO算法对于小目标的检测效果不佳,而行人往往属于小目标。此外,YOLO算法对于目标的边界框回归不够精确,容易出现误检和漏检的情况。

为了解决上述问题,本研究提出了一种改进的YOLOv8算法,并融合了Gold-YOLO的思想,用于车辆未礼让行人检测。改进的YOLOv8算法在YOLOv3的基础上进行了优化和改进,以提高检测的准确性和鲁棒性。同时,融合了Gold-YOLO的思想,引入了更加有效的目标检测策略,进一步提升了检测性能。

本研究的意义主要体现在以下几个方面:

  1. 提高交通安全:车辆未礼让行人是导致交通事故的主要原因之一。通过开发一种高效准确的车辆未礼让行人检测系统,可以及时发现并预警车辆未礼让行人的情况,有效降低交通事故的发生率,提高交通安全水平。

  2. 优化交通流量:车辆未礼让行人不仅会导致交通事故,还会造成交通拥堵和交通流量的不畅。通过车辆未礼让行人检测系统的应用,可以及时发现并处理车辆未礼让行人的情况,减少交通拥堵,优化交通流量,提高道路通行效率。

  3. 推动智能交通发展:智能交通是未来交通发展的重要方向,而车辆未礼让行人检测系统是智能交通系统的重要组成部分。通过开发一种高效准确的车辆未礼让行人检测系统,可以为智能交通系统的建设和应用提供技术支持,推动智能交通的发展。

  4. 拓展目标检测技术:本研究提出的改进的YOLOv8算法和融合Gold-YOLO的思想,对于目标检测技术的发展具有一定的参考价值。通过优化和改进传统的YOLO算法,提高了检测的准确性和鲁棒性,为目标检测技术的研究和应用提供了新的思路和方法。

综上所述,本研究旨在开发一种高效准确的车辆未礼让行人检测系统,以提高交通安全、优化交通流量、推动智能交通发展,并为目标检测技术的研究和应用提供新的思路和方法。该研究对于改善交通安全状况、提高交通效率和推动智能交通发展具有重要的现实意义和深远的影响。

2.图片演示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.视频演示

【改进YOLOv8】融合Gold-YOLO的车辆未礼让行人检测系统_哔哩哔哩_bilibili

4.YOLOv8 概述

具体到 YOLOv8 算法,其核心特性和改动可以归结为如下:

提供了一个全新的 SOTA 模型,包括 P5 640 和 P6 1280 分辨率 的目标检测网络和基于 YOLACT 的实例分割模型。和 YOLOv5 一样,基于缩放系数也提供了 N/S/M/L/X 尺度的不同大小模型,用于满足不同场景需求
骨干网络和 Neck 部分可能参考了 YOLOv7 ELAN 设计思想,将 YOLOv5 的 C3 结构换成了梯度流更丰富的 C2f 结构,并对不同尺度模型调整了不同的通道数,属于对模型结构精心微调,不再是无脑一套参数应用所有模型,大幅提升了模型性能。不过这个 C2f 模块中存在 Split 等操作对特定硬件部署没有之前那么友好了
Head 部分相比 YOLOv5 改动较大,换成了目前主流的解耦头结构,将分类和检测头分离,同时也从 Anchor-Based 换成了 Anchor-Free
Loss 计算方面采用了 TaskAlignedAssigner 正样本分配策略,并引入了 Distribution Focal Loss
训练的数据增强部分引入了 YOLOX 中的最后 10 epoch 关闭 Mosiac 增强的操作,可以有效 地 提升精度
从上面可以看出,YOLOv8 主要参考了最近提出的诸如 YOLOX、YOLOv6、YOLOv7 和 PPYOLOE 等算法的相关设计,本身的创新点不多,偏向工程实践,主推的还是 ultralytics 这个框架本身 。

下面将按照模型结构设计、Loss 计算、训练数据增强、训练策略和模型推理过程共 5 个部分详细介绍 YOLOv8 目标检测的各种改进,实例分割部分暂时不进行描述。

模型结构设计

在这里插入图片描述

以上为基于 YOLOv8 官方代码所绘制的模型结构图。如果你喜欢这种模型结构图风格,可以查看 MMYOLO 里面对应算法 README 中的模型结构图,目前已经支持了 YOLOv5、YOLOv6、YOLOX、RTMDet 和 YOLOv8。MMYOLO 中重构的 YOLOv8 模型对应结构图如下所示:

详细地址为: https://github.com/open-mmlab/mmyolo/blob/dev/configs/yolov8/README.md

在暂时不考虑 Head 情况下,对比 YOLOv5 和 YOLOv8 的 yaml 配置文件可以发现改动较小。

在这里插入图片描述

左侧为 YOLOv5-s,右侧为 YOLOv8-s

骨干网络和 Neck 的具体变化为:

第一个卷积层的 kernel 从 6x6 变成了 3x3
所有的 C3 模块换成 C2f,结构如下所示,可以发现多了更多的跳层连接和额外的 Split 操作

在这里插入图片描述

去掉了 Neck 模块中的 2 个卷积连接层
Backbone 中 C2f 的block 数从 3-6-9-3 改成了 3-6-6-3
查看 N/S/M/L/X 等不同大小模型,可以发现 N/S 和 L/X 两组模型只是改了缩放系数,但是 S/M/L 等骨干网络的通道数设置不一样,没有遵循同一套缩放系数。如此设计的原因应该是同一套缩放系数下的通道设置不是最优设计,YOLOv7 网络设计时也没有遵循一套缩放系数作用于所有模型
Head 部分变化最大,从原先的耦合头变成了解耦头,并且从 YOLOv5 的 Anchor-Based 变成了 Anchor-Free。其结构如下所示:
在这里插入图片描述

5.核心代码讲解

5.2 predict.py

封装为类后的代码如下:

from ultralytics.engine.predictor import BasePredictor
from ultralytics.engine.results import Results
from ultralytics.utils import ops

class DetectionPredictor(BasePredictor):
    def postprocess(self, preds, img, orig_imgs):
        preds = ops.non_max_suppression(preds,
                                        self.args.conf,
                                        self.args.iou,
                                        agnostic=self.args.agnostic_nms,
                                        max_det=self.args.max_det,
                                        classes=self.args.classes)

        if not isinstance(orig_imgs, list):
            orig_imgs = ops.convert_torch2numpy_batch(orig_imgs)

        results = []
        for i, pred in enumerate(preds):
            orig_img = orig_imgs[i]
            pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], orig_img.shape)
            img_path = self.batch[0][i]
            results.append(Results(orig_img, path=img_path, names=self.model.names, boxes=pred))
        return results

这个程序文件是一个名为predict.py的文件,它是一个基于检测模型进行预测的类DetectionPredictor的定义。该类继承自BasePredictor类,并包含一个postprocess方法用于后处理预测结果。该文件使用了Ultralytics YOLO库,采用AGPL-3.0许可证。

在postprocess方法中,首先对预测结果进行非最大值抑制处理,根据一定的置信度和IOU阈值来筛选出最终的预测结果。然后,将预测结果的边界框坐标进行缩放,以适应原始图像的尺寸。最后,将处理后的预测结果封装成Results对象,并返回一个Results对象列表。

该文件还包含一个示例用法,通过创建DetectionPredictor对象,并传入相应的参数,可以进行预测操作。

总之,这个程序文件定义了一个用于基于检测模型进行预测的类DetectionPredictor,并提供了相应的预测方法和后处理方法。

5.3 train.py
# Ultralytics YOLO 🚀, AGPL-3.0 license

from copy import copy

import numpy as np

from ultralytics.data import build_dataloader, build_yolo_dataset
from ultralytics.engine.trainer import BaseTrainer
from ultralytics.models import yolo
from ultralytics.nn.tasks import DetectionModel
from ultralytics.utils import LOGGER, RANK
from ultralytics.utils.torch_utils import de_parallel, torch_distributed_zero_first


class DetectionTrainer(BaseTrainer):
    def build_dataset(self, img_path, mode='train', batch=None):
        gs = max(int(de_parallel(self.model).stride.max() if self.model else 0), 32)
        return build_yolo_dataset(self.args, img_path, batch, self.data, mode=mode, rect=mode == 'val', stride=gs)

    def get_dataloader(self, dataset_path, batch_size=16, rank=0, mode='train'):
        assert mode in ['train', 'val']
        with torch_distributed_zero_first(rank):
            dataset = self.build_dataset(dataset_path, mode, batch_size)
        shuffle = mode == 'train'
        if getattr(dataset, 'rect', False) and shuffle:
            LOGGER.warning("WARNING ⚠️ 'rect=True' is incompatible with DataLoader shuffle, setting shuffle=False")
            shuffle = False
        workers = 0
        return build_dataloader(dataset, batch_size, workers, shuffle, rank)

    def preprocess_batch(self, batch):
        batch['img'] = batch['img'].to(self.device, non_blocking=True).float() / 255
        return batch

    def set_model_attributes(self):
        self.model.nc = self.data['nc']
        self.model.names = self.data['names']
        self.model.args = self.args

    def get_model(self, cfg=None, weights=None, verbose=True):
        model = DetectionModel(cfg, nc=self.data['nc'], verbose=verbose and RANK == -1)
        if weights:
            model.load(weights)
        return model

    def get_validator(self):
        self.loss_names = 'box_loss', 'cls_loss', 'dfl_loss'
        return yolo.detect.DetectionValidator(self.test_loader, save_dir=self.save_dir, args=copy(self.args))

    def label_loss_items(self, loss_items=None, prefix='train'):
        keys = [f'{prefix}/{x}' for x in self.loss_names]
        if loss_items is not None:
            loss_items = [round(float(x), 5) for x in loss_items]
            return dict(zip(keys, loss_items))
        else:
            return keys

    def progress_string(self):
        return ('\n' + '%11s' *
                (4 + len(self.loss_names))) % ('Epoch', 'GPU_mem', *self.loss_names, 'Instances', 'Size')

    def plot_training_samples(self, batch, ni):
        plot_images(images=batch['img'],
                    batch_idx=batch['batch_idx'],
                    cls=batch['cls'].squeeze(-1),
                    bboxes=batch['bboxes'],
                    paths=batch['im_file'],
                    fname=self.save_dir / f'train_batch{ni}.jpg',
                    on_plot=self.on_plot)

    def plot_metrics(self):
        plot_results(file=self.csv, on_plot=self.on_plot)

    def plot_training_labels(self):
        boxes = np.concatenate([lb['bboxes'] for lb in self.train_loader.dataset.labels], 0)
        cls = np.concatenate([lb['cls'] for lb in self.train_loader.dataset.labels], 0)
        plot_labels(boxes, cls.squeeze(), names=self.data['names'], save_dir=self.save_dir, on_plot=self.on_plot)


if __name__ == '__main__':
    args = dict(model='./yolov8l-goldyolo.yaml', data='coco8.yaml', epochs=100)
    trainer = DetectionTrainer(overrides=args)
    trainer.train()

这个程序文件是一个用于训练目标检测模型的程序。它使用了Ultralytics YOLO库,其中包含了构建数据集、构建数据加载器、模型训练等功能。

主要的类是DetectionTrainer,它继承自BaseTrainer类,用于基于目标检测模型进行训练。该类包含了构建数据集、构建数据加载器、预处理数据、设置模型属性、获取模型、获取验证器等方法。

main函数中,创建了一个DetectionTrainer对象,并传入了一些参数,如模型文件路径、数据集文件路径和训练轮数。然后调用train方法开始训练模型。

整个程序的功能是使用YOLO模型进行目标检测模型的训练,并提供了一些辅助方法用于数据处理、模型设置和结果可视化等。

5.5 backbone\convnextv2.py
import torch
import torch.nn as nn
import torch.nn.functional as F
from timm.models.layers import trunc_normal_, DropPath

class LayerNorm(nn.Module):
    def __init__(self, normalized_shape, eps=1e-6, data_format="channels_last"):
        super().__init__()
        self.weight = nn.Parameter(torch.ones(normalized_shape))
        self.bias = nn.Parameter(torch.zeros(normalized_shape))
        self.eps = eps
        self.data_format = data_format
        if self.data_format not in ["channels_last", "channels_first"]:
            raise NotImplementedError 
        self.normalized_shape = (normalized_shape, )
    
    def forward(self, x):
        if self.data_format == "channels_last":
            return F.layer_norm(x, self.normalized_shape, self.weight, self.bias, self.eps)
        elif self.data_format == "channels_first":
            u = x.mean(1, keepdim=True)
            s = (x - u).pow(2).mean(1, keepdim=True)
            x = (x - u) / torch.sqrt(s + self.eps)
            x = self.weight[:, None, None] * x + self.bias[:, None, None]
            return x

class GRN(nn.Module):
    def __init__(self, dim):
        super().__init__()
        self.gamma = nn.Parameter(torch.zeros(1, 1, 1, dim))
        self.beta = nn.Parameter(torch.zeros(1, 1, 1, dim))

    def forward(self, x):
        Gx = torch.norm(x, p=2, dim=(1,2), keepdim=True)
        Nx = Gx / (Gx.mean(dim=-1, keepdim=True) + 1e-6)
        return self.gamma * (x * Nx) + self.beta + x

class Block(nn.Module):
    def __init__(self, dim, drop_path=0.):
        super().__init__()
        self.dwconv = nn.Conv2d(dim, dim, kernel_size=7, padding=3, groups=dim)
        self.norm = LayerNorm(dim, eps=1e-6)
        self.pwconv1 = nn.Linear(dim, 4 * dim)
        self.act = nn.GELU()
        self.grn = GRN(4 * dim)
        self.pwconv2 = nn.Linear(4 * dim, dim)
        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()

    def forward(self, x):
        input = x
        x = self.dwconv(x)
        x = x.permute(0, 2, 3, 1)
        x = self.norm(x)
        x = self.pwconv1(x)
        x = self.act(x)
        x = self.grn(x)
        x = self.pwconv2(x)
        x = x.permute(0, 3, 1, 2)

        x = input + self.drop_path(x)
        return x

class ConvNeXtV2(nn.Module):
    def __init__(self, in_chans=3, num_classes=1000, 
                 depths=[3, 3, 9, 3], dims=[96, 192, 384, 768], 
                 drop_path_rate=0., head_init_scale=1.
                 ):
        super().__init__()
        self.depths = depths
        self.downsample_layers = nn.ModuleList()
        stem = nn.Sequential(
            nn.Conv2d(in_chans, dims[0], kernel_size=4, stride=4),
            LayerNorm(dims[0], eps=1e-6, data_format="channels_first")
        )
        self.downsample_layers.append(stem)
        for i in range(3):
            downsample_layer = nn.Sequential(
                    LayerNorm(dims[i], eps=1e-6, data_format="channels_first"),
                    nn.Conv2d(dims[i], dims[i+1], kernel_size=2, stride=2),
            )
            self.downsample_layers.append(downsample_layer)

        self.stages = nn.ModuleList()
        dp_rates=[x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] 
        cur = 0
        for i in range(4):
            stage = nn.Sequential(
                *[Block(dim=dims[i], drop_path=dp_rates[cur + j]) for j in range(depths[i])]
            )
            self.stages.append(stage)
            cur += depths[i]

        self.norm = nn.LayerNorm(dims[-1], eps=1e-6)
        self.head = nn.Linear(dims[-1], num_classes)

        self.apply(self._init_weights)
        self.channel = [i.size(1) for i in self.forward(torch.randn(1, 3, 640, 640))]

    def _init_weights(self, m):
        if isinstance(m, (nn.Conv2d, nn.Linear)):
            trunc_normal_(m.weight, std=.02)
            nn.init.constant_(m.bias, 0)

    def forward(self, x):
        res = []
        for i in range(4):
            x = self.downsample_layers[i](x)
            x = self.stages[i](x)
            res.append(x)
        return res

该程序文件是一个实现了ConvNeXt V2模型的PyTorch模块。ConvNeXt V2是一个用于图像分类任务的卷积神经网络模型。

该程序文件包含以下几个类和函数:

  1. LayerNorm类:实现了支持两种数据格式(channels_last和channels_first)的LayerNorm层。

  2. GRN类:实现了全局响应归一化(GRN)层。

  3. Block类:实现了ConvNeXtV2模型的基本块。

  4. ConvNeXtV2类:实现了ConvNeXt V2模型。

  5. update_weight函数:用于更新模型的权重。

  6. convnextv2_atto函数:创建一个ConvNeXtV2模型实例,使用atto配置。

  7. convnextv2_femto函数:创建一个ConvNeXtV2模型实例,使用femto配置。

  8. convnextv2_pico函数:创建一个ConvNeXtV2模型实例,使用pico配置。

  9. convnextv2_nano函数:创建一个ConvNeXtV2模型实例,使用nano配置。

  10. convnextv2_tiny函数:创建一个ConvNeXtV2模型实例,使用tiny配置。

  11. convnextv2_base函数:创建一个ConvNeXtV2模型实例,使用base配置。

  12. convnextv2_large函数:创建一个ConvNeXtV2模型实例,使用large配置。

  13. convnextv2_huge函数:创建一个ConvNeXtV2模型实例,使用huge配置。

这些函数可以根据需要选择不同的模型配置,并加载预训练的权重。

5.6 backbone\CSwomTramsformer.py
class CSWinTransformer(nn.Module):
    def __init__(self, img_size=224, patch_size=4, in_chans=3, num_classes=1000, embed_dim=96, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24], mlp_ratio=4., qkv_bias=True, qk_scale=None, drop_rate=0., attn_drop_rate=0., drop_path_rate=0., norm_layer=nn.LayerNorm):
        super().__init__()
        self.num_classes = num_classes
        self.depths = depths
        self.embed_dim = embed_dim
        self.patch_size = patch_size
        self.num_features = self.embed_dim * 4
        self.norm1 = norm_layer(self.num_features)
        self.proj1 = nn.Conv2d(in_chans, self.num_features, kernel_size=patch_size, stride=patch_size)
        self.norm2 = norm_layer(embed_dim)
        self.blocks = nn.ModuleList([
            CSWinBlock(
                dim=self.embed_dim, reso=img_size // patch_size, num_heads=num_heads[i],
                mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale,
                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=drop_path_rate,
                norm_layer=norm_layer, last_stage=(i == len(depths) - 1))
            for i in range(len(depths))])
        self.norm3 = norm_layer(self.embed_dim)
        self.avgpool = nn.AdaptiveAvgPool2d(1)
        self.head = nn.Linear(self.embed_dim, num_classes)

    def forward_features(self, x):
        x = self.proj1(x)
        x = self.norm1(x)
        x = x.flatten(2).transpose(1, 2)
        x = self.norm2(x)
        for blk in self.blocks:
            x = blk(x)
        x = self.norm3(x)
        return x

    def forward(self, x):
        x = self.forward_features(x)
        x = self.avgpool(x).squeeze(3).squeeze(2)
        x = self.head(x)
        return x

该程序文件是一个实现了CSWin Transformer模型的PyTorch模块。CSWin Transformer是一种用于图像分类任务的Transformer模型,具有较低的计算和内存开销。该模型包含了CSWinBlock模块和Merge_Block模块,以及一些辅助函数。

CSWinBlock模块定义了CSWin Transformer的基本组件。它包含了一个多头自注意力机制(LePEAttention),一个多层感知机(Mlp),以及一些归一化和残差连接操作。CSWinBlock模块将输入的图像分割成多个窗口,并对每个窗口进行自注意力计算和多层感知机计算,然后将结果进行残差连接。CSWinBlock模块可以堆叠多次以构建更深的CSWin Transformer模型。

Merge_Block模块用于将CSWin Transformer模型输出的多个窗口特征图合并成一个整体特征图。它使用一个卷积层将窗口特征图的尺寸减半,并进行归一化操作。

除了CSWinBlock和Merge_Block模块外,该程序文件还定义了一些辅助函数,用于将图像转换为窗口表示和将窗口表示转换为图像表示。

该程序文件还定义了一些预定义的CSWin Transformer模型,如CSWin_tiny、CSWin_small、CSWin_base和CSWin_large。这些模型具有不同的参数配置和模型大小,可以根据任务需求选择合适的模型进行训练和推理。

6.系统整体结构

以下是每个文件的功能的整理:

文件功能
export.py导出模型的功能
predict.py进行预测的功能
train.py训练模型的功能
ui.py图形界面的功能
backbone\convnextv2.pyConvNeXtV2模型的定义和配置
backbone\CSwomTramsformer.pyCSWin Transformer模型的定义和配置
backbone\EfficientFormerV2.pyEfficientFormerV2模型的定义和配置
backbone\efficientViT.pyEfficientViT模型的定义和配置
backbone\fasternet.pyFasterNet模型的定义和配置
backbone\lsknet.pyLSKNet模型的定义和配置
backbone\repvit.pyRepVIT模型的定义和配置
backbone\revcol.pyRevCol模型的定义和配置
backbone\SwinTransformer.pySwin Transformer模型的定义和配置
backbone\VanillaNet.pyVanillaNet模型的定义和配置
extra_modules\afpn.pyAFPN模块的定义
extra_modules\attention.py注意力机制模块的定义
extra_modules\block.py基础块模块的定义
extra_modules\dynamic_snake_conv.py动态蛇卷积模块的定义
extra_modules\head.py模型头部模块的定义
extra_modules\kernel_warehouse.py卷积核仓库模块的定义
extra_modules\orepa.pyOREPA模块的定义
extra_modules\rep_block.pyRepBlock模块的定义
extra_modules\RFAConv.pyRFAConv模块的定义
models\common.py通用模型函数和工具函数
models\experimental.py实验性模型的定义
models\tf.pyTensorFlow模型的定义和配置
models\yolo.pyYOLO模型的定义和配置
ultralytics…Ultralytics库的各个模块和功能
utils…工具函数和辅助功能的定义和实现

以上是对每个文件的功能的概括和整理。请注意,这只是根据文件名和路径进行的初步分析,具体的功能和实现可能需要查看代码来确认。

7.数据集的采集&标注和整理

图片的收集

首先,我们需要收集所需的图片。这可以通过不同的方式来实现,例如使用现有的公开数据集TrafficDatasets和coco。

在这里插入图片描述

labelImg是一个图形化的图像注释工具,支持VOC和YOLO格式。以下是使用labelImg将图片标注为VOC格式的步骤:

(1)下载并安装labelImg。
(2)打开labelImg并选择“Open Dir”来选择你的图片目录。
(3)为你的目标对象设置标签名称。
(4)在图片上绘制矩形框,选择对应的标签。
(5)保存标注信息,这将在图片目录下生成一个与图片同名的XML文件。
(6)重复此过程,直到所有的图片都标注完毕。

由于YOLO使用的是txt格式的标注,我们需要将VOC格式转换为YOLO格式。可以使用各种转换工具或脚本来实现。

下面是一个简单的方法是使用Python脚本,该脚本读取XML文件,然后将其转换为YOLO所需的txt格式。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import xml.etree.ElementTree as ET
import os

classes = []  # 初始化为空列表

CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))

def convert(size, box):
    dw = 1. / size[0]
    dh = 1. / size[1]
    x = (box[0] + box[1]) / 2.0
    y = (box[2] + box[3]) / 2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)

def convert_annotation(image_id):
    in_file = open('./label_xml\%s.xml' % (image_id), encoding='UTF-8')
    out_file = open('./label_txt\%s.txt' % (image_id), 'w')  # 生成txt格式文件
    tree = ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)

    for obj in root.iter('object'):
        cls = obj.find('name').text
        if cls not in classes:
            classes.append(cls)  # 如果类别不存在,添加到classes列表中
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')

xml_path = os.path.join(CURRENT_DIR, './label_xml/')

# xml list
img_xmls = os.listdir(xml_path)
for img_xml in img_xmls:
    label_name = img_xml.split('.')[0]
    print(label_name)
    convert_annotation(label_name)

print("Classes:")  # 打印最终的classes列表
print(classes)  # 打印最终的classes列表

整理数据文件夹结构

我们需要将数据集整理为以下结构:

-----data
   |-----train
   |   |-----images
   |   |-----labels
   |
   |-----valid
   |   |-----images
   |   |-----labels
   |
   |-----test
       |-----images
       |-----labels

确保以下几点:

所有的训练图片都位于data/train/images目录下,相应的标注文件位于data/train/labels目录下。
所有的验证图片都位于data/valid/images目录下,相应的标注文件位于data/valid/labels目录下。
所有的测试图片都位于data/test/images目录下,相应的标注文件位于data/test/labels目录下。
这样的结构使得数据的管理和模型的训练、验证和测试变得非常方便。

模型训练
 Epoch   gpu_mem       box       obj       cls    labels  img_size
 1/200     20.8G   0.01576   0.01955  0.007536        22      1280: 100%|██████████| 849/849 [14:42<00:00,  1.04s/it]
           Class     Images     Labels          P          R     mAP@.5 mAP@.5:.95: 100%|██████████| 213/213 [01:14<00:00,  2.87it/s]
             all       3395      17314      0.994      0.957      0.0957      0.0843

 Epoch   gpu_mem       box       obj       cls    labels  img_size
 2/200     20.8G   0.01578   0.01923  0.007006        22      1280: 100%|██████████| 849/849 [14:44<00:00,  1.04s/it]
           Class     Images     Labels          P          R     mAP@.5 mAP@.5:.95: 100%|██████████| 213/213 [01:12<00:00,  2.95it/s]
             all       3395      17314      0.996      0.956      0.0957      0.0845

 Epoch   gpu_mem       box       obj       cls    labels  img_size
 3/200     20.8G   0.01561    0.0191  0.006895        27      1280: 100%|██████████| 849/849 [10:56<00:00,  1.29it/s]
           Class     Images     Labels          P          R     mAP@.5 mAP@.5:.95: 100%|███████   | 187/213 [00:52<00:00,  4.04it/s]
             all       3395      17314      0.996      0.957      0.0957      0.0845

8.Gold-YOLO

在这里插入图片描述

Preliminaries

YOLO系列的中间层结构采用了传统的FPN结构,其中包含多个分支用于多尺度特征融合。然而,它只充分融合来自相邻级别的特征,对于其他层次的信息只能间接地进行“递归”获取。

传统的FPN结构在信息传输过程中存在丢失大量信息的问题。这是因为层之间的信息交互仅限于中间层选择的信息,未被选择的信息在传输过程中被丢弃。这种情况导致某个Level的信息只能充分辅助相邻层,而对其他全局层的帮助较弱。因此,整体上信息融合的有效性可能受到限制。
为了避免在传输过程中丢失信息,本文采用了一种新颖的“聚集和分发”机制(GD),放弃了原始的递归方法。该机制使用一个统一的模块来收集和融合所有Level的信息,并将其分发到不同的Level。通过这种方式,作者不仅避免了传统FPN结构固有的信息丢失问题,还增强了中间层的部分信息融合能力,而且并没有显著增加延迟。
在这里插入图片描述

低阶聚合和分发分支 Low-stage gather-and-distribute branch

从主干网络中选择输出的B2、B3、B4、B5特征进行融合,以获取保留小目标信息的高分辨率特征。

在这里插入图片描述

高阶聚合和分发分支 High-stage gather-and-distribute branch

高级全局特征对齐模块(High-GD)将由低级全局特征对齐模块(Low-GD)生成的特征{P3, P4, P5}进行融合。

在这里插入图片描述

Transformer融合模块由多个堆叠的transformer组成,transformer块的数量为L。每个transformer块包括一个多头注意力块、一个前馈网络(FFN)和残差连接。采用与LeViT相同的设置来配置多头注意力块,使用16个通道作为键K和查询Q的头维度,32个通道作为值V的头维度。为了加速推理过程,将层归一化操作替换为批归一化,并将所有的GELU激活函数替换为ReLU。为了增强变换器块的局部连接,在两个1x1卷积层之间添加了一个深度卷积层。同时,将FFN的扩展因子设置为2,以在速度和计算成本之间取得平衡。
在这里插入图片描述

信息注入模块(Information injection module): 高级全局特征对齐模块(High-GD)中的信息注入模块与低级全局特征对齐模块(Low-GD)中的相同。在高级阶段,局部特征(Flocal)等于Pi,因此公式如下所示:

在这里插入图片描述

增强的跨层信息流动 Enhanced cross-layer information flow

为了进一步提升性能,从YOLOv6 中的PAFPN模块中得到启发,引入了Inject-LAF模块。该模块是注入模块的增强版,包括了一个轻量级相邻层融合(LAF)模块,该模块被添加到注入模块的输入位置。为了在速度和准确性之间取得平衡,设计了两个LAF模型:LAF低级模型和LAF高级模型,分别用于低级注入(合并相邻两层的特征)和高级注入(合并相邻一层的特征)。它们的结构如图5(b)所示。为了确保来自不同层级的特征图与目标大小对齐,在实现中的两个LAF模型仅使用了三个操作符:双线性插值(上采样过小的特征)、平均池化(下采样过大的特征)和1x1卷积(调整与目标通道不同的特征)。模型中的LAF模块与信息注入模块的结合有效地平衡了准确性和速度之间的关系。通过使用简化的操作,能够增加不同层级之间的信息流路径数量,从而提高性能而不显著增加延迟。
在这里插入图片描述

9.系统整合

下图完整源码&数据集&环境部署视频教程&自定义UI界面

在这里插入图片描述

参考博客《【改进YOLOv8】融合Gold-YOLO的车辆未礼让行人检测系统》

10.参考文献


[1]周晓彦,王珂,李凌燕.基于深度学习的目标检测算法综述[J].电子测量技术.2017,(11).DOI:10.3969/j.issn.1002-7300.2017.11.020 .

[2]李旭冬,叶茂,李涛.基于卷积神经网络的目标检测研究综述[J].计算机应用研究.2017,(10).DOI:10.3969/j.issn.1001-3695.2017.10.001 .

[3]高仕博,程咏梅,肖利平,等.面向目标检测的稀疏表示方法研究进展[J].电子学报.2015,(2).DOI:10.3969/j.issn.0372-2112.2015.02.018 .

[4]黄凯奇,陈晓棠,康运锋,等.智能视频监控技术综述[J].计算机学报.2015,(6).DOI:10.11897/SP.J.1016.2015.01093 .

[5]张娟,毛晓波,陈铁军.运动目标跟踪算法研究综述[J].计算机应用研究.2009,(12).DOI:10.3969/j.issn.1001-3695.2009.12.002 .

[6]侯志强,韩崇昭.视觉跟踪技术综述[J].自动化学报.2006,(4).

[7]万缨,韩毅,卢汉清.运动目标检测算法的探讨[J].计算机仿真.2006,(10).DOI:10.3969/j.issn.1006-9348.2006.10.056 .

[8]尹宏鹏,陈波,柴毅,等.基于视觉的目标检测与跟踪综述[J].自动化学报.2016,(10).DOI:10.16383/j.aas.2016.c150823 .

[9]Shelhamer, Evan,Long, Jonathan,Darrell, Trevor.Fully Convolutional Networks for Semantic Segmentation[J].IEEE Transactions on Pattern Analysis & Machine Intelligence.2017,39(6).640-651.

[10]Everingham, M,Winn, J,Van Gool, L,等.The Pascal Visual Object Classes (VOC) Challenge[J].International Journal of Computer Vision.2010,88(2).

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从零开始:同城O2O外卖APP的技术开发指南

随着互联网的迅速发展&#xff0c;O2O&#xff08;OnlinetoOffline&#xff09;模式在各个行业都取得了巨大成功&#xff0c;而同城外卖APP更是成为人们生活中不可或缺的一部分。本文将从零开始&#xff0c;为您提供一份同城O2O外卖APP的技术开发指南&#xff0c;让您能够深入了…

OpenCV交叉编译

1.下载代码解压 tar -zxvf opencv-4.8.1.tar.gz cd cd opencv-4.8.1 sudo mkdir chmod 777 build cd build 2.配置交叉编译工具 根据自己的板子进行修改 -D CMAKE_C_COMPILERaarch64-mix210-linux-gcc -D CMAKE_CXX_COMPILERaarch64-mix210-linux-g 3.cmake生成makefi…

1.4 场景设计精要

一、场景主题确定 设计游戏场景首先明确游戏发生的时间地点等时代背景。通过对玩家动线的设计&#xff0c;功能模型的合理布局构建出场景的基本骨架。利用光影效果和色彩变化烘托场景氛围。 市场上常见的主题场景&#xff1a;剑侠、科幻、废墟、魔幻等 二、场景风格确定 大类分…

C51汇编程序

目录 一.C51的数据类型和存储类型 1.数据类型&#xff1a; 2.C51的扩展数据类型&#xff1a; 3.数据存储类型 4.数据存储模式 二.特殊功能寄存器及其位变量定义 1.特殊功能寄存器的C51定义 2.位变量的C51定义 三.C51语言的绝对地址访问 1.绝对宏 2._at_关键字 一.C5…

Linux CentOS本地部署SQL Server数据库结合cpolar内网穿透实现公网访问

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、Cpolar杂谈 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 安装sql server二. 局域网测试连接三. 安装cpolar内网穿透四. 将sqlserver映射…

创业6个月裤衩都赔掉了;2023生成式AI年度大事表;AI工程师的自我修养;LLM开发者成长计划;OpenAI LLM入门课程 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f440; 黄家驹AI演唱「直到世界尽头」&#xff0c;是科技前进也是青春回望~ https://www.bilibili.com/video/BV1CG411i7MV 最近几天&#xf…

2022 RedisDays 内容揭秘

上个月&#xff0c;Redis举办了3场线上会议&#xff0c;分别介绍了即将正式发布的Redis 7中包括的重要更新的内容&#xff0c;还有Redis完全重写的RedisJSON 2.0模块&#xff0c;和新发布的Redis Stack模块。除此之外&#xff0c;在此次线上会议中还介绍了现代化的软件架构与Re…

pyside6详细笔记

文章目录 主要模组简介绍安装与环境配置安装配置QtDesignerPyUICPyRCC基础了解元对象系统对象模型重要的类Qt 对象:身份?值?对象树与所有状态概述QObjects 的构造/销毁顺序继承关系图Qt 命名空间模块简介QWidget窗口的创建在PyQt中使用qrc/rcc资源系统Qt 资源系统简介qrc 文件…

从Java8升级到Java17,特色优化点

从Java8升级到Java17&#xff0c;特色优化点 一、局部变量类型推断二、switch表达式三、文本块四、Records五、模式匹配instanceof六、密封类七、NullPointerException 从Java 8 到 Java 20&#xff0c;Java 已经走过了漫长的道路&#xff0c;自 Java 8 以来&#xff0c;Java 生…

预赛->省赛->国赛 我的全国软件测试大赛之旅

学习推荐 Web 功能测试&#xff1a;Javaselenium3 web自动化测试实战 性能测试&#xff1a;看慕测官方的视频&#xff0c;这里会用就行&#xff0c;不用学太多 自己根据视频写的&#xff1a;Web自动测试常用代码(Java版) Web没啥难的&#xff0c;主要拼手速&#xff0c;其…

出错:I/O文件读取JAVA

I/O文件读取 /** author:xiaowang* date:2023/12/6* demand:读取java1班的数据* * */ package homework;import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException;public class FileReadTest {public static void main(String[] args) …

Windows系统上如何搭建Linux操作系统

一、准备工作 1&#xff0c;VMware安装包 2&#xff0c;Centos IOS镜像 3&#xff0c;finalshell安装包 阿里云盘下载地址&#xff1a; https://www.alipan.com/s/uSQsWn15E3W 二&#xff0c;VMware安装 1&#xff0c;新建虚拟机 2&#xff0c;选择下一步 3&#xff0c;…

小航助学题库白名单竞赛考级蓝桥杯等考scratch(14级)(含题库教师学生账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09; 需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;

每日一题 1466. 重新规划路线(树,DFS)

根据 connections 建立无向树从 0 开始深搜&#xff0c;每次调用 dfs 时判断路径方向是否正确 class Solution:def minReorder(self, n: int, connections: List[List[int]]) -> int:to defaultdict(set)edge defaultdict(list)for con in connections:edge[con[0]].appe…

Numpy 实现ID3决策树

Numpy 实现ID3决策树 # 定义节点类 二叉树 class Node:def __init__(self, rootTrue, labelNone, feature_nameNone, featureNone):self.root rootself.label labelself.feature_name feature_nameself.feature featureself.tree {}self.result {label:: self.label,fea…

HarmonyOS学习--TypeScript语言学习(一)

注意&#xff1a;这只是我学习的笔记&#xff01;&#xff01;&#xff01; 注意&#xff1a;这只是我学习的笔记&#xff01;&#xff01;&#xff01; 注意&#xff1a;这只是我学习的笔记&#xff01;&#xff01;&#xff01; 本章目录如下&#xff1a; 一、TypeScript语言…

汽车防爆膜行业研究:中国发展前景及市场投资分析

随着汽车保有量的不断增长&#xff0c;汽车的维修和保养等服务市场规模也会快速提升。业内人士表示&#xff0c;今年以来&#xff0c;越来越多的企业开始发力这一市场&#xff0c;汽车后市场的竞争区域也从大中城市向县域城市下沉。 防爆膜就是在车的玻璃上安装一层保护膜&…

各大期刊网址

1.NeurIPS&#xff0c;全称Annual Conference on Neural Information Processing Systems&#xff0c; 是机器学习领域的顶级会议&#xff0c;与ICML&#xff0c;ICLR并称为机器学习领域难度最大&#xff0c;水平最高&#xff0c;影响力最强的会议&#xff01; NeurIPS是CCF 推…

Android 背景边框集合

效果图 代码 <?xml version"1.0" encoding"utf-8"?> <shape xmlns:android"http://schemas.android.com/apk/res/android" android:shape"rectangle"><solid android:color"#ffffff" /><stroke and…

Doris 编译报错 Error: flex version (2.5.37) must be greater than or equal to 2.6.0

Doris 编译过程报错 Error: flex version (2.5.37) must be greater than or equal to 2.6.0yum update flex 不生效 下载flex 安装包 https://github.com/westes/flex/releases解压 tar -xvf flex-2.6.4.tar