【目标检测】Yolov7 的 ELAN 和 E-ELAN 模块演进(涉及到分组卷积,cardinality,梯度路径)

发布于:2024-04-30 ⋅ 阅读:(27) ⋅ 点赞:(0)

感觉从 YOLOv6 开始,YOLOv6 系列感觉优化点都着重于推理速度上面,YOLOv6 的 RepBlock 重参数化,给我的感觉就是算子融合进行加速。而 YOLOv7,为了在各种架构的边缘设备上获得极致的推理速度。

YOLOv7 的工作:

  1. 新的 bag of freebies(有效的训练技巧,不会增加推理的计算量)
  2. 有规划的重参数化模型(不同边缘设备架构,不同的重参数化方法)
  3. 新的动态标签分配方法

为了更好的理解 YOLOv7 里的 E-ELAN 模块,我们将模块的整个演变历程给出来:

E-ELAN 模块的演进

ResNet -> DenseNet -> VovNet -> CspVovNet -> ELAN(YOLOv7) -> E-ELAN

ResNet -> DenseNet

首先是何凯明大佬的 ResNet,DenseNet 的作者认为相比于 ResNet 对 shortcut 进行 Add 的方式,Concat 的方式可以让网络的 feature map 获得多个感知域的信息,对于不同尺度的特征提取是非常有效的。

DenseNet -> VovNet

在这里插入图片描述
但是 DenseNet 有两个问题:

  1. 每一层都用到之前所有特征层,导致大量内存读取(MAC memory access cost 比较大,shuffleNet v2 提出的概念)
  2. 每次 Concat 都会成倍扩大 channel,为了减少计算量而使用的 1x1 卷积,但是这种小卷积核不能很好被 GPU 并行计算支持

解决方案:OSA(One-Shot Aggregation)

最后阶段才进行 aggregation。不仅继承了 DenseNet 的多感受野表示多种特征的优点,也解决了密集连接效率低下的问题。

VovNet -> CspVovNet

在这里插入图片描述
Csp 结构我们已经很熟悉了,是在 PRN 的基础上发展过来的,在 YOLOv4,YOLOv5 和 YOLOv6 都得到了广泛的应用,通过将特征图分成 2 部分,在这些部分之间进行交叉连接。来提升特征提取能力。

CspVovNet 就是 VovNet 加上了 Csp 结构,既可以保留 DenseNet 多感受野的信息,也可以通过 CSP 结构避免过多重复梯度信息。

CspVovNet 的输入是 2c,因为 Csp,所以将通道 2c 分成了两部分,每部分的输出是 c,第一部分直接通过 cross stage connection,第二部分就是流过 VovNet 的部分。

CspVovNet -> ELAN

作者发现一个问题,在比较 VovNet 和 ResNet 的时候,随着 VovNet 模块的叠加,网络的表现会比 ResNet 要差,作者觉得是因为随着叠加, VovNet 中 transition layer 过多导致的。

我们一般会将改变特征图尺寸或者通道数的层,叫做 transition layer。从上面 CspVovNet 的图可以看出来,模块中含有两个 transition layer,分别是将通道数从 3c -> c 和 4c -> c 两个。梯度在经过 transition layer 这些层的时候,可能会发生损失或者变形。

所以,作者的对模块修改的优化方向就是减少这样的 transition layer:
在这里插入图片描述
在设计 ELAN 的时候涉及两个概念:梯度最短路径梯度最长路径。关于这个还是有点没太明白这两个概念的定义是啥。

在 ELAN 模块中,中间的 transition layer 被删掉了,合并了之前的两条 shortcut。

ELAN -> E-ELAN

在这里插入图片描述
E-ELAN 上半部分会出现 4 个分支,和 ELAN 一样,但是 ELAN 经过一个 transition layer 就输出了,但是 E-ELAN 的 4 个分支,每个分支都是 2c,然后每个分支的 2c 都分成两个 c 的分支,分别输入两个 4c 的层。

由上图可以看出,E-ELAN 在右侧 computational block 部分扩展 cardinality,进行 VoVNet 中 OSA Module 相关操作,在 OSA Module 最后的 concatenate 阶段使用 shuffule ,最后对 cardinality进行融合。

我们看到上面主要有三个操作:

  • Expand cardinality
  • Shuffle cardinality
  • Merge cardinality

这里又涉及到一个新的概念 cardinality 基数,这个超参数是在 ResNeXt 中第一次被引入的。

在这里插入图片描述

分组卷积

其实就是分组卷积,每一组都分配到一定的通道,然后分别进行卷积,然后 concat 到一起。例如,

首先说一下普通的多通道卷积,我们输入是一个 32x32x4 的图像,如果想要输出 64 通道的特征图,我们需要有 64 个三维卷积核,这意味着,每个三维卷积核都是 3x3x4 的维度,然后使用输入的 4 个通道,一一和 64 个三维卷积核对应的通道进行卷积,这样就会产生,4 x 64 个特征图,也就是每个三维卷积核都会生成 4 个特征图,这 4 个特征图会进行 Add 操作,也就是最终,每个三维卷积核都只会产生 1 张特征图,所以最后会输出 64 个特征图,也就是得到所谓的 64 通道。

分组卷积呢,还是 32x32x4 的输入,如果我们想分成 4 组,则会将输入的通道数 C i n = 4 C_{in}=4 Cin=4 分成 4 份,然后 64 个三维卷积核,也是分别分成 4 组 64 个一维的卷积核,然后分别进行单通道的卷积。就是每一组都会得到 16 个特征图,得到的结果再进行 concat 操作,4 组的 16 个特征图 concat 在一起就是 64 通道的特征图了。

虽然分组卷积核普通的多通道卷积得到的输出特征图的尺寸维度一致,但是要说他们的操作并不是等价的,只是维度操作得到一样的结果。

我们要明白分组卷积与 Inception 模块有什么区别,虽然两者都会分成很多分支,但是 Inception 分支中的卷积,并不会进行分组,然后求解,都是全量通过不同的卷积核,得到不同的特征图,然后进行 concat 拼接。

expand, shuffle,merge cardinality

上面的 expand cardinality,是扩大了通道数,本来输入的通道数是 2c,现在扩大成 2 个分支,每个分支都是 2c 的通道数,一支是 shortcut,另外一支和 ELAN 的操作差不多。

而 shuffle cardinality 和分组中的 shuffle 类似,两个分组卷积之间加入 Channel_Shuffle 模块打乱通道顺序,从而实现不同分组间的信息交换。这边的 shuffle 操作也是类似的,打乱各个通道的顺序。

最后进行 merge cardinality,而merge操作则是CSPNet的精髓——跨阶段特征融合,使用 Add 操作进行特征融合。

参考文章:


网站公告

今日签到

点亮在社区的每一天
去签到