EfficientNet model. Most easily loaded with the .from_name or .from_pretrained methods. Args: blocks_args (list[namedtuple]): A list of BlockArgs to construct blocks. global_params (namedtuple): A set of GlobalParams shared between blocks. References: [1] https
| 147 | |
| 148 | @MODELS.register_module() |
| 149 | class EfficientNet(nn.Module): |
| 150 | """EfficientNet model. |
| 151 | Most easily loaded with the .from_name or .from_pretrained methods. |
| 152 | Args: |
| 153 | blocks_args (list[namedtuple]): A list of BlockArgs to construct blocks. |
| 154 | global_params (namedtuple): A set of GlobalParams shared between blocks. |
| 155 | References: |
| 156 | [1] https://arxiv.org/abs/1905.11946 (EfficientNet) |
| 157 | Example: |
| 158 | >>> import torch |
| 159 | >>> from efficientnet.model import EfficientNet |
| 160 | >>> inputs = torch.rand(1, 3, 224, 224) |
| 161 | >>> model = EfficientNet.from_pretrained('efficientnet-b0') |
| 162 | >>> model.eval() |
| 163 | >>> outputs = model(inputs) |
| 164 | """ |
| 165 | |
| 166 | def __init__(self, blocks_args=None, global_params=None): |
| 167 | super().__init__() |
| 168 | assert isinstance(blocks_args, list), 'blocks_args should be a list' |
| 169 | assert len(blocks_args) > 0, 'block args must be greater than 0' |
| 170 | self._global_params = global_params |
| 171 | self._blocks_args = blocks_args |
| 172 | |
| 173 | # Batch norm parameters |
| 174 | bn_mom = 1 - self._global_params.batch_norm_momentum |
| 175 | bn_eps = self._global_params.batch_norm_epsilon |
| 176 | |
| 177 | # Get stem static or dynamic convolution depending on image size |
| 178 | image_size = global_params.image_size |
| 179 | Conv2d = get_same_padding_conv2d(image_size=image_size) |
| 180 | |
| 181 | # Stem |
| 182 | in_channels = 3 # rgb |
| 183 | out_channels = round_filters(32, self._global_params) # number of output channels |
| 184 | self._conv_stem = Conv2d(in_channels, out_channels, kernel_size=3, stride=2, bias=False) |
| 185 | self._bn0 = nn.BatchNorm2d(num_features=out_channels, momentum=bn_mom, eps=bn_eps) |
| 186 | image_size = calculate_output_image_size(image_size, 2) |
| 187 | |
| 188 | # Build blocks |
| 189 | self._blocks = nn.ModuleList([]) |
| 190 | for block_args in self._blocks_args: |
| 191 | |
| 192 | # Update block input and output filters based on depth multiplier. |
| 193 | block_args = block_args._replace( |
| 194 | input_filters=round_filters(block_args.input_filters, self._global_params), |
| 195 | output_filters=round_filters(block_args.output_filters, self._global_params), |
| 196 | num_repeat=round_repeats(block_args.num_repeat, self._global_params) |
| 197 | ) |
| 198 | |
| 199 | # The first block needs to take care of stride and filter size increase. |
| 200 | self._blocks.append(MBConvBlock(block_args, self._global_params, image_size=image_size)) |
| 201 | image_size = calculate_output_image_size(image_size, block_args.stride) |
| 202 | if block_args.num_repeat > 1: # modify block_args to keep same output size |
| 203 | block_args = block_args._replace(input_filters=block_args.output_filters, stride=1) |
| 204 | for _ in range(block_args.num_repeat - 1): |
| 205 | self._blocks.append(MBConvBlock(block_args, self._global_params, image_size=image_size)) |
| 206 | # image_size = calculate_output_image_size(image_size, block_args.stride) # stride = 1 |
nothing calls this directly
no outgoing calls
no test coverage detected