YOLOv5+BiSeNet——同时进行目标检测和语义分割

这篇具有很好参考价值的文章主要介绍了YOLOv5+BiSeNet——同时进行目标检测和语义分割。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在Gayhub上看到个项目,有人在YOLOv5的基础上,新增了一个分割头,把BiSeNet语义分割算法加入到了目标检测中,使其能够同时进行目标检测和语义分割。
项目地址:https://github.com/TomMao23/multiyolov5

效果预览

先看我使用原作者提供的模型,复刻出来的效果:
(本来想放视频的,不过传了两次CSDN都莫名其妙消失了,那就放动图了)
YOLOv5+BiSeNet——同时进行目标检测和语义分割

模型架构

目标检测模型采用的是YOLOv5,具体原理在我之前的博文【目标检测】从YOLOv1到YOLOX(理论梳理)里已经详细解读过。
语义分割模型采用的是部分BiSeNet结构,因为我不是这个方向的,具体原理不做细究,放张BiSeNet的结构图[1]:

YOLOv5+BiSeNet——同时进行目标检测和语义分割

核心代码

原作者目标检测使用的Coco数据集,语义分割使用的是Cityscapes数据集。
模型主要是在YOLOv5-5.0版本上进行修改的,基准模型采用的是YOLOv5m,语义分割的实现主要是在模型输出的Head部分添加了一个头:
yolov5m_city_seg.yaml

# parameters
nc: 10  # number of classes
n_segcls: 19 # 分割类别数
depth_multiple: 0.67  # model depth multiple
width_multiple: 0.75  # layer channel multiple

# anchors
anchors:
  - [10,13, 16,30, 33,23]  # P3/8
  - [30,61, 62,45, 59,119]  # P4/16
  - [116,90, 156,198, 373,326]  # P5/32

# YOLOv5 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Focus, [64, 3]],  # 0-P1/2
   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
   [-1, 3, C3, [128]],
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
   [-1, 9, C3, [256]],
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
   [-1, 9, C3, [512]],
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 1, SPP, [1024, [5, 9, 13]]],
   [-1, 3, C3, [1024, False]],  # 9
  ]

# YOLOv5 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4  # PANet是add, yolov5是concat
   [-1, 3, C3, [512, False]],  # 13

   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, C3, [256, False]],  # 17 (P3/8-small)

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, C3, [1024, False]],  # 23 (P5/32-large)
                  #[类别/输出通道, C3的n, C3的c2, C3的shortcut(以base为例,其他头含义可能不同)] yolo.py解析代码, []内第一项必须是输出通道数
   #[[4, 19], 1, SegMaskLab, [n_segcls, 3, 256, False]],  # 语义分割头通道配置256,[]内n为3
   [[16, 19, 22], 1, SegMaskPSP, [n_segcls, 3, 256, False]],  # 语义分割头通道配置256
   #[[16, 19, 22], 1, SegMaskBiSe, [n_segcls, 3, 256, False]],  # 语义分割头通道配置无效
   #[[16], 1, SegMaskBase, [n_segcls, 3, 512, False]],  # 语义分割头通道配置512

   [[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)  必须在最后一层, 原代码很多默认了Detect是最后, 并没有全改
  ]

代码中,在最后的输出部分,作者添加了3个和Detect平行的分割头,其中,SegMaskLabSegMaskPSPSegMaskBiSeSegMaskBase分别是不同的独立结构,是作者实验所用。
在yolo.py中,可以看到它们详细的结构:

