|
|
|
@ -35,7 +35,7 @@ from .efficientnet_blocks import round_channels, resolve_bn_args, resolve_act_la
|
|
|
|
|
from .efficientnet_builder import EfficientNetBuilder, decode_arch_def, efficientnet_init_weights
|
|
|
|
|
from .features import FeatureInfo, FeatureHooks
|
|
|
|
|
from .helpers import build_model_with_cfg
|
|
|
|
|
from .layers import SelectAdaptivePool2d, create_conv2d
|
|
|
|
|
from .layers import create_conv2d, create_classifier
|
|
|
|
|
from .registry import register_model
|
|
|
|
|
|
|
|
|
|
__all__ = ['EfficientNet']
|
|
|
|
@ -336,32 +336,28 @@ class EfficientNet(nn.Module):
|
|
|
|
|
self.num_classes = num_classes
|
|
|
|
|
self.num_features = num_features
|
|
|
|
|
self.drop_rate = drop_rate
|
|
|
|
|
self._in_chs = in_chans
|
|
|
|
|
|
|
|
|
|
# Stem
|
|
|
|
|
if not fix_stem:
|
|
|
|
|
stem_size = round_channels(stem_size, channel_multiplier, channel_divisor, channel_min)
|
|
|
|
|
self.conv_stem = create_conv2d(self._in_chs, stem_size, 3, stride=2, padding=pad_type)
|
|
|
|
|
self.conv_stem = create_conv2d(in_chans, stem_size, 3, stride=2, padding=pad_type)
|
|
|
|
|
self.bn1 = norm_layer(stem_size, **norm_kwargs)
|
|
|
|
|
self.act1 = act_layer(inplace=True)
|
|
|
|
|
self._in_chs = stem_size
|
|
|
|
|
|
|
|
|
|
# Middle stages (IR/ER/DS Blocks)
|
|
|
|
|
builder = EfficientNetBuilder(
|
|
|
|
|
channel_multiplier, channel_divisor, channel_min, output_stride, pad_type, act_layer, se_kwargs,
|
|
|
|
|
norm_layer, norm_kwargs, drop_path_rate, verbose=_DEBUG)
|
|
|
|
|
self.blocks = nn.Sequential(*builder(self._in_chs, block_args))
|
|
|
|
|
self.blocks = nn.Sequential(*builder(stem_size, block_args))
|
|
|
|
|
self.feature_info = builder.features
|
|
|
|
|
self._in_chs = builder.in_chs
|
|
|
|
|
head_chs = builder.in_chs
|
|
|
|
|
|
|
|
|
|
# Head + Pooling
|
|
|
|
|
self.conv_head = create_conv2d(self._in_chs, self.num_features, 1, padding=pad_type)
|
|
|
|
|
self.conv_head = create_conv2d(head_chs, self.num_features, 1, padding=pad_type)
|
|
|
|
|
self.bn2 = norm_layer(self.num_features, **norm_kwargs)
|
|
|
|
|
self.act2 = act_layer(inplace=True)
|
|
|
|
|
self.global_pool = SelectAdaptivePool2d(pool_type=global_pool)
|
|
|
|
|
|
|
|
|
|
# Classifier
|
|
|
|
|
self.classifier = nn.Linear(self.num_features * self.global_pool.feat_mult(), self.num_classes)
|
|
|
|
|
self.global_pool, self.classifier = create_classifier(
|
|
|
|
|
self.num_features, self.num_classes, pool_type=global_pool)
|
|
|
|
|
|
|
|
|
|
efficientnet_init_weights(self)
|
|
|
|
|
|
|
|
|
@ -369,7 +365,7 @@ class EfficientNet(nn.Module):
|
|
|
|
|
layers = [self.conv_stem, self.bn1, self.act1]
|
|
|
|
|
layers.extend(self.blocks)
|
|
|
|
|
layers.extend([self.conv_head, self.bn2, self.act2, self.global_pool])
|
|
|
|
|
layers.extend([nn.Flatten(), nn.Dropout(self.drop_rate), self.classifier])
|
|
|
|
|
layers.extend([nn.Dropout(self.drop_rate), self.classifier])
|
|
|
|
|
return nn.Sequential(*layers)
|
|
|
|
|
|
|
|
|
|
def get_classifier(self):
|
|
|
|
@ -377,12 +373,8 @@ class EfficientNet(nn.Module):
|
|
|
|
|
|
|
|
|
|
def reset_classifier(self, num_classes, global_pool='avg'):
|
|
|
|
|
self.num_classes = num_classes
|
|
|
|
|
self.global_pool = SelectAdaptivePool2d(pool_type=global_pool)
|
|
|
|
|
if num_classes:
|
|
|
|
|
num_features = self.num_features * self.global_pool.feat_mult()
|
|
|
|
|
self.classifier = nn.Linear(num_features, num_classes)
|
|
|
|
|
else:
|
|
|
|
|
self.classifier = nn.Identity()
|
|
|
|
|
self.global_pool, self.classifier = create_classifier(
|
|
|
|
|
self.num_features, self.num_classes, pool_type=global_pool)
|
|
|
|
|
|
|
|
|
|
def forward_features(self, x):
|
|
|
|
|
x = self.conv_stem(x)
|
|
|
|
@ -397,7 +389,6 @@ class EfficientNet(nn.Module):
|
|
|
|
|
def forward(self, x):
|
|
|
|
|
x = self.forward_features(x)
|
|
|
|
|
x = self.global_pool(x)
|
|
|
|
|
x = x.flatten(1)
|
|
|
|
|
if self.drop_rate > 0.:
|
|
|
|
|
x = F.dropout(x, p=self.drop_rate, training=self.training)
|
|
|
|
|
return self.classifier(x)
|
|
|
|
@ -417,24 +408,21 @@ class EfficientNetFeatures(nn.Module):
|
|
|
|
|
super(EfficientNetFeatures, self).__init__()
|
|
|
|
|
norm_kwargs = norm_kwargs or {}
|
|
|
|
|
self.drop_rate = drop_rate
|
|
|
|
|
self._in_chs = in_chans
|
|
|
|
|
|
|
|
|
|
# Stem
|
|
|
|
|
if not fix_stem:
|
|
|
|
|
stem_size = round_channels(stem_size, channel_multiplier, channel_divisor, channel_min)
|
|
|
|
|
self.conv_stem = create_conv2d(self._in_chs, stem_size, 3, stride=2, padding=pad_type)
|
|
|
|
|
self.conv_stem = create_conv2d(in_chans, stem_size, 3, stride=2, padding=pad_type)
|
|
|
|
|
self.bn1 = norm_layer(stem_size, **norm_kwargs)
|
|
|
|
|
self.act1 = act_layer(inplace=True)
|
|
|
|
|
self._in_chs = stem_size
|
|
|
|
|
|
|
|
|
|
# Middle stages (IR/ER/DS Blocks)
|
|
|
|
|
builder = EfficientNetBuilder(
|
|
|
|
|
channel_multiplier, channel_divisor, channel_min, output_stride, pad_type, act_layer, se_kwargs,
|
|
|
|
|
norm_layer, norm_kwargs, drop_path_rate, feature_location=feature_location, verbose=_DEBUG)
|
|
|
|
|
self.blocks = nn.Sequential(*builder(self._in_chs, block_args))
|
|
|
|
|
self.blocks = nn.Sequential(*builder(stem_size, block_args))
|
|
|
|
|
self.feature_info = FeatureInfo(builder.features, out_indices)
|
|
|
|
|
self._stage_out_idx = {v['stage']: i for i, v in enumerate(self.feature_info) if i in out_indices}
|
|
|
|
|
self._in_chs = builder.in_chs
|
|
|
|
|
|
|
|
|
|
efficientnet_init_weights(self)
|
|
|
|
|
|
|
|
|
|