【AAAI2025】风车卷积替代标准卷积,增强了底层特征提取能力

Pinwheel-shaped Convolution and Scale-based Dynamic Loss for Infrared Small Target Detection

基于风车形卷积和尺度动态损失的红外小目标检测

风车形卷积(PConv)模块:

作者提出了一种新颖的风车形卷积(PConv)模块,用于替代标准卷积。该模块更好地符合红外小目标(IRST)的高斯空间分布特性,增强了底层特征提取能力,并显著扩展了感受野,同时仅引入了极少的参数增加。

效果图

代码

python 复制代码
import torch
import torch.nn as nn
import torch.nn.functional as F
"""风车型卷积,使用了padding再各个方向上实现方向敏感性,增加了参数量"""

def autopad(k, p=None, d=1):  # kernel, padding, dilation
    """Pad to 'same' shape outputs."""
    if d > 1:
        k = d * (k - 1) + 1 if isinstance(k, int) else [d * (x - 1) + 1 for x in k]  # actual kernel-size
    if p is None:
        p = k // 2 if isinstance(k, int) else [x // 2 for x in k]  # auto-pad
    return p


class Conv(nn.Module):
    """Standard convolution with args(ch_in, ch_out, kernel, stride, padding, groups, dilation, activation)."""

    default_act = nn.SiLU()  # default activation

    def __init__(self, c1, c2, k=1, s=1, p=None, g=1, d=1, act=True):
        """Initialize Conv layer with given arguments including activation."""
        super().__init__()
        self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p, d), groups=g, dilation=d, bias=False)
        self.bn = nn.BatchNorm2d(c2)
        self.act = self.default_act if act is True else act if isinstance(act, nn.Module) else nn.Identity()

    def forward(self, x):
        """Apply convolution, batch normalization and activation to input tensor."""
        return self.act(self.bn(self.conv(x)))

    def forward_fuse(self, x):
        """Perform transposed convolution of 2D data."""
        return self.act(self.conv(x))


class PConv(nn.Module):  
    ''' Pinwheel-shaped Convolution using the Asymmetric Padding method. '''
    
    def __init__(self, c1, c2, k, s):
        super().__init__()

        # self.k = k
        p = [(k, 0, 1, 0), (0, k, 0, 1), (0, 1, k, 0), (1, 0, 0, k)]
        self.pad = [nn.ZeroPad2d(padding=(p[g])) for g in range(4)]
        self.cw = Conv(c1, c2 // 4, (1, k), s=s, p=0)
        self.ch = Conv(c1, c2 // 4, (k, 1), s=s, p=0)
        self.cat = Conv(c2, c2, 2, s=1, p=0)

    def forward(self, x):
        yw0 = self.cw(self.pad[0](x))
        yw1 = self.cw(self.pad[1](x))
        yh0 = self.ch(self.pad[2](x))
        yh1 = self.ch(self.pad[3](x))
        return self.cat(torch.cat([yw0, yw1, yh0, yh1], dim=1))


if __name__ == "__main__":
    x = torch.randn(1, 32, 64, 64).cuda()
    xm = torch.randn(1, 1, 320, 320).cuda()
    model = PConv(c1=32,c2=32,k=3,s=1).cuda()
    #model = Conv(c1=32, c2=32, k=3, s=1).cuda()
    y  = model(x)
    print(y.size())
    print("最大内存占用:", torch.cuda.max_memory_allocated() // 1024 // 1024, "MB")
    # | 模块   | 参数量 | FLOPs   | 特征提取能力       |
    # |--------|--------|---------|--------------------|
    # | Conv   | 3.7K   | 2.4G    | 各向同性特征        |
    # | PConv  | 25.6K  | 3.2G    | 方向敏感特征        |
相关推荐
段一凡-华北理工大学几秒前
工业智能体:从Codex/Claude到项目实战~系列文章06:一张蓝图看懂“工业智能体×高炉炼铁“
人工智能·claude·codex·工业智能体·高炉炼铁智能化·高炉智能体技术栈
怕浪猫3 分钟前
十个人,630 万订阅:一张 AI 学习清单里的五种老师
人工智能
JonaHu1 小时前
5分钟搭建帮你赚钱的 AI API 网站:从品牌门户到客户 Key 交付
人工智能·api·开发者·ai创业·acedatacloud
Csvn1 小时前
模型挂了全站 502?降级链让它先保住“有响应”(R04)
人工智能·aigc·agent
isNotNullX1 小时前
仓储管理最全框架:6大流程、8项指标、10个管理动作、12个常见问题
大数据·人工智能
小白菜002 小时前
AI的理解
人工智能·机器学习
科技苑2 小时前
C++ CAS与ABA问题详解,无锁编程的经典陷阱怎么解决?
c++·人工智能
DFT计算杂谈3 小时前
可DIY布里渊区图像绘制编辑器
人工智能·机器学习·语言模型·矩阵·编辑器
国科安芯3 小时前
把接口变成观测量:CANFD收发器状态可观测性驱动的星上故障检测隔离与恢复方法
大数据·人工智能·物联网·卫星·抗辐射·通信芯片·载荷