forked from AIFengheshu/Plug-play-modules
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path(AAAI 2025) PConv.py
More file actions
80 lines (60 loc) · 3.06 KB
/
(AAAI 2025) PConv.py
File metadata and controls
80 lines (60 loc) · 3.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import torch
import torch.nn as nn
# 论文题目:Pinwheel-shaped Convolution and Scale-based Dynamic Loss for Infrared Small Target Detection
# 中文题目:风车形状的卷积和基于尺度的动态损失用于红外小目标检测
# 论文链接:https://arxiv.org/pdf/2412.16986
# 官方github:https://github.com/JN-Yang/PConv-SDloss-Data
# 所属机构:西南科技大学信息与工程学院,南京理工大学电子与光学工程学院
# 代码整理:微信公众号《AI缝合术》
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 Pinwheel_shapedConv(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__":
# 将模块移动到 GPU(如果可用)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 创建测试输入张量 (batch_size, channels, height, width)
x = torch.randn(1, 32, 256, 256).to(device)
# 初始化 pconv 模块
pconv = Pinwheel_shapedConv(c1=32, c2=64, k=3, s=1)
print(pconv)
pconv = pconv.to(device)
# 前向传播
output = pconv(x)
# 打印输入和输出张量的形状
print("输入张量形状:", x.shape)
print("输出张量形状:", output.shape)