class SegMaskPSP(nn.Module):  # PSP头,多了RFB2和FFM,同样砍了通道数,没找到合适的位置加辅助损失,因此放弃辅助损失
    def __init__(self, n_segcls=19, n=1, c_hid=256, shortcut=False, ch=()):  # n是C3的, (接口保留了,没有使用)c_hid是隐藏层输出通道数(注意配置文件s*0.5,m*0.75,l*1)
        super(SegMaskPSP, self).__init__()
        self.c_in8 = ch[0]  # 16  # 用16,19,22宁可在融合处加深耗费一些时间,检测会涨点分割也很好。严格的消融实验证明用17,20,23分割可能还会微涨,但检测会掉3个点以上,所有头如此
        self.c_in16 = ch[1]  # 19
        self.c_in32 = ch[2]  # 22
        # self.c_aux = ch[0]  # 辅助损失  找不到合适地方放辅助,放弃
        self.c_out = n_segcls
        # 注意配置文件通道写256,此时s模型c_hid=128
        self.out = nn.Sequential(  # 实验表明引入较浅非线性不太强的层做分割会退化成检测的辅助(分割会相对低如72退到70,71,检测会明显升高),PP前应加入非线性强一点的层并适当扩大感受野
                                RFB2(c_hid*3, c_hid, d=[2,3], map_reduce=6),  # 3*128//6=64 RFB2和RFB无关,仅仅是历史遗留命名(训完与训练模型效果不错就没有改名重训了)
                                PyramidPooling(c_hid, k=[1, 2, 3, 6]),  # 按原文1,2,3,6,PSP加全局更好,但是ASPP加了全局后出现边界破碎
                                FFM(c_hid*2, c_hid, k=3, is_cat=False),  # FFM改用k=3, 相应的砍掉部分通道降低计算量(原则就是差距大的融合哪怕砍通道第一层也最好用3*3卷积,FFM融合效果又比一般卷积好,除base头外其他头都遵循这种融合方式)
                                nn.Conv2d(c_hid, self.c_out, kernel_size=1, padding=0),
                                nn.Upsample(scale_factor=8, mode='bilinear', align_corners=True),
                               )
        self.m8 = nn.Sequential(
                                Conv(self.c_in8, c_hid, k=1),
        )
        self.m32 = nn.Sequential(
                                Conv(self.c_in32, c_hid, k=1),
                                nn.Upsample(scale_factor=4, mode='bilinear', align_corners=True),
        )
        self.m16 = nn.Sequential(
                                Conv(self.c_in16, c_hid, k=1),
                                nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True),
        )
        # self.aux = nn.Sequential(
        #                        Conv(self.c_aux, 256, 3),  
        #                        nn.Dropout(0.1, False), 
        #                        nn.Conv2d(256, self.c_out, kernel_size=1),
        #                        nn.Upsample(scale_factor=8, mode='bilinear', align_corners=True),
        # )
    def forward(self, x):
        # 这个头三层融合输入做过消融实验,单独16:72.6三层融合:73.5,建议所有用1/8的头都采用三层融合,在Lab的实验显示三层融合的1/16输入也有增长
        feat = torch.cat([self.m8(x[0]), self.m16(x[1]), self.m32(x[2])], 1)
        # return self.out(feat) if not self.training else [self.out(feat), self.aux(x[0])]
        return self.out(feat)

下面是模型检测(detect.py)中的主要改动,在模型输出部分使用seg来获取语义分割结果,再利用提前定义好的颜色图Cityscapes_COLORMAP分别给分割部分上色。

seg = F.interpolate(seg, (im0.shape[0], im0.shape[1]), mode='bilinear', align_corners=True)[0]
mask = label2image(seg.max(axis=0)[1].cpu().numpy(), Cityscapes_COLORMAP)[:, :, ::-1]
dst = cv2.addWeighted(mask, 0.4, im0, 0.6, 0)

代码备份

其它改动还很多,可以去原作者的仓库阅读。
这里将其代码进行备份,包含作者提供的模型权重:
https://pan.baidu.com/s/1JtqCtlJwk5efkiTQqmNpVA?pwd=36bk

References

[1]https://blog.csdn.net/qq_40073354/article/details/120725919文章来源地址https://www.toymoban.com/news/detail-466638.html

