YOLO目标检测创新改进与实战案例专栏
专栏目录: YOLO有效改进系列及项目实战目录 包含卷积,主干 注意力,检测头等创新机制 以及 各种目标检测分割项目实战案例
专栏链接: YOLO基础解析+创新改进+实战案例
介绍
摘要
目标检测是计算机视觉中的一项重要下游任务。对于车载边缘计算平台来说,巨大的模型难以满足实时检测的要求,而由大量深度可分离卷积层构建的轻量化模型无法达到足够的准确性。我们引入了一种新的轻量级卷积技术,GSConv,以减轻模型的重量但保持准确性。GSConv 在模型的准确性和速度之间实现了出色的平衡。我们还提供了一种设计范式,称为 slim-neck,以实现检测器更高的计算成本效益。我们的方法在超过二十组比较实验中得到了稳健验证。特别是,通过我们的方法改进后的检测器在与原始版本相比时取得了最先进的结果(例如,在 Tesla T4 GPU 上以约 100FPS 的速度在 SODA10M 数据集上达到 70.9% mAP0.5)。代码可在 https://github.com/alanli1997/slim-neck-by-gsconv 获得。
文章链接
论文地址:论文地址
代码地址:代码地址
基本原理
Slim-Neck是一种用于目标检测器架构的设计范式,旨在通过引入轻量级卷积技术GSConv来实现在维持准确性的同时满足实时检测需求。Slim-Neck的设计理念是在保持准确性的同时提高检测器的计算成本效益。GSConv是一种通用的卷积方法,旨在减少计算复杂性,降低推理时间,并保持模型的准确性。
Slim-Neck的设计原理包括以下几个关键点:
- GSConv:GSConv是Slim-Neck中的关键技术,它通过减少冗余信息和压缩不必要的重复信息来降低计算复杂性。GSConv在颈部阶段处理连接的特征图,这时特征图已经变得足够纤细,通道维度达到最大,宽度和高度维度达到最小,从而使得转换更加适度。
- 纤细颈部设计:Slim-Neck通过设计纤细的颈部结构来降低检测器的计算复杂性和推理时间,同时保持准确性。这种设计受到了DensNet、VoVNet和CSPNet等方法的启发,旨在提高CNNs的学习能力。
- 结构设计:Slim-Neck的结构设计旨在降低计算复杂性,同时保持准确性。通过合理设计的结构,Slim-Neck能够在保持准确性的同时提高计算效率,特别适用于轻量级检测器,如YOLOv3/v4-tiny。
yolov8 代码引入
class GSConvns(GSConv):
# GSConv with a normative-shuffle https://github.com/AlanLi1997/slim-neck-by-gsconv
def __init__(self, c1, c2, k=1, s=1, g=1, act=True):
super().__init__(c1, c2, k=1, s=1, g=1, act=True)
c_ = c2 // 2
self.shuf = nn.Conv2d(c_ * 2, c2, 1, 1, 0, bias=False)
def forward(self, x):
x1 = self.cv1(x)
x2 = torch.cat((x1, self.cv2(x1)), 1)
# normative-shuffle, TRT supported
return nn.ReLU(self.shuf(x2))
class GSBottleneck(nn.Module):
# GS Bottleneck https://github.com/AlanLi1997/slim-neck-by-gsconv
def __init__(self, c1, c2, k=3, s=1, e=0.5):
super().__init__()
c_ = int(c2*e)
# for lighting
self.conv_lighting = nn.Sequential(
GSConv(c1, c_, 1, 1),
GSConv(c_, c2, 3, 1, act=False))
self.shortcut = Conv(c1, c2, 1, 1, act=False)
def forward(self, x):
return self.conv_lighting(x) + self.shortcut(x)
class DWConv(Conv):
# Depth-wise convolution class
def __init__(self, c1, c2, k=1, s=1, act=True): # ch_in, ch_out, kernel, stride, padding, groups
super().__init__(c1, c2, k, s, g=math.gcd(c1, c2), act=act)
class GSBottleneckC(GSBottleneck):
# cheap GS Bottleneck https://github.com/AlanLi1997/slim-neck-by-gsconv
def __init__(self, c1, c2, k=3, s=1):
super().__init__(c1, c2, k, s)
self.shortcut = DWConv(c1, c2, k, s, act=False)
class VoVGSCSP(nn.Module):
# VoVGSCSP module with GSBottleneck
def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):
super().__init__()
c_ = int(c2 * e) # hidden channels
self.cv1 = Conv(c1, c_, 1, 1)
self.cv2 = Conv(c1, c_, 1, 1)
# self.gc1 = GSConv(c_, c_, 1, 1)
# self.gc2 = GSConv(c_, c_, 1, 1)
# self.gsb = GSBottleneck(c_, c_, 1, 1)
self.gsb = nn.Sequential(*(GSBottleneck(c_, c_, e=1.0) for _ in range(n)))
self.res = Conv(c_, c_, 3, 1, act=False)
self.cv3 = Conv(2 * c_, c2, 1) #
def forward(self, x):
x1 = self.gsb(self.cv1(x))
y = self.cv2(x)
return self.cv3(torch.cat((y, x1), dim=1))
class VoVGSCSPC(VoVGSCSP):
# cheap VoVGSCSP module with GSBottleneck
def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):
super().__init__(c1, c2)
c_ = int(c2 * 0.5) # hidden channels
self.gsb = GSBottleneckC(c_, c_, 1, 1)
task与yaml配置
详见:https://blog.csdn.net/shangyanaf/article/details/139878671