|
|
@@ -8,47 +8,62 @@ except:
|
|
|
from yolox_basic import Conv, CSPBlock
|
|
|
from yolox_neck import SPPF
|
|
|
|
|
|
-model_urls = {
|
|
|
- "cspdarknet_nano": "https://github.com/yjh0410/image_classification_pytorch/releases/download/weight/cspdarknet_nano.pth",
|
|
|
- "cspdarknet_small": "https://github.com/yjh0410/image_classification_pytorch/releases/download/weight/cspdarknet_small.pth",
|
|
|
- "cspdarknet_medium": "https://github.com/yjh0410/image_classification_pytorch/releases/download/weight/cspdarknet_medium.pth",
|
|
|
- "cspdarknet_large": "https://github.com/yjh0410/image_classification_pytorch/releases/download/weight/cspdarknet_large.pth",
|
|
|
- "cspdarknet_huge": None,
|
|
|
-}
|
|
|
|
|
|
# CSPDarkNet
|
|
|
class CSPDarkNet(nn.Module):
|
|
|
def __init__(self, depth=1.0, width=1.0, act_type='silu', norm_type='BN', depthwise=False):
|
|
|
super(CSPDarkNet, self).__init__()
|
|
|
- self.feat_dims = [int(256*width), int(512*width), int(1024*width)]
|
|
|
-
|
|
|
- # P1
|
|
|
- self.layer_1 = Conv(3, int(64*width), k=6, p=2, s=2, act_type=act_type, norm_type=norm_type, depthwise=depthwise)
|
|
|
-
|
|
|
- # P2
|
|
|
+ self.feat_dims = [round(64 * width), round(128 * width), round(256 * width), round(512 * width), round(1024 * width)]
|
|
|
+ # P1/2
|
|
|
+ self.layer_1 = Conv(3, self.feat_dims[0], k=6, p=2, s=2, act_type=act_type, norm_type=norm_type, depthwise=depthwise)
|
|
|
+ # P2/4
|
|
|
self.layer_2 = nn.Sequential(
|
|
|
- Conv(int(64*width), int(128*width), k=3, p=1, s=2, act_type=act_type, norm_type=norm_type, depthwise=depthwise),
|
|
|
- CSPBlock(int(128*width), int(128*width), expand_ratio=0.5, nblocks=int(3*depth),
|
|
|
- shortcut=True, act_type=act_type, norm_type=norm_type, depthwise=depthwise)
|
|
|
+ Conv(self.feat_dims[0], self.feat_dims[1], k=3, p=1, s=2, act_type=act_type, norm_type=norm_type, depthwise=depthwise),
|
|
|
+ CSPBlock(in_dim = self.feat_dims[1],
|
|
|
+ out_dim = self.feat_dims[1],
|
|
|
+ expand_ratio = 0.5,
|
|
|
+ nblocks = round(3*depth),
|
|
|
+ shortcut = True,
|
|
|
+ act_type = act_type,
|
|
|
+ norm_type = norm_type,
|
|
|
+ depthwise = depthwise)
|
|
|
)
|
|
|
- # P3
|
|
|
+ # P3/8
|
|
|
self.layer_3 = nn.Sequential(
|
|
|
- Conv(int(128*width), int(256*width), k=3, p=1, s=2, act_type=act_type, norm_type=norm_type, depthwise=depthwise),
|
|
|
- CSPBlock(int(256*width), int(256*width), expand_ratio=0.5, nblocks=int(9*depth),
|
|
|
- shortcut=True, act_type=act_type, norm_type=norm_type, depthwise=depthwise)
|
|
|
+ Conv(self.feat_dims[1], self.feat_dims[2], k=3, p=1, s=2, act_type=act_type, norm_type=norm_type, depthwise=depthwise),
|
|
|
+ CSPBlock(in_dim = self.feat_dims[2],
|
|
|
+ out_dim = self.feat_dims[2],
|
|
|
+ expand_ratio = 0.5,
|
|
|
+ nblocks = round(9*depth),
|
|
|
+ shortcut = True,
|
|
|
+ act_type = act_type,
|
|
|
+ norm_type = norm_type,
|
|
|
+ depthwise = depthwise)
|
|
|
)
|
|
|
- # P4
|
|
|
+ # P4/16
|
|
|
self.layer_4 = nn.Sequential(
|
|
|
- Conv(int(256*width), int(512*width), k=3, p=1, s=2, act_type=act_type, norm_type=norm_type, depthwise=depthwise),
|
|
|
- CSPBlock(int(512*width), int(512*width), expand_ratio=0.5, nblocks=int(9*depth),
|
|
|
- shortcut=True, act_type=act_type, norm_type=norm_type, depthwise=depthwise)
|
|
|
+ Conv(self.feat_dims[2], self.feat_dims[3], k=3, p=1, s=2, act_type=act_type, norm_type=norm_type, depthwise=depthwise),
|
|
|
+ CSPBlock(in_dim = self.feat_dims[3],
|
|
|
+ out_dim = self.feat_dims[3],
|
|
|
+ expand_ratio = 0.5,
|
|
|
+ nblocks = round(9*depth),
|
|
|
+ shortcut = True,
|
|
|
+ act_type = act_type,
|
|
|
+ norm_type = norm_type,
|
|
|
+ depthwise = depthwise)
|
|
|
)
|
|
|
- # P5
|
|
|
+ # P5/32
|
|
|
self.layer_5 = nn.Sequential(
|
|
|
- Conv(int(512*width), int(1024*width), k=3, p=1, s=2, act_type=act_type, norm_type=norm_type, depthwise=depthwise),
|
|
|
- SPPF(int(1024*width), int(1024*width), expand_ratio=0.5),
|
|
|
- CSPBlock(int(1024*width), int(1024*width), expand_ratio=0.5, nblocks=int(3*depth),
|
|
|
- shortcut=True, act_type=act_type, norm_type=norm_type, depthwise=depthwise)
|
|
|
+ Conv(self.feat_dims[3], self.feat_dims[4], k=3, p=1, s=2, act_type=act_type, norm_type=norm_type, depthwise=depthwise),
|
|
|
+ SPPF(self.feat_dims[4], self.feat_dims[4], expand_ratio=0.5),
|
|
|
+ CSPBlock(in_dim = self.feat_dims[4],
|
|
|
+ out_dim = self.feat_dims[4],
|
|
|
+ expand_ratio = 0.5,
|
|
|
+ nblocks = round(3*depth),
|
|
|
+ shortcut = True,
|
|
|
+ act_type = act_type,
|
|
|
+ norm_type = norm_type,
|
|
|
+ depthwise = depthwise)
|
|
|
)
|
|
|
|
|
|
|
|
|
@@ -65,57 +80,10 @@ class CSPDarkNet(nn.Module):
|
|
|
|
|
|
|
|
|
# ---------------------------- Functions ----------------------------
|
|
|
-## load pretrained weight
|
|
|
-def load_weight(model, model_name):
|
|
|
- # load weight
|
|
|
- print('Loading pretrained weight ...')
|
|
|
- url = model_urls[model_name]
|
|
|
- if url is not None:
|
|
|
- checkpoint = torch.hub.load_state_dict_from_url(
|
|
|
- url=url, map_location="cpu", check_hash=True)
|
|
|
- # checkpoint state dict
|
|
|
- checkpoint_state_dict = checkpoint.pop("model")
|
|
|
- # model state dict
|
|
|
- model_state_dict = model.state_dict()
|
|
|
- # check
|
|
|
- for k in list(checkpoint_state_dict.keys()):
|
|
|
- if k in model_state_dict:
|
|
|
- shape_model = tuple(model_state_dict[k].shape)
|
|
|
- shape_checkpoint = tuple(checkpoint_state_dict[k].shape)
|
|
|
- if shape_model != shape_checkpoint:
|
|
|
- checkpoint_state_dict.pop(k)
|
|
|
- else:
|
|
|
- checkpoint_state_dict.pop(k)
|
|
|
- print(k)
|
|
|
-
|
|
|
- model.load_state_dict(checkpoint_state_dict)
|
|
|
- else:
|
|
|
- print('No pretrained for {}'.format(model_name))
|
|
|
-
|
|
|
- return model
|
|
|
-
|
|
|
-
|
|
|
## build CSPDarkNet
|
|
|
-def build_backbone(cfg, pretrained=False):
|
|
|
- """Constructs a darknet-53 model.
|
|
|
- Args:
|
|
|
- pretrained (bool): If True, returns a model pre-trained on ImageNet
|
|
|
- """
|
|
|
+def build_backbone(cfg):
|
|
|
backbone = CSPDarkNet(cfg['depth'], cfg['width'], cfg['bk_act'], cfg['bk_norm'], cfg['bk_dpw'])
|
|
|
- feat_dims = backbone.feat_dims
|
|
|
-
|
|
|
- # check whether to load imagenet pretrained weight
|
|
|
- if pretrained:
|
|
|
- if cfg['width'] == 0.25 and cfg['depth'] == 0.34:
|
|
|
- backbone = load_weight(backbone, model_name='cspdarknet_nano')
|
|
|
- elif cfg['width'] == 0.5 and cfg['depth'] == 0.34:
|
|
|
- backbone = load_weight(backbone, model_name='cspdarknet_small')
|
|
|
- elif cfg['width'] == 0.75 and cfg['depth'] == 0.67:
|
|
|
- backbone = load_weight(backbone, model_name='cspdarknet_medium')
|
|
|
- elif cfg['width'] == 1.0 and cfg['depth'] == 1.0:
|
|
|
- backbone = load_weight(backbone, model_name='cspdarknet_large')
|
|
|
- elif cfg['width'] == 1.25 and cfg['depth'] == 1.34:
|
|
|
- backbone = load_weight(backbone, model_name='cspdarknet_huge')
|
|
|
+ feat_dims = backbone.feat_dims[-3:]
|
|
|
|
|
|
return backbone, feat_dims
|
|
|
|
|
|
@@ -124,7 +92,6 @@ if __name__ == '__main__':
|
|
|
import time
|
|
|
from thop import profile
|
|
|
cfg = {
|
|
|
- 'pretrained': False,
|
|
|
'bk_act': 'lrelu',
|
|
|
'bk_norm': 'BN',
|
|
|
'bk_dpw': False,
|