到了这里,关于YOLOv5+BiSeNet——同时进行目标检测和语义分割的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 利用yolov5进行目标检测,并将检测到的目标裁剪出来

    利用yolov5进行目标检测,并将检测到的目标裁剪出来

    写在前面:关于yolov5的调试运行在这里不做过多赘述,有关yolov5的调试运行请看: https://www.bilibili.com/video/BV1tf4y1t7ru/spm_id_from=333.999.0.0vd_source=043dc71f3eaf6a0ccb6dada9dbd8be37 本文章主要讲解的是裁剪。 需求:识别图片中的人物并将其裁剪出来 如果只需识别人物的话,那么只需在y

    2024年02月02日
    浏览(6)
  • 记录使用yolov5进行旋转目标的检测

    记录使用yolov5进行旋转目标的检测

    由于实习公司需要使用到旋转目标的检测,所以这几天学习了相关知识,并找了许多资料,饶了许多的弯路。下面记录下项目的整个实现过程。 我参考的是以下几位博主: DOTAv2遥感图像旋转目标检测竞赛经验分享(Swin Transformer + Anchor free/based方案) - 知乎 小鸡炖技术的个人

    2024年02月02日
    浏览(14)
  • 如何使YOLOv5在检测到目标后进行声音告警提示?

    如何使YOLOv5在检测到目标后进行声音告警提示?

    导师有一个异常行为检测的小任务(吸烟行为检测),给我让我和师弟一起去完成。本身以为在YOLOv5的detect.py检测脚本中加入语音提示很简单,但是其中的过程却是一言难尽。 这也是查阅了很多资料,尝试过了各种大佬分享的经验,集百家之长完成了这个任务,感谢CSDN中各

    2024年01月19日
    浏览(11)
  • YOLOv5改进 | Neck篇 | 利用ASF-YOLO改进特征融合层(适用于分割和目标检测)

    本文给大家带来的改进机制是 ASF-YOLO(发布于2023.12月份的最新机制) ,其是特别设计用于细胞实例分割。这个模型通过结合空间和尺度特征,提高了在处理细胞图像时的准确性和速度。在实验中, ASF-YOLO在2018年数据科学竞赛 数据集上取得了卓越的分割准确性和速度,达到了

    2024年01月15日
    浏览(12)
  • Python——一文详解使用yolov5进行目标检测全流程(无需gpu)

    Python——一文详解使用yolov5进行目标检测全流程(无需gpu)

    本文按步骤详细介绍了使用yolov5进行目标检测的全流程,包括:模型下载、环境配置、数据集准备和数据预处理、模型调整、模型训练、进行目标检测和检测结果分析。本文全部流程使用cpu完成(无需gpu),旨在跑通流程,模型训练过程较慢,且未能到达最优结果。需要 py

    2024年03月18日
    浏览(12)
  • c++读取yolov5模型进行目标检测(读取摄像头实时监测)

    c++读取yolov5模型进行目标检测(读取摄像头实时监测)

    文章介绍 本文是篇基于yolov5模型的一个工程,主要是利用c++将yolov5模型进行调用并测试,从而实现目标检测任务 任务过程中主要重点有两个,第一 版本问题,第二配置问题 一,所需软件及版本       训练部分 pytorch==1.13.0  opencv==3.4.1   其他的直接pip即可       c++部署 

    2024年02月07日
    浏览(12)
  • 计算机视觉的应用7-利用YOLOv5模型启动电脑摄像头进行目标检测

    计算机视觉的应用7-利用YOLOv5模型启动电脑摄像头进行目标检测

    大家好,我是微学AI,今天给大家介绍一下计算机视觉的应用7-利用YOLOv5模型启动电脑摄像头进行目标检测,本文将详细介绍YOLOv5模型的原理,YOLOv5模型的结构,并展示如何利用电脑摄像头进行目标检测。文章将提供样例代码,以帮助读者更好地理解和实践YOLOv5模型。 目录 引

    2024年02月10日
    浏览(13)
  • BiSeNetv2:语义分割经典方法BiSeNet的升级版本

    BiSeNetv2:语义分割经典方法BiSeNet的升级版本

    分享IJCV2021上发表的一篇文章BiSeNetv2,这是BiSeNet的升级版本。开源代码地址:https://github.com/open-mmlab/mmsegmentation/tree/master/configs/bisenetv2 语义分割是指为每个像素分配一个标签,它广泛用于场景理解、自动驾驶、人机交互、视频监控等领域中。近年来,随着卷积神经网络的发展

    2024年02月07日
    浏览(7)
  • BiSeNet:用于实时语义分割的双边分割网络——BiSeNet:Bilateral Segmentation Network for Real-time Semantic Segmentation

    BiSeNet:用于实时语义分割的双边分割网络——BiSeNet:Bilateral Segmentation Network for Real-time Semantic Segmentation

            语义分割需要丰富的空间信息和较大的感受野。然而,现代的方法通常为了实现实时推断速度而牺牲空间分辨率,导致性能下降。本文提出了一种新的双边分割网络(BiSeNet)来解决这个问题。我们首先设计了一个具有小步长的空间路径来保留空间信息并生成高分

    2024年04月28日
    浏览(6)
  • 深度学习中语义分割、实例分割、目标检测和图像分类区别

    深度学习中语义分割、实例分割、目标检测和图像分类区别

    语义分割 实例分割 目标检测 语义分割:需要判断每个像素属于哪一个类别,属于像素级别分类标注 实例分割:相较于语义分割 会将同一类别的不同物体进行分离标注   目标检测:输入图像通常包含多个物体,对物体的位置与类别进行标注  图像分类:输入图像通常包含一

    2024年02月08日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包