Ejemplo n.º 1
0
    def __init__(self, config: EfficientNetConfig):
        super(EfficientNet, self).__init__()
        bef_filter_num = round_filters(32, config.width, 8)
        self.modules = [
            nn.Sequential(
                nn.Conv2d(in_channels=3,
                          out_channels=bef_filter_num,
                          kernel_size=3,
                          padding=1,
                          stride=2,
                          bias=False),
                nn.BatchNorm2d(num_features=bef_filter_num,
                               momentum=config.batch_norm_momentum), nn.SiLU())
        ]
        sum_layers = 0
        for k in self.baseline:
            k[0] = round_filters(k[0], config.width, 8)
            k[4] = round_repeats(k[4], config.depth)
            sum_layers += k[4]

        cnt_layers = 0
        for k in self.baseline:
            channels, stride, kernel_size, expansion_ratio, num_layers = k
            cur_dropout = (cnt_layers / sum_layers) * config.dropout_rate
            block_conf = MBConvConfig(in_channels=bef_filter_num,
                                      out_channels=channels,
                                      kernel_size=kernel_size,
                                      stride=stride,
                                      expansion_ratio=expansion_ratio,
                                      se_ratio=0.25,
                                      dropout_rate=cur_dropout)
            self.modules.append(MBConv(block_conf, config))
            cnt_layers += 1
            if num_layers > 1:
                new_conf = copy.deepcopy(block_conf)
                new_conf.get_zero()
                for _ in range(num_layers - 1):
                    cur_dropout = (cnt_layers /
                                   sum_layers) * config.dropout_rate
                    new_conf.dropout_rate = cur_dropout
                    self.modules.append(MBConv(new_conf, config))
                    cnt_layers += 1
            bef_filter_num = channels

        # End of Conv
        final_channel = round_filters(1280,
                                      width=config.width,
                                      depth_divisor=8)
        self.modules.append(
            nn.Sequential(
                nn.Conv2d(in_channels=bef_filter_num,
                          out_channels=final_channel,
                          kernel_size=1,
                          bias=False),
                nn.BatchNorm2d(num_features=final_channel,
                               momentum=config.batch_norm_momentum), nn.SiLU(),
                nn.AdaptiveAvgPool2d(1), nn.Dropout(config.dropout_rate),
                nn.Flatten(), nn.Linear(final_channel, config.num_classes)))
        self.model = nn.Sequential(*self.modules)
Ejemplo n.º 2
0
    def __init__(self, blocks_args=None, global_params=None):
        super().__init__()
        assert isinstance(blocks_args, list), 'blocks_args should be a list'
        assert len(blocks_args) > 0, 'block args must be greater than 0'
        self._global_params = global_params
        self._blocks_args = blocks_args

        # Batch norm parameters
        bn_mom = 1 - self._global_params.batch_norm_momentum
        bn_eps = self._global_params.batch_norm_epsilon

        # Get stem static or dynamic convolution depending on image size
        image_size = global_params.image_size
        Conv2d = get_same_padding_conv2d(image_size=image_size)

        # Stem
        in_channels = 3  # rgb
        out_channels = round_filters(32, self._global_params)  # number of output channels
        self._conv_stem = Conv2d(in_channels, out_channels, kernel_size=3, stride=2, bias=False)
        self._bn0 = nn.BatchNorm2d(num_features=out_channels, momentum=bn_mom, eps=bn_eps)
        image_size = calculate_output_image_size(image_size, 2)

        # Build blocks
        self._blocks = nn.ModuleList([])
        for block_args in self._blocks_args:

            # Update block input and output filters based on depth multiplier.
            block_args = block_args._replace(
                input_filters=round_filters(block_args.input_filters, self._global_params),
                output_filters=round_filters(block_args.output_filters, self._global_params),
                num_repeat=round_repeats(block_args.num_repeat, self._global_params)
            )

            # The first block needs to take care of stride and filter size increase.
            self._blocks.append(MBConvBlock(block_args, self._global_params, image_size=image_size))
            image_size = calculate_output_image_size(image_size, block_args.stride)
            if block_args.num_repeat > 1: # modify block_args to keep same output size
                block_args = block_args._replace(input_filters=block_args.output_filters, stride=1)
            for _ in range(block_args.num_repeat - 1):
                self._blocks.append(MBConvBlock(block_args, self._global_params, image_size=image_size))
                # image_size = calculate_output_image_size(image_size, block_args.stride)  # stride = 1

        # Head
        in_channels = block_args.output_filters  # output of final block
        out_channels = round_filters(1280, self._global_params)
        Conv2d = get_same_padding_conv2d(image_size=image_size)
        self._conv_head = Conv2d(in_channels, out_channels, kernel_size=1, bias=False)
        self._bn1 = nn.BatchNorm2d(num_features=out_channels, momentum=bn_mom, eps=bn_eps)

        # Final linear layer
        self._avg_pooling = nn.AdaptiveAvgPool2d(1)
        self._dropout = nn.Dropout(self._global_params.dropout_rate)
        self._fc = nn.Linear(out_channels, self._global_params.num_classes)
        self._swish = MemoryEfficientSwish()
