CNN难以捕捉全局表征,这通常对高级计算机视觉任务至关重要。一个直观的解决方案是扩大感受野,但这可能需要更密集但具有破坏性的池化操作。由于自注意力机制和多层感知器(MLP)结构,transformer反映了复杂的空间变换和长距离特征依赖性,构成了全局表示。不幸的是,观察到视觉transformer忽略了局部特征细节,这降低了背景和前景之间的可辨别性。一些改进的视觉转换器提出了一个标记化模块或利用 CNN 特征图作为输入标记来捕获特征相邻信息。然而关于如何将局部特征和全局表示精确地相互嵌入的问题仍然存在。在Conformer中,我们连续将transformer分支的全局上下文馈送到卷积特征图,以加强CNN分支的全局感知能力。 类似地来自CNN分支的局部特征逐渐反馈到patch embedding中,以丰富transformer分支的局部细节,这样的过程构成了相互作用。
Conformer 由一个主干模块、双分支、桥接双分支的 FCU 和用于双分支的两个分类器(一个 fc 层)组成。
主干模块:主干模块是一个 7×7 卷积,步长为 2,然后是一个 3×3最大池化,步长为 2,用于提取初始局部特征
双分支:CNN 分支和transformer分支分别由N个重复的卷积块和transformer 块组成,这样的并发结构意味着CNN和transformer分支可以分别最大程度地保留局部特征和全局表示。
FCU: FCU 作为桥接模块,将 CNN 分支中的局部特征与transformer分支中的全局表示融合,FCU 从第二个块开始应用,因为两个分支的初始化特征是相同的。沿着分支,FCU 以交互方式逐步融合特征图和patch embedding。
分类:最后对于CNN分支,所有特征都被汇集并馈送到一个分类器。对于transformer 分支,类token 被取出并馈送到另一个分类器。在训练过程中,使用两个交叉熵损失来分别监督两个分类器。
CNN分支: CNN分支采用特征金字塔结构,特征图的分辨率随着网络深度的增加而降低,而通道数增加。我们将整个分支分为 4 个阶段,每个stage由多个卷积块组成,每个卷积块包含n个bottlenecks。遵循ResNet,bottlenecks包含 1×1 卷积、3×3 空间卷积、1×1 卷积以及输入和输出之间的残差连接。
transformer 通过一步将图像patch投影到向量中,导致局部细节丢失。而在CNN 中,卷积核滑动重叠的过特征图,这提供了保留精细局部特征的可能性。因此CNN 分支能够为transformer分支连续提供局部特征细节。
Transformer Branch: 类似ViT ,该分支包含N个重复的Transformer块,每个 Transformer 块由一个多头自注意力模块和一个 MLP 块组成。在每一层之前应用layernorm,并且在自注意力层和 MLP 块这两个层中都有残差连接。我们将主干模块生成的特征图压缩成14×14的patch embedding,而没有重叠,通过线性投影层,这是一个步长为4的4×4卷积
FCU:给定CNN分支中的特征图和transformer分支中的patch embedding,如何消除它们之间的错位是一个重要问题。为了解决这个问题,我们提出FCU以交互方式将局部特征与全局表示连续耦合。
一方面CNN和transformer的特征维度不一致,CNN特征图的维度为C×H×W,而patch embeddings的形状为(K+1)×E,其中K、1和E分别表示图像块的数量、类别 token和embedding维度。当馈送到transformer分支时,特征图首先需要通过 1×1 卷积来对齐patch embedding的通道数。然后使用下采样模块完成空间维度对齐。最后特征图添加patch embedding。 当从transformer branch 反馈到CNN 分支时,patch embedding需要上采样以对齐空间尺度,然后通过1×1卷积将通道维度与 CNN 特征图的维度对齐,并添加到特征图中。同时,LayerNorm 和 BatchNorm 模块用于对特征进行正则化。
另一方面,特征图和patch embedding之间存在显着的语义差距,即特征图是从局部卷积算子中收集的,而patch embedding与全局自我聚合。因此在每个块(除了第一个块)中应用 FCU 以逐步填补语义空白。
Conformer-s模型配置信息:
Conformer-Ti、Conformer-B模型配置信息:
在YOLOv5项目中添加模型作为Backbone使用的教程:
(1)将YOLOv5项目的models/yolo.py修改parse_model函数以及BaseModel的_forward_once函数
(2)在models/backbone(新建)文件下新建Conformer.py,添加如下的代码:
(3)在models/yolo.py导入模型并在parse_model函数中修改如下(先导入文件):
(4)在model下面新建配置文件:yolov5_conformer.yaml
(5)运行验证:在models/yolo.py文件指定–cfg参数为新建的yolov5_conformer.yaml