CoolFace
Apppublic

josedolot/HybridNet_Demo2

sourceHugging Facemitupdated 5y agoView on Hugging Face
2likes
backbone.py144 linesDownload Raw Back to root
1import torch2from torch import nn3import timm4 5from hybridnets.model import BiFPN, Regressor, Classifier, BiFPNDecoder6from utils.utils import Anchors7from hybridnets.model import SegmentationHead8 9from encoders import get_encoder10 11class HybridNetsBackbone(nn.Module):12    def __init__(self, num_classes=80, compound_coef=0, seg_classes=1, backbone_name=None, **kwargs):13        super(HybridNetsBackbone, self).__init__()14        self.compound_coef = compound_coef15 16        self.seg_classes = seg_classes17 18        self.backbone_compound_coef = [0, 1, 2, 3, 4, 5, 6, 6, 7]19        self.fpn_num_filters = [64, 88, 112, 160, 224, 288, 384, 384, 384]20        self.fpn_cell_repeats = [3, 4, 5, 6, 7, 7, 8, 8, 8]21        self.input_sizes = [512, 640, 768, 896, 1024, 1280, 1280, 1536, 1536]22        self.box_class_repeats = [3, 3, 3, 4, 4, 4, 5, 5, 5]23        self.pyramid_levels = [5, 5, 5, 5, 5, 5, 5, 5, 6]24        self.anchor_scale = [1.25,1.25,1.25,1.25,1.25,1.25,1.25,1.25,1.25,]25        self.aspect_ratios = kwargs.get('ratios', [(1.0, 1.0), (1.4, 0.7), (0.7, 1.4)])26        self.num_scales = len(kwargs.get('scales', [2 ** 0, 2 ** (1.0 / 3.0), 2 ** (2.0 / 3.0)]))27        conv_channel_coef = {28            # the channels of P3/P4/P5.29            0: [40, 112, 320],30            1: [40, 112, 320],31            2: [48, 120, 352],32            3: [48, 136, 384],33            4: [56, 160, 448],34            5: [64, 176, 512],35            6: [72, 200, 576],36            7: [72, 200, 576],37            8: [80, 224, 640],38        }39 40        num_anchors = len(self.aspect_ratios) * self.num_scales41 42        self.bifpn = nn.Sequential(43            *[BiFPN(self.fpn_num_filters[self.compound_coef],44                    conv_channel_coef[compound_coef],45                    True if _ == 0 else False,46                    attention=True if compound_coef < 6 else False,47                    use_p8=compound_coef > 7)48              for _ in range(self.fpn_cell_repeats[compound_coef])])49 50        self.num_classes = num_classes51        self.regressor = Regressor(in_channels=self.fpn_num_filters[self.compound_coef], num_anchors=num_anchors,52                                   num_layers=self.box_class_repeats[self.compound_coef],53                                   pyramid_levels=self.pyramid_levels[self.compound_coef])54 55        '''Modified by Dat Vu'''56        # self.decoder = DecoderModule()57        self.bifpndecoder = BiFPNDecoder(pyramid_channels=self.fpn_num_filters[self.compound_coef])58 59        self.segmentation_head = SegmentationHead(60            in_channels=64,61            out_channels=self.seg_classes+1 if self.seg_classes > 1 else self.seg_classes,62            activation='softmax2d' if self.seg_classes > 1 else 'sigmoid',63            kernel_size=1,64            upsampling=4,65        )66 67        self.classifier = Classifier(in_channels=self.fpn_num_filters[self.compound_coef], num_anchors=num_anchors,68                                     num_classes=num_classes,69                                     num_layers=self.box_class_repeats[self.compound_coef],70                                     pyramid_levels=self.pyramid_levels[self.compound_coef])71 72        self.anchors = Anchors(anchor_scale=self.anchor_scale[compound_coef],73                               pyramid_levels=(torch.arange(self.pyramid_levels[self.compound_coef]) + 3).tolist(),74                               **kwargs)75 76        if backbone_name:77            # Use timm to create another backbone that you prefer78            # https://github.com/rwightman/pytorch-image-models79            self.encoder = timm.create_model(backbone_name, pretrained=True, features_only=True, out_indices=(2,3,4))  # P3,P4,P580        else:81            # EfficientNet_Pytorch82            self.encoder = get_encoder(83                'efficientnet-b' + str(self.backbone_compound_coef[compound_coef]),84                in_channels=3,85                depth=5,86                weights='imagenet',87            )88    89        self.initialize_decoder(self.bifpndecoder)90        self.initialize_head(self.segmentation_head)91        self.initialize_decoder(self.bifpn)92 93    def freeze_bn(self):94        for m in self.modules():95            if isinstance(m, nn.BatchNorm2d):96                m.eval()97 98    def forward(self, inputs):99        max_size = inputs.shape[-1]100 101        # p1, p2, p3, p4, p5 = self.backbone_net(inputs)102        p2, p3, p4, p5 = self.encoder(inputs)[-4:]  # self.backbone_net(inputs)103 104        features = (p3, p4, p5)105 106        features = self.bifpn(features)107        108        p3,p4,p5,p6,p7 = features109        110        outputs = self.bifpndecoder((p2,p3,p4,p5,p6,p7))111 112        segmentation = self.segmentation_head(outputs)113        114        regression = self.regressor(features)115        classification = self.classifier(features)116        anchors = self.anchors(inputs, inputs.dtype)117 118        return features, regression, classification, anchors, segmentation119    120    def initialize_decoder(self, module):121        for m in module.modules():122 123            if isinstance(m, nn.Conv2d):124                nn.init.kaiming_uniform_(m.weight, mode="fan_in", nonlinearity="relu")125                if m.bias is not None:126                    nn.init.constant_(m.bias, 0)127 128            elif isinstance(m, nn.BatchNorm2d):129                nn.init.constant_(m.weight, 1)130                nn.init.constant_(m.bias, 0)131 132            elif isinstance(m, nn.Linear):133                nn.init.xavier_uniform_(m.weight)134                if m.bias is not None:135                    nn.init.constant_(m.bias, 0)136 137 138    def initialize_head(self, module):139        for m in module.modules():140            if isinstance(m, (nn.Linear, nn.Conv2d)):141                nn.init.xavier_uniform_(m.weight)142                if m.bias is not None:143                    nn.init.constant_(m.bias, 0)144