一、Yolov6网络结构
- EfficientRep Backbone
- Rep-PAN
- Efficient Decoupled Head
Yolov6的backbone不再使用Cspdarknet,而是比Rep更高效的EfficientRep。
Neck也是基于Rep和PAN搭建了Rep-PAN。
Head和YOLOX一样进行了解耦,加入了更高效结构。
YOLOv6沿用anchor-free的方式。
数据增强和YOLOv5保持一致,标签分配上和YOLOX一样采用simOTA。
引入新的边框回归损失:SIOU。
二、整体网络结构
三、代码理解
1、模型Model
class Model(nn.Module):
def forward(self, x):
x = self.backbone(x)
x = self.neck(x)
x = self.detect(x)
return x
2、network
def build_network(config, channels, num_classes, anchors, num_layers):
backbone = EfficientRep(in_channels=channels, channels_list=channels_list, num_repeats=num_repeat, block=block)
neck = RepPANNeck(channels_list=channels_list, num_repeats=num_repeat, block=block)
head_layers = build_effidehead_layer(channels_list, num_anchors, num_classes)
head = Detect(num_classes, anchors, num_layers, head_layers=head_layers)
return backbone, neck, head
3、backbone
class EfficientRep(nn.Module):
def forward(self, x):
outputs = []
x = self.stem(x)
x = self.ERBlock_2(x)
x = self.ERBlock_3(x)
outputs.append(x)
x = self.ERBlock_4(x)
outputs.append(x)
x = self.ERBlock_5(x)
outputs.append(x)
return tuple(outputs)
4、neck
class RepPANNeck(nn.Module):
def forward(self, input):
(x2, x1, x0) = input
fpn_out0 = self.reduce_layer0(x0)
upsample_feat0 = self.upsample0(fpn_out0)
f_concat_layer0 = torch.cat([upsample_feat0, x1], 1)
f_out0 = self.Rep_p4(f_concat_layer0)
fpn_out1 = self.reduce_layer1(f_out0)
upsample_feat1 = self.upsample1(fpn_out1)
f_concat_layer1 = torch.cat([upsample_feat1, x2], 1)
pan_out2 = self.Rep_p3(f_concat_layer1)
down_feat1 = self.downsample2(pan_out2)
p_concat_layer1 = torch.cat([down_feat1, fpn_out1], 1)
pan_out1 = self.Rep_n3(p_concat_layer1)
down_feat0 = self.downsample1(pan_out1)
p_concat_layer2 = torch.cat([down_feat0, fpn_out0], 1)
pan_out0 = self.Rep_n4(p_concat_layer2)
outputs = [pan_out2, pan_out1, pan_out0]
return outputs
5、head
class Detect(nn.Module):
def forward(self, x):
z = []
for i in range(self.nl):
x[i] = self.stems[i](x[i])
cls_x = x[i]
reg_x = x[i]
cls_feat = self.cls_convs[i](cls_x)
cls_output = self.cls_preds[i](cls_feat)
reg_feat = self.reg_convs[i](reg_x)
reg_output = self.reg_preds[i](reg_feat)
obj_output = self.obj_preds[i](reg_feat)
if self.training:
x[i] = torch.cat([reg_output, obj_output, cls_output], 1)
bs, _, ny, nx = x[i].shape
x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
else:
######
return x if self.training else torch.cat(z, 1)