# copyright (c) 2023 PaddlePaddle Authors. All Rights Reserve. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Code was based on https://gitee.com/mindspore/models/tree/master/research/cv/tinynet # reference: https://arxiv.org/abs/2010.14819 import paddle.nn as nn from .efficientnet import EfficientNet, efficientnet from ....utils.save_load import load_dygraph_pretrain, load_dygraph_pretrain_from_url MODEL_URLS = { "TinyNet_A": "https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/TinyNet_A_pretrained.pdparams", "TinyNet_B": "https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/TinyNet_B_pretrained.pdparams", "TinyNet_C": "https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/TinyNet_C_pretrained.pdparams", "TinyNet_D": "https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/TinyNet_D_pretrained.pdparams", "TinyNet_E": "https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/TinyNet_E_pretrained.pdparams", } __all__ = list(MODEL_URLS.keys()) def tinynet_params(model_name): """ Map TinyNet model name to parameter coefficients. """ params_dict = { # Coefficients: width,depth,resolution,dropout "tinynet-a": (1.00, 1.200, 192, 0.2), "tinynet-b": (0.75, 1.100, 188, 0.2), "tinynet-c": (0.54, 0.850, 184, 0.2), "tinynet-d": (0.54, 0.695, 152, 0.2), "tinynet-e": (0.51, 0.600, 106, 0.2), } return params_dict[model_name] def get_model_params(model_name, override_params): """ Get the block args and global params for a given model """ if model_name.startswith('tinynet'): w, d, _, p = tinynet_params(model_name) blocks_args, global_params = efficientnet( width_coefficient=w, depth_coefficient=d, dropout_rate=p) else: raise NotImplementedError('model name is not pre-defined: %s' % model_name) if override_params: global_params = global_params._replace(**override_params) return blocks_args, global_params class TinyNet(EfficientNet): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.apply(self._init_weights) def _init_weights(self, m): if isinstance(m, nn.Conv2D): fin_in = m.weight.shape[1] * m.weight.shape[2] * m.weight.shape[3] std = (2 / fin_in)**0.5 nn.initializer.Normal(std=std)(m.weight) if m.bias is not None: nn.initializer.Constant(0)(m.bias) elif isinstance(m, nn.Linear): fin_in = m.weight.shape[0] bound = 1 / fin_in**0.5 nn.initializer.Uniform(-bound, bound)(m.weight) if m.bias is not None: nn.initializer.Constant(0)(m.bias) def _load_pretrained(pretrained, model, model_url, use_ssld=False): if pretrained is False: pass elif pretrained is True: load_dygraph_pretrain_from_url(model, model_url, use_ssld=use_ssld) elif isinstance(pretrained, str): load_dygraph_pretrain(model, pretrained) else: raise RuntimeError( "pretrained type is not available. Please use `string` or `boolean` type." ) def TinyNet_A(padding_type='DYNAMIC', override_params=None, use_se=True, pretrained=False, use_ssld=False, **kwargs): block_args, global_params = get_model_params("tinynet-a", override_params) model = TinyNet( block_args, global_params, name='a', padding_type=padding_type, use_se=use_se, fix_stem=True, num_features=1280, **kwargs) _load_pretrained(pretrained, model, MODEL_URLS["TinyNet_A"], use_ssld) return model def TinyNet_B(padding_type='DYNAMIC', override_params=None, use_se=True, pretrained=False, use_ssld=False, **kwargs): block_args, global_params = get_model_params("tinynet-b", override_params) model = TinyNet( block_args, global_params, name='b', padding_type=padding_type, use_se=use_se, fix_stem=True, num_features=1280, **kwargs) _load_pretrained(pretrained, model, MODEL_URLS["TinyNet_B"], use_ssld) return model def TinyNet_C(padding_type='DYNAMIC', override_params=None, use_se=True, pretrained=False, use_ssld=False, **kwargs): block_args, global_params = get_model_params("tinynet-c", override_params) model = TinyNet( block_args, global_params, name='c', padding_type=padding_type, use_se=use_se, fix_stem=True, num_features=1280, **kwargs) _load_pretrained(pretrained, model, MODEL_URLS["TinyNet_C"], use_ssld) return model def TinyNet_D(padding_type='DYNAMIC', override_params=None, use_se=True, pretrained=False, use_ssld=False, **kwargs): block_args, global_params = get_model_params("tinynet-d", override_params) model = TinyNet( block_args, global_params, name='d', padding_type=padding_type, use_se=use_se, fix_stem=True, num_features=1280, **kwargs) _load_pretrained(pretrained, model, MODEL_URLS["TinyNet_D"], use_ssld) return model def TinyNet_E(padding_type='DYNAMIC', override_params=None, use_se=True, pretrained=False, use_ssld=False, **kwargs): block_args, global_params = get_model_params("tinynet-e", override_params) model = TinyNet( block_args, global_params, name='e', padding_type=padding_type, use_se=use_se, fix_stem=True, num_features=1280, **kwargs) _load_pretrained(pretrained, model, MODEL_URLS["TinyNet_E"], use_ssld) return model