《------往期经典推荐------》
二、机器学习实战专栏【链接】,已更新31期,欢迎关注,持续更新中~~
三、深度学习【Pytorch】专栏【链接】
四、【Stable Diffusion绘画系列】专栏【链接】
五、YOLOv8改进专栏【链接】,持续更新中~~
六、YOLO性能对比专栏【链接】,持续更新中~
《------正文------》
论文信息
论文地址:https://arxiv.org/abs/1905.02188
代码地址:https://github.com/open-mmlab/mmdetection
摘要
论文提出了一种名为CARAFE(内容感知特征重组)的新型特征上采样算子,用于解决现代卷积神经网络中的特征上采样问题。相比传统的双线性插值和反卷积等方法,CARAFE具有三大优势:
- 大感受野:能够聚合更大区域内的上下文信息
- 内容感知:根据输入内容动态生成自适应核
- 计算高效:引入的计算开销极小
实验表明,CARAFE在目标检测、实例分割、语义分割和图像修复等任务上都能带来显著性能提升(分别提升1.2% AP、1.3% AP、1.8% mIoU和1.1dB PSNR),同时计算开销几乎可以忽略。相关代码和模型已在开源平台发布。
方法详解
CARAFE的工作流程分为两个关键步骤:
1. 核预测模块
通过三个子模块动态生成内容感知的上采样核:
- 通道压缩器:使用1×1卷积减少通道数(默认Cm=64)
- 内容编码器:基于k_encoder×k_encoder的卷积生成上采样核
- 核归一化器:通过softmax进行空间归一化
2. 内容感知重组模块
使用预测的核权重对k_up×k_up邻域内的特征进行加权组合,实现特征上采样。
关键设计选择:
- 经验公式k_encoder = k_up - 2(默认k_up=5)
- 相比反卷积,计算量仅为HW199k FLOPs(反卷积为HW1180k)
创新点
- 动态核生成机制:首次将内容感知引入特征上采样过程,核权重根据输入特征动态预测
- 高效实现方案:通过通道压缩和轻量级预测模块,在保持大感受野(k_up=5)的同时控制计算量
- 通用性能提升:在多个密集预测任务中验证了有效性,且无需修改网络架构
CARAFE的核心作用
-
特征金字塔增强:替换FPN中的最近邻插值,使高层特征包含更多语义信息
-
细节恢复能力:在图像修复任务中,能更好地重建缺失区域的纹理和结构
-
多尺度特征融合:在UperNet中改进PPM、FPN和FUSE模块的上采样过程
实验验证:
- 目标检测:Faster R-CNN提升1.2% AP
- 语义分割:UperNet提升1.8% mIoU
- 计算效率:FLOPs仅为反卷积的1/6
总结
CARAFE通过内容感知的特征重组机制,为神经网络提供了更智能的上采样方案。其核心价值在于:
- 突破传统上采样方法的固定模式限制
- 以极小计算代价实现显著的性能提升
- 即插即用的设计使其易于集成到现有架构
未来可探索在超分辨率等低层视觉任务中的应用潜力。这项工作为特征上采样研究提供了新的方向标。
源码
import torch
from torch import nn
from ultralytics.nn.modules import Conv
class CARAFE(nn.Module):
"""
CARAFE 是一种上采样模块,通过学习的权重对特征图进行上采样。
参数:
c (int): 输入通道数
k_enc (int): 编码器部分的卷积核大小
k_up (int): 上采样时使用的 unfold 核大小
c_mid (int): 中间通道数
scale (int): 上采样倍率
"""
def __init__(self, c, k_enc=3, k_up=5, c_mid=64, scale=2):
super(CARAFE, self).__init__()
self.scale = scale # 设置上采样倍率
# 压缩输入通道到中间通道数
self.comp = Conv(c, c_mid)
# 编码器生成权重,输出通道数为(scale * k_up)^2
self.enc = Conv(c_mid, (scale * k_up) ** 2, k=k_enc, act=False)
# 使用 PixelShuffle 进行上采样操作
self.pix_shf = nn.PixelShuffle(scale)
# 最近邻插值方法作为上采样操作
self.upsmp = nn.Upsample(scale_factor=scale, mode='nearest')
# Unfold 操作提取感受野内的特征
self.unfold = nn.Unfold(kernel_size=k_up, dilation=scale,
padding=k_up // 2 * scale)
def forward(self, X):
b, c, h, w = X.size() # 获取输入张量的形状
h_, w_ = h * self.scale, w * self.scale # 计算上采样后的高度和宽度
W = self.comp(X) # 压缩输入通道
W = self.enc(W) # 编码器生成权重
W = self.pix_shf(W) # Pixel Shuffle 上采样权重
W = torch.softmax(W, dim=1) # 对权重应用 softmax 归一化
X = self.upsmp(X) # 输入特征图使用最近邻插值上采样
X = self.unfold(X) # 提取上采样后特征的感受野
X = X.view(b, c, -1, h_, w_) # 调整视图以分离感受野维度
X = torch.einsum('bkhw,bckhw->bchw', [W, X]) # 应用注意力机制加权聚合
return X # 返回上采样后的特征图
好了,这篇文章就介绍到这里,喜欢的小伙伴感谢给点个赞和关注,更多精彩内容持续更新~~
关于本篇文章大家有任何建议或意见,欢迎在评论区留言交流!