Ejemplo n.º 3
0
    def _change_in_channels(self, in_channels):
        """Adjust model's first convolution layer to in_channels, if in_channels not equals 3.

        Args:
            in_channels (int): Input data's channel number.
        """
        if in_channels != 3:
            Conv2d = get_same_padding_conv2d(image_size = self._global_params.image_size)
            out_channels = round_filters(32, self._global_params)
            self._conv_stem = Conv2d(in_channels, out_channels, kernel_size=3, stride=2, bias=False)
Ejemplo n.º 4
0
 def from_pretrained(cls, model_name, num_classes=1000, in_channels=3):
     model = cls.from_name(model_name,
                           override_params={'num_classes': num_classes})
     load_pretrained_weights(model,
                             model_name,
                             load_fc=(num_classes == 1000))
     if in_channels != 3:
         Conv2d = get_same_padding_conv2d(
             image_size=model._global_params.image_size)
         out_channels = round_filters(32, model._global_params)
         model._conv_stem = Conv2d(in_channels,
                                   out_channels,
                                   kernel_size=3,
                                   stride=2,
                                   bias=False)
     return model
Ejemplo n.º 5
0
    def __init__(self,
                 width_coefficient,
                 depth_coefficient,
                 dropout_rate,
                 drop_connect_rate=0.2):
        super(EfficientNet, self).__init__()
        print("EFFICIENTNET CLASS __INIT__")
        self.conv1 = Conv2D(filters=round_filters(32, width_coefficient),
                            kernel_size=(3, 3),
                            strides=2,
                            padding='same',
                            use_bias=False)
        self.bn1 = BatchNormalization()

        self.block1 = MBConvBlock(
            in_channels=round_filters(32, width_coefficient),
            out_channels=round_filters(16, width_coefficient),
            layer=round_repeats(1, depth_coefficient),
            stride=1,
            expansion_factor=1,
            k=3,
            drop_connect_rate=drop_connect_rate)
        self.block2 = MBConvBlock(
            in_channels=round_filters(16, width_coefficient),
            out_channels=round_filters(24, width_coefficient),
            layer=round_repeats(2, depth_coefficient),
            stride=2,
            expansion_factor=6,
            k=3,
            drop_connect_rate=drop_connect_rate)
        self.block3 = MBConvBlock(
            in_channels=round_filters(24, width_coefficient),
            out_channels=round_filters(40, width_coefficient),
            layer=round_repeats(2, depth_coefficient),
            stride=2,
            expansion_factor=6,
            k=5,
            drop_connect_rate=drop_connect_rate)
        self.block4 = MBConvBlock(
            in_channels=round_filters(40, width_coefficient),
            out_channels=round_filters(80, width_coefficient),
            layer=round_repeats(3, depth_coefficient),
            stride=2,
            expansion_factor=6,
            k=3,
            drop_connect_rate=drop_connect_rate)
        self.block5 = MBConvBlock(
            in_channels=round_filters(80, width_coefficient),
            out_channels=round_filters(112, width_coefficient),
            layer=round_repeats(3, depth_coefficient),
            stride=1,
            expansion_factor=6,
            k=5,
            drop_connect_rate=drop_connect_rate)
        self.block6 = MBConvBlock(
            in_channels=round_filters(112, width_coefficient),
            out_channels=round_filters(192, width_coefficient),
            layer=round_repeats(4, depth_coefficient),
            stride=2,
            expansion_factor=6,
            k=5,
            drop_connect_rate=drop_connect_rate)
        self.block7 = MBConvBlock(
            in_channels=round_filters(192, width_coefficient),
            out_channels=round_filters(320, width_coefficient),
            layer=round_repeats(1, depth_coefficient),
            stride=1,
            expansion_factor=6,
            k=3,
            drop_connect_rate=drop_connect_rate)

        self.conv2 = Conv2D(filters=round_filters(1280, width_coefficient),
                            kernel_size=(1, 1),
                            strides=1,
                            padding='same',
                            use_bias=False)
        self.bn2 = BatchNormalization()
        self.pool = GlobalAveragePooling2D()
        self.dropout = Dropout(rate=dropout_rate)
        self.fc = Dense(units=NUM_CLASSES, activation=softmax)
