import torch.nn as nn
class C2f(nn.Module):
"""CSP Bottleneck的快速实现,包含两个卷积层。"""
def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):
"""初始化CSP瓶颈层,参数包括输入通道数c1,输出通道数c2,重复次数n,是否使用shortcut,分组卷积数g,扩展比例e。"""
super().__init__()
self.c = int(c2 * e) # 隐藏通道数
self.cv1 = Conv(c1, 2 * self.c, 1, 1)
self.cv2 = Conv((2 + n) * self.c, c2, 1) # 可选的激活函数为FReLU(c2)
self.m = nn.ModuleList(Bottleneck(self.c, self.c, shortcut, g, k=((3, 3), (3, 3)), e=1.0) for _ in range(n))
def forward(self, x):
"""C2f层的前向传播。"""
y = list(self.cv1(x).chunk(2, 1))
y.extend(m(y[-1]) for m in self.m)
return self.cv2(torch.cat(y, 1))
def forward_split(self, x):
"""前向传播,使用split()而不是chunk()。"""
y = list(self.cv1(x).split((self.c, self.c), 1))
y.extend(m(y[-1]) for m in self.m)
return self.cv2(torch.cat(y, 1))
-
输入层 (
x
): 输入数据通过cv1
(Conv层)进行处理,将输入通道数c1
转换为2 * c
。 -
主要处理块:
- Bottleneck Blocks (
m
): 有n
个 Bottleneck 块,每个块将输入y[-1]
(cv1
的输出的后半部分)进行处理,其中y[-1]
是上一个块的输出。这些块的输出被连接到下一个块的输入。
- Bottleneck Blocks (
-
输出层:
- 最终卷积 (
cv2
): 所有Bottleneck块的输出与cv1
的输出的前半部分连接起来,然后通过cv2
进行最终卷积操作,将通道数转换为c2
。
- 最终卷积 (
这个模块的基本结构遵循了CSP块的设计,包括两个卷积层和多个Bottleneck块。具体的卷积操作和块的细节可能需要查看 Conv
和 Bottleneck
类的定义,以便更好地理解模块内部的操作。