YOLOv11 改进策略 | CVPR-2023 部分卷积 PConv:即插即用,减少冗余计算并提升特征学习
介绍
标准卷积层在处理输入特征图时,会与所有输入通道进行交互,即使这些通道中可能存在信息冗余。这导致了不必要的计算和内存访问开销。PConv (Partial Convolution),发表于 CVPR 2023,是一种高效的卷积操作,它巧妙地只对输入特征图的一部分通道进行标准卷积处理,而将剩余通道直接传递(恒等映射)。通过这种方式,PConv 显著减少了计算量和内存访问,是一种有效的轻量化卷积模块。将其集成到 YOLOv11(假设的未来版本)中,可以在保持甚至提升性能的同时,实现模型的高效化。
引言
YOLO 系列算法追求在速度和精度之间取得最佳平衡,并在各种硬件平台上的高效部署。标准卷积是 YOLO 中最常用的操作,但其计算成本较高。为了进一步提高 YOLOv11 的效率,需要采用更高效的卷积模块。PConv 的核心理念在于识别标准卷积中的冗余,并提出一种简单而有效的方法来减少这种冗余:只对一部分输入通道进行卷积。这种“部分处理”的方式直接降低了计算量(FLOPs),减少了需要访问的输入通道数量(降低了内存访问成本,MAC),并减少了参数数量。通过定期或策略性地使用通道混洗等机制,可以确保所有通道在网络的深度方向都能得到处理,并且信息能够在处理过的通道和未处理的通道之间流动。作为一种即插即用模块,PConv 可以方便地替换 YOLOv11 中标准的卷积层,是实现模型轻量化和提高推理速度的有效途径。
技术背景
标准卷积的计算与内存访问开销
标准卷积的计算量(FLOPs)与输入通道数、输出通道数、卷积核大小和输出特征图尺寸成正比。内存访问成本(MAC)与读取输入特征、权重和写入输出特征的次数相关。当输入通道数很大时,标准卷积的 FLOPs 和 MAC 都非常高。
轻量化卷积方法 (回顾)
- 深度可分离卷积: 通过深度卷积和逐点卷积分解标准卷积,大幅减少 FLOPs 和参数,但 MAC 可能并非最优,且通道间交流受限。
- 组卷积: 将通道分组处理,减少 FLOPs 和参数,但也限制了通道间交流,且 MAC 可能因分组而增加。
Motivation for PConv
PConv 的动机在于设计一种更简单、更直接且高效的轻量化卷积方法:
- 直接减少计算和 MAC: 通过只对一部分输入通道进行卷积,直接从源头减少了计算量和需要访问的内存。
- 保留原始信息: 未处理的通道直接传递,保留了原始输入信息,避免了信息丢失。
- 简单结构: PConv 的结构相对简单,易于实现和集成。
- 即插即用: 可以方便地替换标准卷积层。
PConv 原理 (基于 CVPR 2023 论文)
PConv 的核心原理如下:
- 通道划分 (Channel Splitting): 将输入特征图的通道分成两组:
- Processed Channels: 占输入通道的比例为 c i n / n c_{in} / n cin/n(例如 n = 4 n=4 n=4 时处理 1/4 的通道)。
- Unprocessed Channels: 占输入通道的比例为 c i n × ( n − 1 ) / n c_{in} \times (n-1) / n cin×(n−1)/n(例如 n = 4 n=4 n=4 时未处理 3/4 的通道)。
这种划分是沿着通道维度进行的。
- 部分卷积 (Partial Convolution): 对 Processed Channels 这一部分通道应用标准的卷积操作(例如 3x3 Conv)。这个卷积的输入通道数只有 c i n / n c_{in} / n cin/n,计算量大幅减少。
- 恒等映射 (Identity Mapping): 对 Unprocessed Channels 这一部分通道进行恒等映射,即直接传递,不进行任何计算。
- 通道拼接 (Channel Concatenation): 将经过部分卷积处理的通道和直接传递的未处理通道在通道维度上拼接起来,形成输出特征图。输出通道数由部分卷积的输出通道数和未处理通道数决定。为了使输出通道数与原始标准卷积一致,部分卷积的输出通道数和未处理通道数之和需要等于期望的输出通道数。通常,为了方便替换,输出通道数等于输入通道数,且部分卷积的输出通道数等于处理的输入通道数。
- 通道混洗 (Channel Mixing): 虽然 PConv 本身不强制要求在每个模块后进行通道混洗,但在网络的深度方向,需要定期或策略性地进行通道混洗或 1x1 卷积等操作,以确保信息能够在处理过的通道和未处理的通道之间流动,避免信息隔绝。
应用使用场景
将 PConv 模块集成到 YOLOv11 中,可以显著提升其在以下场景中的性能和效率:
- 部署到资源受限设备: 在移动端、嵌入式系统、物联网设备等计算能力、内存和功耗有限的平台上运行 YOLOv11。
- 需要极高推理速度的应用: 例如工业检测、高速视频监控等,通过降低计算量和 MAC 提高 FPS。
- 构建更小尺寸的模型: 减少模型参数量,方便在存储空间有限的设备上部署。
- 提升模型在各种任务上的通用性能: 作为通用的卷积替代品,有望在 YOLOv11 的不同层级都带来性能提升。
不同场景下详细代码实现
以下提供使用 PyTorch 实现标准的卷积层以及 PConv 模块。
1. 标准卷积层实现 (回顾)
import torch
import torch.nn as nn
class StandardConv(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False, act=True):
super().__init__()
self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding, bias=bias)
self.bn = nn.BatchNorm2d(out_channels)
self.act = nn.SiLU() if act else nn.Identity()
def forward(self, x):
return self.act(self.bn(self.conv(x)))
2. PConv 模块实现 (PyTorch)
根据论文描述,PConv 包含通道划分、部分卷积、恒等映射和拼接。通常用于替换标准卷积。为了方便替换,PConv 的输入输出通道数通常与标准卷积一致。
import torch
import torch.nn as nn
import torch.nn.functional as F
class PConv(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=1, groups=1, bias=False, act=True, n_ratio=4):
"""
PConv: Partial Convolution
Args:
in_channels (int): 输入通道数
out_channels (int): 输出通道数 (通常等于 in_channels for replacement)
kernel_size (int): 卷积核大小
stride (int): 步长
padding (int): padding
groups (int): 卷积分组 (通常为 1 for standard conv replacement)
bias (bool): 是否使用偏置
act (bool): 是否使用激活函数
n_ratio (int): 控制处理通道比例的参数,处理通道数为 in_channels // n_ratio
"""
super().__init__()
self.in_channels = in_channels
self.out_channels = out_channels
self.kernel_size = kernel_size
self.stride = stride
self.padding = padding
self.groups = groups
self.n_ratio = n_ratio
# Calculate the number of processed channels
self.processed_channels = in_channels // n_ratio
# Ensure the number of processed channels is at least 1
self.processed_channels = max(1