Ejemplo n.º 6
0
    def __init__(self,
                 blocks_args=None,
                 global_params=None,
                 ds_low=None,
                 ds_high=None):
        super().__init__()
        assert isinstance(blocks_args, list), 'blocks_args should be a list'
        assert len(blocks_args) > 0, 'block args must be greater than 0'
        assert ds_high > ds_low, 'ds_high must be greater than ds_low'
        assert max(
            ds_high,
            ds_low) <= 32, 'downsampling time should not be greater than 32'
        self._global_params = global_params
        self._blocks_args = blocks_args
        self.ds_low = ds_low
        self.ds_high = ds_high

        # Get static or dynamic convolution depending on image size
        Conv2d = get_same_padding_conv2d(image_size=global_params.image_size)

        # Batch norm parameters
        bn_mom = 1 - self._global_params.batch_norm_momentum
        bn_eps = self._global_params.batch_norm_epsilon

        # Stem
        in_channels = 3  # rgb
        out_channels = round_filters(
            32, self._global_params)  # number of output channels
        self._conv_stem = Conv2d(in_channels,
                                 out_channels,
                                 kernel_size=3,
                                 stride=2,
                                 bias=False)
        self._bn0 = nn.BatchNorm2d(num_features=out_channels,
                                   momentum=bn_mom,
                                   eps=bn_eps)

        # Build blocks
        self._blocks = nn.ModuleList([])

        # Calculate the number of blocks
        block_indexs = [0, 1, 2, 4, 5, 6]
        if ds_high == None:
            self.num_blocks = 7
        else:
            self.num_blocks = round(math.log(self.ds_high, 2))

        for block_args in self._blocks_args[0:block_indexs[self.num_blocks]]:

            # Update block input and output filters based on depth multiplier.
            block_args = block_args._replace(
                input_filters=round_filters(block_args.input_filters,
                                            self._global_params),
                output_filters=round_filters(block_args.output_filters,
                                             self._global_params),
                num_repeat=round_repeats(block_args.num_repeat,
                                         self._global_params))

            # The first block needs to take care of stride and filter size increase.
            self._blocks.append(MBConvBlock(block_args, self._global_params))
            if block_args.num_repeat > 1:
                block_args = block_args._replace(
                    input_filters=block_args.output_filters, stride=1)
            for _ in range(block_args.num_repeat - 1):
                self._blocks.append(
                    MBConvBlock(block_args, self._global_params))

        # Head
        in_channels = block_args.output_filters  # output of final block
        out_channels = round_filters(1280, self._global_params)
        #self._conv_head = Conv2d(in_channels, out_channels, kernel_size=1, bias=False)
        #self._bn1 = nn.BatchNorm2d(num_features=out_channels, momentum=bn_mom, eps=bn_eps)

        # Final linear layer
        #self._avg_pooling = nn.AdaptiveAvgPool2d(1)
        #self._dropout = nn.Dropout(self._global_params.dropout_rate)
        #self._fc = nn.Linear(out_channels, self._global_params.num_classes)
        self._swish = MemoryEfficientSwish()
    def __init__(self,
                 blocks_args=None,
                 global_params=None,
                 norm='',
                 model_version=4):
        super().__init__()
        assert isinstance(blocks_args, list), 'blocks_args should be a list'
        assert len(blocks_args) > 0, 'block args must be greater than 0'
        self.g_cfg = global_params
        self.b_cfgs = blocks_args

        # Get static or dynamic convolution depending on image size
        Conv2d = get_same_padding_conv2d(image_size=global_params.image_size)

        # Batch norm parameters
        bn_mom = 1 - self.g_cfg.batch_norm_momentum
        bn_eps = self.g_cfg.batch_norm_epsilon

        # Stem
        in_channels = 3  # rgb
        out_channels = round_filters(32,
                                     self.g_cfg)  # number of output channels
        self._conv_stem = Conv2d(in_channels,
                                 out_channels,
                                 kernel_size=3,
                                 stride=2,
                                 bias=False)
        # self._bn0 = nn.BatchNorm2d(num_features=out_channels, momentum=bn_mom, eps=bn_eps)
        self._bn0 = get_norm(norm, out_channels)

        # Build blocks
        self._blocks = nn.ModuleList([])

        idx = 0
        out_inds = []
        out_channels = []
        for b_cfg in self.b_cfgs:
            # Update block input and output filters based on depth multiplier.
            b_cfg = b_cfg._replace(
                input_filters=round_filters(b_cfg.input_filters, self.g_cfg),
                output_filters=round_filters(b_cfg.output_filters, self.g_cfg),
                num_repeat=round_repeats(b_cfg.num_repeat, self.g_cfg))

            # The first block needs to take care of stride and filter size increase.
            self._blocks.append(MBConvBlock(b_cfg, self.g_cfg, norm))
            print(b_cfg.stride)
            if b_cfg.stride[0] != 1:
                out_inds.append(idx - 1)
                out_channels.append(b_cfg.input_filters)
            idx += 1
            if b_cfg.num_repeat > 1:
                b_cfg = b_cfg._replace(input_filters=b_cfg.output_filters,
                                       stride=1)
            for _ in range(b_cfg.num_repeat - 1):
                self._blocks.append(MBConvBlock(b_cfg, self.g_cfg, norm))
                idx += 1
        out_inds.append(idx - 1)
        out_channels.append(b_cfg.output_filters)
        self.out_block_inds_all_stage = out_inds
        self.out_block_inds = out_inds[1:]
        self._out_feature_channels = out_channels[1:]
        # Head
        # in_channels = block_args.output_filters  # output of final block
        # out_channels = round_filters(1280, self._global_params)
        # self._conv_head = Conv2d(in_channels, out_channels, kernel_size=1, bias=False)
        # self._bn1 = nn.BatchNorm2d(num_features=out_channels, momentum=bn_mom, eps=bn_eps)
        #
        # # Final linear layer
        # self._avg_pooling = nn.AdaptiveAvgPool2d(1)
        # self._dropout = nn.Dropout(self._global_params.dropout_rate)
        # self._fc = nn.Linear(out_channels, self._global_params.num_classes)
        self._swish = MemoryEfficientSwish()
