|
|
@@ -1,3 +1,4 @@
|
|
|
+from typing import List
|
|
|
import numpy as np
|
|
|
import torch
|
|
|
import torch.nn as nn
|
|
|
@@ -156,11 +157,12 @@ class YoloBottleneck(nn.Module):
|
|
|
def __init__(self,
|
|
|
in_dim,
|
|
|
out_dim,
|
|
|
- expand_ratio=0.5,
|
|
|
- shortcut=False,
|
|
|
- act_type='silu',
|
|
|
- norm_type='BN',
|
|
|
- depthwise=False):
|
|
|
+ kernel_sizes :List[int] = [3, 3],
|
|
|
+ expand_ratio :float = 0.5,
|
|
|
+ shortcut :bool = False,
|
|
|
+ act_type :str = 'silu',
|
|
|
+ norm_type :str = 'BN',
|
|
|
+ depthwise :bool = False):
|
|
|
super(YoloBottleneck, self).__init__()
|
|
|
# ------------------ Basic parameters ------------------
|
|
|
self.in_dim = in_dim
|
|
|
@@ -168,8 +170,8 @@ class YoloBottleneck(nn.Module):
|
|
|
self.inter_dim = int(out_dim * expand_ratio)
|
|
|
self.shortcut = shortcut and in_dim == out_dim
|
|
|
# ------------------ Network parameters ------------------
|
|
|
- self.cv1 = Conv(in_dim, self.inter_dim, k=1, norm_type=norm_type, act_type=act_type)
|
|
|
- self.cv2 = Conv(self.inter_dim, out_dim, k=3, p=1, norm_type=norm_type, act_type=act_type, depthwise=depthwise)
|
|
|
+ self.cv1 = Conv(in_dim, self.inter_dim, k=kernel_sizes[0], p=kernel_sizes[0]//2, norm_type=norm_type, act_type=act_type, depthwise=depthwise)
|
|
|
+ self.cv2 = Conv(self.inter_dim, out_dim, k=kernel_sizes[1], p=kernel_sizes[1]//2, norm_type=norm_type, act_type=act_type, depthwise=depthwise)
|
|
|
|
|
|
def forward(self, x):
|
|
|
h = self.cv2(self.cv1(x))
|
|
|
@@ -180,23 +182,23 @@ class YoloBottleneck(nn.Module):
|
|
|
# ---------------------------- Base Modules ----------------------------
|
|
|
## ELAN Stage of Backbone
|
|
|
class ELAN_Stage(nn.Module):
|
|
|
- def __init__(self, in_dim, out_dim, squeeze_ratio :float=0.5, branch_depth :int=1, shortcut=False, act_type='silu', norm_type='BN', depthwise=False):
|
|
|
+ def __init__(self, in_dim, out_dim, expand_ratio :float=0.5, branch_depth :int=1, shortcut=False, act_type='silu', norm_type='BN', depthwise=False):
|
|
|
super().__init__()
|
|
|
# ----------- Basic Parameters -----------
|
|
|
self.in_dim = in_dim
|
|
|
self.out_dim = out_dim
|
|
|
- self.inter_dim = round(in_dim * squeeze_ratio)
|
|
|
- self.squeeze_ratio = squeeze_ratio
|
|
|
+ self.inter_dim = round(in_dim * expand_ratio)
|
|
|
+ self.expand_ratio = expand_ratio
|
|
|
self.branch_depth = branch_depth
|
|
|
# ----------- Network Parameters -----------
|
|
|
self.cv1 = Conv(in_dim, self.inter_dim, k=1, act_type=act_type, norm_type=norm_type)
|
|
|
self.cv2 = Conv(in_dim, self.inter_dim, k=1, act_type=act_type, norm_type=norm_type)
|
|
|
self.cv3 = nn.Sequential(*[
|
|
|
- YoloBottleneck(self.inter_dim, self.inter_dim, 1.0, shortcut, act_type, norm_type, depthwise)
|
|
|
+ YoloBottleneck(self.inter_dim, self.inter_dim, [1, 3], 1.0, shortcut, act_type, norm_type, depthwise)
|
|
|
for _ in range(branch_depth)
|
|
|
])
|
|
|
self.cv4 = nn.Sequential(*[
|
|
|
- YoloBottleneck(self.inter_dim, self.inter_dim, 1.0, shortcut, act_type, norm_type, depthwise)
|
|
|
+ YoloBottleneck(self.inter_dim, self.inter_dim, [1, 3], 1.0, shortcut, act_type, norm_type, depthwise)
|
|
|
for _ in range(branch_depth)
|
|
|
])
|
|
|
## output
|
|
|
@@ -217,17 +219,12 @@ class DSBlock(nn.Module):
|
|
|
super().__init__()
|
|
|
self.in_dim = in_dim
|
|
|
self.out_dim = out_dim
|
|
|
- self.inter_dim = out_dim // 2
|
|
|
# branch-1
|
|
|
- self.maxpool = nn.Sequential(
|
|
|
- Conv(in_dim, self.inter_dim, k=1, act_type=act_type, norm_type=norm_type),
|
|
|
- nn.MaxPool2d((2, 2), 2)
|
|
|
- )
|
|
|
+ self.maxpool = nn.MaxPool2d((2, 2), 2)
|
|
|
# branch-2
|
|
|
- self.ds_conv = nn.Sequential(
|
|
|
- Conv(in_dim, self.inter_dim, k=1, act_type=act_type, norm_type=norm_type),
|
|
|
- Conv(self.inter_dim, self.inter_dim, k=3, p=1, s=2, act_type=act_type, norm_type=norm_type, depthwise=depthwise)
|
|
|
- )
|
|
|
+ self.ds_conv = Conv(in_dim, in_dim, k=3, p=1, s=2, act_type=act_type, norm_type=norm_type, depthwise=depthwise)
|
|
|
+ # output
|
|
|
+ self.out_conv = Conv(in_dim*2, out_dim, k=1, act_type=act_type, norm_type=norm_type, depthwise=depthwise)
|
|
|
|
|
|
|
|
|
def forward(self, x):
|
|
|
@@ -236,7 +233,7 @@ class DSBlock(nn.Module):
|
|
|
# branch-2
|
|
|
x2 = self.ds_conv(x)
|
|
|
# out-proj
|
|
|
- out = torch.cat([x1, x2], dim=1)
|
|
|
+ out = self.out_conv(torch.cat([x1, x2], dim=1))
|
|
|
|
|
|
return out
|
|
|
|
|
|
@@ -247,7 +244,7 @@ def build_fpn_block(cfg, in_dim, out_dim):
|
|
|
if cfg['fpn_core_block'] == 'elan_block':
|
|
|
layer = ELAN_Stage(in_dim = in_dim,
|
|
|
out_dim = out_dim,
|
|
|
- squeeze_ratio = cfg['fpn_squeeze_ratio'],
|
|
|
+ expand_ratio = cfg['fpn_expand_ratio'],
|
|
|
branch_depth = round(3 * cfg['depth']),
|
|
|
shortcut = False,
|
|
|
act_type = cfg['fpn_act'],
|