前言
今天我们基于CBNetV2: A Composite Backbone Network Architecture for Object Detection这篇文章来复现其中的复合骨干部分。类似于CBNetV2类的网络相当于爸妈模型变宽了,重复利用特征,对目标检测有一定的优势。
模型结构
模型结构如图所示,方框中的我们就先不进行复现了,主要复现这种复合结构。
这种复合结构有两种一种是Backbone 1,另一种Backbone K
代码实现
在Backbone 1中无输入递归结构,输出分别是x2到x5的特征,所以结构可以表示为:
class First_Backbone(nn.Module): #定义上采样函数
def __init__(self, in_channels, in_channel1, out_channels, bilinear=False):
super().__init__()
self.layer1 = Conv(in_channels, out_channels)
self.layer2 = Down(out_channels, out_channels)
self.layer3 = Down(out_channels, out_channels)
self.layer4 = Down(out_channels, out_channels)
def forward(self, x1): #x是设置的参数,代表输入数据
x2 = self.layer1(x1)
x3 = self.layer2(x2)
x4 = self.layer3(x3)
x5 = self.layer4(x4)
return x2, x3, x4, x5
N Backbone比较复杂,他需要前面的x2到x5的特征,并且通过反卷积复原:
class N_Backbone(nn.Module): #定义上采样函数
def __init__(self, in_channels, in_channel1, out_channels, bilinear=False):
super().__init__()
self.layer1 = Conv(in_channels, out_channels)
self.layer2 = Down(out_channels, out_channels)
self.layer3 = Down(out_channels, out_channels)
self.layer4 = Down(out_channels, out_channels)
self.layer1_1 = Up(in_channels, out_channels)
self.layer2_1 = Up(out_channels, out_channels)
self.layer3_1 = Up(out_channels, out_channels)
def forward(self, x1, x2, x3, x4, x5): #x是设置的参数,代表输入数据
x2_1 = self.layer1(x1) + x2 + self.layer1_1(x3) + self.layer2_1(self.layer1_1(x4)) + self.layer3_1(self.layer2_1(self.layer1_1(x5)))
x3_1 = self.layer1(x2_1) + x3 +self.layer2_1(x4) + self.layer3_1(self.layer2_1(x5))
x4_1 = self.layer1(x3_1) + x4 + self.layer3_1(x5)
x5_1 = self.layer1(x4_1) + x5
return x1, x2, x3, x4
其中Down,Up,和Conv函数如下:
mport torch
import torch.nn as nn
class Conv(nn.Module): #定义函数DoubleConv
# 卷积+ReLU函数+卷积+ReLU函数
def __init__(self, in_channels, out_channels): ##in_channels, out_channels是设置的两个参数
super().__init__()
self.conv = nn.Sequential( ##nn.Sequential:封装函数
nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1), ####卷积(输入channel,输出channel,卷积核大小3(一般取3/5,根据GPU计算力),卷积前扩张维度1)
#nn.BatchNorm2d(out_channels),
nn.ReLU(inplace=True), #####激活函数,增强模型表达能力
)
def forward(self, x): #x是设置的参数,代表输入数据
x = self.conv(x)
return x
class Down(nn.Module): #定义下采样函数,给数据降维
def __init__(self, in_channels, out_channels):
super().__init__()
self.maxpool_conv = nn.Sequential(
nn.MaxPool2d(2),
Conv(in_channels, out_channels)
)
def forward(self, x):
return self.maxpool_conv(x) ####池化操作
class Up(nn.Module): #定义上采样函数
def __init__(self, in_channels, in_channel1, out_channels, bilinear=False):
super().__init__()
self.up = nn.ConvTranspose2d(in_channels, in_channels, kernel_size=3, stride=2, padding=1, output_padding=1)
def forward(self, x1): #x是设置的参数,代表输入数据F
# 四维batch, channel, height, width
x1 = self.up(x1) ######反卷积
return x