Ejemplo n.º 8
0
    def __init__(self, blocks_args, global_params, heads, head_conv):
        super(EfficientNet, self).__init__()
        assert isinstance(blocks_args, list), 'blocks_args should be a list'
        assert len(blocks_args) > 0, 'block args must be greater than 0'
        self._global_params = global_params
        self._blocks_args = blocks_args
        self._heads = heads

        # Batch norm parameters
        bn_mom = 1 - self._global_params.batch_norm_momentum
        bn_eps = self._global_params.batch_norm_epsilon

        # Stem
        in_channels = 3  # rgb
        out_channels = round_filters(
            32, self._global_params)  # number of output channels
        self._conv_stem = Conv2dSamePadding(in_channels,
                                            out_channels,
                                            kernel_size=3,
                                            stride=2,
                                            bias=False)
        self._bn0 = nn.BatchNorm2d(num_features=out_channels,
                                   momentum=bn_mom,
                                   eps=bn_eps)

        # Build blocks
        self._blocks = nn.ModuleList([])
        for block_args in self._blocks_args:

            # Update block input and output filters based on depth multiplier.
            block_args = block_args._replace(
                input_filters=round_filters(block_args.input_filters,
                                            self._global_params),
                output_filters=round_filters(block_args.output_filters,
                                             self._global_params),
                num_repeat=round_repeats(block_args.num_repeat,
                                         self._global_params))

            # The first block needs to take care of stride and filter size increase.
            self._blocks.append(MBConvBlock(block_args, self._global_params))
            if block_args.num_repeat > 1:
                block_args = block_args._replace(
                    input_filters=block_args.output_filters, stride=1)
            for _ in range(block_args.num_repeat - 1):
                self._blocks.append(
                    MBConvBlock(block_args, self._global_params))
        self._blocks = self._blocks[0:11]

        for head in self._heads:
            classes = self._heads[head]
            if head_conv > 0:
                fc = nn.Sequential(
                    nn.Conv2d(112,
                              head_conv,
                              kernel_size=3,
                              padding=1,
                              bias=True), nn.ReLU(inplace=True),
                    nn.Conv2d(head_conv,
                              classes,
                              kernel_size=1,
                              stride=1,
                              padding=0,
                              bias=True))
                if 'hm' in head:
                    fc[-1].bias.data.fill_(-2.19)
                else:
                    fill_fc_weights(fc)
            else:
                fc = nn.Conv2d(112,
                               classes,
                               kernel_size=1,
                               stride=1,
                               padding=0,
                               bias=True)
                if 'hm' in head:
                    fc.bias.data.fill_(-2.19)
                else:
                    fill_fc_weights(fc)
            self.__setattr__(head, fc)
        '''