程序运行顺序:ReResNet–ResLayer–Bottleneck
class ReResNet(BaseBackbone)
class ResLayer(nn.Sequential)
class Bottleneck(enn.EquivariantModule)
以运行train.py为例,按照程序运行流程解读。
python tools/train.py /configs/re_resnet/re_resnet50_c8_batch256.py
- List item
_in_channels = stem_channels
_out_channels = base_channels * self.expansion
for i, num_blocks in enumerate(self.stage_blocks):
stride = strides[i]
dilation = dilations[i]
res_layer = self.make_res_layer(
block=self.block,
num_blocks=num_blocks,
in_channels=_in_channels,
out_channels=_out_channels,
expansion=self.expansion,
stride=stride,
dilation=dilation,
style=self.style,
avg_down=self.avg_down,
with_cp=with_cp,
conv_cfg=conv_cfg,
norm_cfg=norm_cfg)
_in_channels = _out_channels
_out_channels *= 2
layer_name = f'layer{i + 1}'
self.add_module(layer_name, res_layer)
self.res_layers.append(layer_name)
第一轮循环,_in_channels =64,_out_channels =256,self.stage_blocks=(3,4,6,3)。
self.make_res_layer调用ResLayer,开始构建神经网络。
- ResLayer
首先判断是否下采样(downsample),对应Resnet论文中提到的短连接。
layers = []
layers.append(
block(
in_channels=in_channels,
out_channels=out_channels,
expansion=self.expansion,
stride=stride,
downsample=downsample,
conv_cfg=conv_cfg,
norm_cfg=norm_cfg,
**kwargs))
in_channels = out_channels
开始构建第一层网络,调用Bottleneck
- Bottleneck
self.norm1_name, norm1 = build_norm_layer(
norm_cfg, self.mid_channels, postfix=1)
self.norm2_name, norm2 = build_norm_layer(
norm_cfg, self.mid_channels, postfix=2)
self.norm3_name, norm3 = build_norm_layer(
norm_cfg, out_channels, postfix=3)
构建BN层
self.conv1 = build_conv_layer(
conv_cfg,
in_channels,
self.mid_channels,
kernel_size=1,
stride=self.conv1_stride,
bias=False)
self.add_module(self.norm1_name, norm1)
self.relu1 = ennReLU(self.mid_channels)
self.conv2 = build_conv_layer(
conv_cfg,
self.mid_channels,
self.mid_channels,
kernel_size=3,
stride=self.conv2_stride,
padding=dilation,
dilation=dilation,
bias=False)
self.add_module(self.norm2_name, norm2)
self.relu2 = ennReLU(self.mid_channels)
self.conv3 = build_conv_layer(
conv_cfg,
self.mid_channels,
out_channels,
kernel_size=1,
bias=False)
self.add_module(self.norm3_name, norm3)
self.relu3 = ennReLU(out_channels)
构建卷积层,一共三层卷积,每一层都是由卷积+BN+Relu构成。
- ResLayer
卷积层构建完后,append到layers里面,开始生成剩下num_blocks-1个神经网络,这里对应Resnet论文中残差提取特征。然后调用Bottleneck生成卷积层。
for i in range(1, num_blocks):
layers.append(
block(
in_channels=in_channels,
out_channels=out_channels,
expansion=self.expansion,
stride=1,
conv_cfg=conv_cfg,
norm_cfg=norm_cfg,
**kwargs))
- 网络全貌
生成4个layer
layer3是6,对应self.stage_blocks=(3,4,6,3)
layer3的第一层,包含三个卷积三个BN,一个下采样层。