YOLO组件之C2f模块介绍

C2F类是yolo算法中的组件之一,该类是一个继承自 nn.Module 的神经网络模块。

1. C2f 类的前向传播过程

首先将输入数据经过第一个卷积层 cv1,然后将输出分为两个部分。其中一个部分直接传递给输出,另一个部分经过多个 Bottleneck 模块的处理。最后,两个部分的结果在通道维度上进行拼接,并经过第二个卷积层 cv2 得到最终的输出。

结构如下:

2. C2f模块的作用

特征转换:C2f模块通过两个卷积层(cv1和cv2)对输入数据进行特征转换。cv1卷积层将输入数据的通道数从c1变换为2 * self.c,cv2卷积层将经过一系列操作后的特征图的通道数从(2 + n) * self.c变换为c2。这些卷积操作有助于提取输入数据中的不同层次和抽象程度的特征。

分支处理:C2f模块将输入数据分为两个分支进行处理。其中一个分支直接传递给输出,另一个分支经过多个Bottleneck模块的处理。这样的分支设计有助于增加网络的非线性能力和表示能力,从而提高网络对复杂数据的建模能力。

特征融合:C2f模块通过在通道维度上对不同分支的特征进行拼接,实现特征融合。拼接后的特征将包含来自不同分支的信息,丰富了特征的表达能力。

3. yolov8中代码实现

class C2f(nn.Module):
    """CSP Bottleneck with 2 convolutions."""
    def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion
        super().__init__()
        self.c = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, 2 * self.c, 1, 1)
        self.cv2 = Conv((2 + n) * self.c, c2, 1)  # optional act=FReLU(c2)
        self.m = nn.ModuleList(Bottleneck(self.c, self.c, shortcut, g, k=((3, 3), (3, 3)), e=1.0) for _ in range(n))
    def forward(self, x):
        """Forward pass through C2f layer."""
        y = list(self.cv1(x).chunk(2, 1))
        y.extend(m(y[-1]) for m in self.m)
        return self.cv2(torch.cat(y, 1))
    def forward_split(self, x):
        """Forward pass using split() instead of chunk()."""
        y = list(self.cv1(x).split((self.c, self.c), 1))
        y.extend(m(y[-1]) for m in self.m)
        return self.cv2(torch.cat(y, 1))

代码解析:

a. init(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):初始化函数,用于定义和初始化类的属性和子模块。

c1:输入通道数。

c2:输出通道数。

n:Bottleneck 模块的数量。

shortcut:是否使用残差连接(shortcut)。

g:分组卷积中的组数。

e:扩展因子,用于计算隐藏通道数。

self.c = int(c2 * e):计算隐藏通道数。

self.cv1 = Conv(c1, 2 * self.c, 1, 1):定义第一个卷积层 cv1,输入通道数为 c1,输出通道数为 2 * self.c,卷积核大小为 1x1,步长为 1。

self.cv2 = Conv((2 + n) * self.c, c2, 1):定义第二个卷积层 cv2,输入通道数为 (2 + n) * self.c,输出通道数为 c2,卷积核大小为 1x1。

self.m = nn.ModuleList(Bottleneck(self.c, self.c, shortcut, g, k=((3, 3), (3, 3)), e=1.0) for _ in range(n)):创建一个包含 n 个 Bottleneck 模块的 nn.ModuleList 对象,并将其赋值给属性 self.m。每个 Bottleneck 模块的输入通道数和输出通道数都为 self.c,使用的卷积核大小为 ((3, 3), (3, 3)),扩展因子为 1.0。

b. forward(self, x):前向传播函数,定义了数据在网络中的正向流动。

x:输入数据。

y = list(self.cv1(x).chunk(2, 1)):将输入数据 x 经过 cv1 卷积层后的结果进行分割成两个张量,并存储在列表 y 中。

y.extend(m(y[-1]) for m in self.m):将列表 y 的最后一个张量作为输入,依次经过 self.m 中的每个 Bottleneck 模块,并将结果添加到列表 y 中。

return self.cv2(torch.cat(y, 1)):将列表 y 中的张量在维度 1 上进行拼接,并将拼接后的结果经过 cv2 卷积层得到最终的输出。

c. forward_split(self, x):前向传播函数的另一种实现方式,它与 forward 函数的区别在于使用了 split() 方法代替了 chunk() 方法。

y = list(self.cv1(x).split((self.c, self.c), 1)):将输入数据 x 经过 cv1 卷积层后的结果按照指定大小进行切割,并存储在列表 y 中。

y.extend(m(y[-1]) for m in self.m):将列表 y 的最后一个张量作为输入,依次经过 self.m 中的每个 Bottleneck 模块,并将结果添加到列表 y 中。

return self.cv2(torch.cat(y, 1)):将列表 y 中的张量在维度 1 上进行拼接,并将拼接后的结果经过 cv2 卷积层得到最终的输出。

4. 总结

综上,C2f模块在CSP Bottleneck结构中起到关键的作用,通过特征转换、分支处理和特征融合等操作,提取和转换输入数据的特征,生成更具表征能力的输出。这有助于提高网络的性能和表示能力,使得网络能够更好地适应复杂的数据任务。

相关推荐
苦学LCP的小猪13 分钟前
OpenCV图像基本操作
opencv·计算机视觉
量子-Alex14 分钟前
【目标检测】【PANet】Path Aggregation Network for Instance Segmentation
人工智能·目标检测·计算机视觉
lihuayong17 分钟前
计算机视觉:经典数据格式(VOC、YOLO、COCO)解析与转换(附代码)
人工智能·yolo·目标检测·计算机视觉·目标跟踪·coco·数据标注
thinkMoreAndDoMore22 分钟前
深度学习(3)-TensorFlow入门(常数张量和变量)
开发语言·人工智能·python
kngines30 分钟前
【Python量化金融实战】-第1章:Python量化金融概述:1.4 开发环境搭建:Jupyter Notebook、VS Code、PyCharm
python·量化金融
kngines34 分钟前
【Python量化金融实战】-第1章:Python量化金融概述:1.2 Python在量化金融中的优势与生态
python·量化金融
wapicn9935 分钟前
‌挖数据平台对接DeepSeek推出一键云端部署功能:API接口驱动金融、汽车等行业智能化升级
java·人工智能·python·金融·汽车·php
蓝桉8021 小时前
图片爬取案例
开发语言·数据库·python
wang_yb1 小时前
『Python底层原理』--Python整数为什么可以无限大
python·databook
敲上瘾1 小时前
基础dp——动态规划
java·数据结构·c++·python·算法·线性回归·动态规划