Unverified Commit 45ae8785 authored by Pavel Yakubovskiy's avatar Pavel Yakubovskiy Committed by GitHub

Merge pull request #43 from qubvel/feature-new-backbones

New backbones
parents 0b209b9e e9e47cca
keras>=2.1.4
scikit-image
image-classifiers==0.1.0rc0
\ No newline at end of file
image-classifiers==0.2.0
\ No newline at end of file
from .inception_resnet_v2 import InceptionResNetV2
from .inception_v3 import InceptionV3
from classification_models import Classifiers
from classification_models import resnext
from .backbones import get_backbone
from .preprocessing import get_preprocessing
\ No newline at end of file
from . import inception_resnet_v2 as irv2
from . import inception_v3 as iv3
# replace backbones with others, which have corrected padding mode in first pooling
Classifiers._models.update({
'inceptionresnetv2': [irv2.InceptionResNetV2, irv2.preprocess_input],
'inceptionv3': [iv3.InceptionV3, iv3.preprocess_input],
'resnext50': [resnext.ResNeXt50, resnext.models.preprocess_input],
'resnext101': [resnext.ResNeXt101, resnext.models.preprocess_input],
})
DEFAULT_FEATURE_LAYERS = {
# List of layers to take features from backbone in the following order:
# (x16, x8, x4, x2, x1) - `x4` mean that features has 4 times less spatial
# resolution (Height x Width) than input image.
# VGG
'vgg16': ('block5_conv3', 'block4_conv3', 'block3_conv3', 'block2_conv2', 'block1_conv2'),
'vgg19': ('block5_conv4', 'block4_conv4', 'block3_conv4', 'block2_conv2', 'block1_conv2'),
# ResNets
'resnet18': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnet34': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnet50': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnet101': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnet152': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
# ResNeXt
'resnext50': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnext101': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
# Inception
'inceptionv3': (228, 86, 16, 9),
'inceptionresnetv2': (594, 260, 16, 9),
# DenseNet
'densenet121': (311, 139, 51, 4),
'densenet169': (367, 139, 51, 4),
'densenet201': (479, 139, 51, 4),
# SE models
'seresnet18': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'seresnet34': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'seresnet50': (233, 129, 59, 4),
'seresnet101': (522, 129, 59, 4),
'seresnet152': (811, 197, 59, 4),
'seresnext50': (1065, 577, 251, 4),
'seresnext101': (2442, 577, 251, 4),
'senet154': (6837, 1614, 451, 12),
# Mobile Nets
'mobilenet': ('conv_pw_11_relu', 'conv_pw_5_relu', 'conv_pw_3_relu', 'conv_pw_1_relu'),
'mobilenetv2': ('block_13_expand_relu', 'block_6_expand_relu', 'block_3_expand_relu', 'block_1_expand_relu'),
}
def get_names():
return list(DEFAULT_FEATURE_LAYERS.keys())
def get_feature_layers(name, n=5):
return DEFAULT_FEATURE_LAYERS[name][:n]
def get_backbone(name, *args, **kwargs):
return Classifiers.get_classifier(name)(*args, **kwargs)
def get_preprocessing(name):
return Classifiers.get_preprocessing(name)
import keras.applications as ka
import classification_models as cm
from .inception_resnet_v2 import InceptionResNetV2
from .inception_v3 import InceptionV3
backbones = {
"vgg16": ka.VGG16,
"vgg19": ka.VGG19,
"resnet18": cm.ResNet18,
"resnet34": cm.ResNet34,
"resnet50": cm.ResNet50,
"resnet101": cm.ResNet101,
"resnet152": cm.ResNet152,
"resnext50": cm.ResNeXt50,
"resnext101": cm.ResNeXt101,
"inceptionresnetv2": InceptionResNetV2,
"inceptionv3": InceptionV3,
"densenet121": ka.DenseNet121,
"densenet169": ka.DenseNet169,
"densenet201": ka.DenseNet201,
}
def get_backbone(name, *args, **kwargs):
return backbones[name](*args, **kwargs)
\ No newline at end of file
"""
Image pre-processing functions.
Images are assumed to be read in uint8 format (range 0-255).
"""
import keras.applications as ka
identical = lambda x: x
bgr_transpose = lambda x: x[..., ::-1]
models_preprocessing = {
'vgg16': ka.vgg16.preprocess_input,
'vgg19': ka.vgg19.preprocess_input,
'resnet18': bgr_transpose,
'resnet34': bgr_transpose,
'resnet50': bgr_transpose,
'resnet101': bgr_transpose,
'resnet152': bgr_transpose,
'resnext50': identical,
'resnext101': identical,
'densenet121': ka.densenet.preprocess_input,
'densenet169': ka.densenet.preprocess_input,
'densenet201': ka.densenet.preprocess_input,
'inceptionv3': ka.inception_v3.preprocess_input,
'inceptionresnetv2': ka.inception_resnet_v2.preprocess_input,
}
def get_preprocessing(backbone):
"""Returns pre-processing function for image data according to name of backbone
Args:
backbone (str): name of classification model
Returns:
``callable``: preprocessing_function
"""
return models_preprocessing[backbone]
from .builder import build_fpn
from ..backbones import get_backbone
from ..backbones import get_backbone, get_feature_layers
from ..utils import freeze_model
from ..utils import legacy_support
DEFAULT_FEATURE_PYRAMID_LAYERS = {
'vgg16': ('block5_conv3', 'block4_conv3', 'block3_conv3'),
'vgg19': ('block5_conv4', 'block4_conv4', 'block3_conv4'),
'resnet18': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1'),
'resnet34': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1'),
'resnet50': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1'),
'resnet101': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1'),
'resnet152': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1'),
'resnext50': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1'),
'resnext101': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1'),
'inceptionv3': (228, 86, 16),
'inceptionresnetv2': (594, 260, 16),
'densenet121': (311, 139, 51),
'densenet169': (367, 139, 51),
'densenet201': (479, 139, 51),
}
old_args_map = {
'freeze_encoder': 'encoder_freeze',
'fpn_layers': 'encoder_features',
......@@ -83,7 +66,7 @@ def FPN(backbone_name='vgg16',
include_top=False)
if encoder_features == 'default':
encoder_features = DEFAULT_FEATURE_PYRAMID_LAYERS[backbone_name]
encoder_features = get_feature_layers(backbone_name, n=3)
upsample_rates = [2] * len(encoder_features)
last_upsample = 2 ** (5 - len(encoder_features))
......
from .builder import build_linknet
from ..utils import freeze_model
from ..utils import legacy_support
from ..backbones import get_backbone
DEFAULT_SKIP_CONNECTIONS = {
'vgg16': ('block5_conv3', 'block4_conv3', 'block3_conv3', 'block2_conv2'),
'vgg19': ('block5_conv4', 'block4_conv4', 'block3_conv4', 'block2_conv2'),
'resnet18': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnet34': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnet50': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnet101': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnet152': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnext50': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnext101': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'inceptionv3': (228, 86, 16, 9),
'inceptionresnetv2': (594, 260, 16, 9),
'densenet121': (311, 139, 51, 4),
'densenet169': (367, 139, 51, 4),
'densenet201': (479, 139, 51, 4),
}
from ..backbones import get_backbone, get_feature_layers
old_args_map = {
'freeze_encoder': 'encoder_freeze',
......@@ -84,7 +67,7 @@ def Linknet(backbone_name='vgg16',
include_top=False)
if encoder_features == 'default':
encoder_features = DEFAULT_SKIP_CONNECTIONS[backbone_name]
encoder_features = get_feature_layers(backbone_name, n=4)
model = build_linknet(backbone,
classes,
......
from .builder import build_psp
from ..utils import freeze_model
from ..utils import legacy_support
from ..backbones import get_backbone
PSP_BASE_LAYERS = {
'vgg16': ('block5_conv3', 'block4_conv3', 'block3_conv3'),
'vgg19': ('block5_conv4', 'block4_conv4', 'block3_conv4'),
'resnet18': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1'),
'resnet34': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1'),
'resnet50': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1'),
'resnet101': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1'),
'resnet152': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1'),
'resnext50': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1'),
'resnext101': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1'),
'inceptionv3': (228, 86, 16),
'inceptionresnetv2': (594, 260, 16),
'densenet121': (311, 139, 51),
'densenet169': (367, 139, 51),
'densenet201': (479, 139, 51),
}
from ..backbones import get_backbone, get_feature_layers
def _get_layer_by_factor(backbone_name, factor):
feature_layers = get_feature_layers(backbone_name, n=3)
if factor == 4:
return PSP_BASE_LAYERS[backbone_name][-1]
return feature_layers[-1]
elif factor == 8:
return PSP_BASE_LAYERS[backbone_name][-2]
return feature_layers[-2]
elif factor == 16:
return PSP_BASE_LAYERS[backbone_name][-3]
return feature_layers[-3]
else:
raise ValueError('Unsupported factor - `{}`, Use 4, 8 or 16.'.format(factor))
......
from .builder import build_unet
from ..utils import freeze_model
from ..utils import legacy_support
from ..backbones import get_backbone
DEFAULT_SKIP_CONNECTIONS = {
'vgg16': ('block5_conv3', 'block4_conv3', 'block3_conv3', 'block2_conv2', 'block1_conv2'),
'vgg19': ('block5_conv4', 'block4_conv4', 'block3_conv4', 'block2_conv2', 'block1_conv2'),
'resnet18': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'), # check 'bn_data'
'resnet34': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnet50': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnet101': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnet152': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnext50': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'resnext101': ('stage4_unit1_relu1', 'stage3_unit1_relu1', 'stage2_unit1_relu1', 'relu0'),
'inceptionv3': (228, 86, 16, 9),
'inceptionresnetv2': (594, 260, 16, 9),
'densenet121': (311, 139, 51, 4),
'densenet169': (367, 139, 51, 4),
'densenet201': (479, 139, 51, 4),
}
from ..backbones import get_backbone, get_feature_layers
old_args_map = {
'freeze_encoder': 'encoder_freeze',
'skip_connections': 'encoder_features',
'upsample_rates': None, # removed
'upsample_rates': None, # removed
'input_tensor': None, # removed
}
......@@ -80,7 +63,7 @@ def Unet(backbone_name='vgg16',
include_top=False)
if encoder_features == 'default':
encoder_features = DEFAULT_SKIP_CONNECTIONS[backbone_name]
encoder_features = get_feature_layers(backbone_name, n=4)
model = build_unet(backbone,
classes,
......
......@@ -9,10 +9,20 @@ from segmentation_models import Unet
from segmentation_models import Linknet
from segmentation_models import PSPNet
from segmentation_models import FPN
from segmentation_models.backbones import backbones as bkb
from segmentation_models import backbones as sm_backbones
BACKBONES = list(bkb.backbones.keys())
def get_backbones():
is_travis = os.environ.get('TRAVIS', False)
exclude = ['senet154']
backbones = sm_backbones.get_names()
if is_travis:
backbones = [b for b in backbones if b not in exclude]
return backbones
BACKBONES = get_backbones()
def _select_names(names):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment