segmodels-keras 0.1.0.dev6__tar.gz → 0.1.0.dev8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/PKG-INFO +1 -1
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/README.rst +3 -1
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/__init__.py +4 -4
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/_version.py +1 -1
- segmodels_keras-0.1.0.dev8/segmodels_keras/backbones/_common_blocks.py +131 -0
- segmodels_keras-0.1.0.dev8/segmodels_keras/backbones/_weights.py +363 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/backbones/backbones_factory.py +31 -21
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/backbones/inception_resnet_v2.py +2 -117
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/backbones/inception_v3.py +1 -0
- segmodels_keras-0.1.0.dev8/segmodels_keras/backbones/resnet_18_34.py +368 -0
- segmodels_keras-0.1.0.dev8/segmodels_keras/backbones/resnet_common.py +122 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/base/functional.py +3 -3
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras.egg-info/PKG-INFO +1 -1
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras.egg-info/SOURCES.txt +4 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/tests/test_models.py +8 -8
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/LICENSE +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/MANIFEST.in +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/pyproject.toml +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/_compat.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/backbones/__init__.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/base/__init__.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/base/objects.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/losses.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/metrics.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/models/__init__.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/models/_common_blocks.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/models/_utils.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/models/fpn.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/models/linknet.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/models/pspnet.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/models/unet.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras/utils.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras.egg-info/dependency_links.txt +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras.egg-info/requires.txt +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/segmodels_keras.egg-info/top_level.txt +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/setup.cfg +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/setup.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/tests/test_backbones.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/tests/test_metrics.py +0 -0
- {segmodels_keras-0.1.0.dev6 → segmodels_keras-0.1.0.dev8}/tests/test_utils.py +0 -0
|
@@ -24,7 +24,9 @@ improvements and support for some extra backbone models.
|
|
|
24
24
|
It is not meant as a full replacement of the original library, but rather as a
|
|
25
25
|
solution for a library I developed and depended on segmentation_models:
|
|
26
26
|
`orthoseg <https://github.com/orthoseg/orthoseg>`__ . Hence, full backwards
|
|
27
|
-
compatibility
|
|
27
|
+
compatibility or support for all features is not an explicit goal. For example,
|
|
28
|
+
the resnet backbones got small changes compared to the original library, so existing
|
|
29
|
+
weights you saved for them won't be compatible.
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
**The main features** of this library are:
|
|
@@ -59,17 +59,17 @@ def set_framework(name):
|
|
|
59
59
|
name = name.lower()
|
|
60
60
|
|
|
61
61
|
if name == _KERAS_FRAMEWORK_NAME:
|
|
62
|
-
import keras
|
|
62
|
+
import keras # noqa: PLC0415
|
|
63
63
|
elif name == _TF_KERAS_FRAMEWORK_NAME:
|
|
64
|
-
from tensorflow import keras
|
|
64
|
+
from tensorflow import keras # noqa: PLC0415
|
|
65
65
|
else:
|
|
66
66
|
raise ValueError(
|
|
67
67
|
f"Not correct module name `{name}`, use `{_KERAS_FRAMEWORK_NAME}` or "
|
|
68
68
|
f"`{_TF_KERAS_FRAMEWORK_NAME}`"
|
|
69
69
|
)
|
|
70
70
|
|
|
71
|
-
global _KERAS_BACKEND, _KERAS_LAYERS, _KERAS_MODELS
|
|
72
|
-
global _KERAS_UTILS, _KERAS_LOSSES, _KERAS_FRAMEWORK
|
|
71
|
+
global _KERAS_BACKEND, _KERAS_LAYERS, _KERAS_MODELS # noqa: PLW0603
|
|
72
|
+
global _KERAS_UTILS, _KERAS_LOSSES, _KERAS_FRAMEWORK # noqa: PLW0603
|
|
73
73
|
|
|
74
74
|
_KERAS_FRAMEWORK = name
|
|
75
75
|
_KERAS_BACKEND = keras.backend
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__versioninfo__ = (0, 1, 0, "
|
|
1
|
+
__versioninfo__ = (0, 1, 0, "dev8")
|
|
2
2
|
__version__ = ".".join(map(str, __versioninfo__))
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""Common blocks for backbone models.
|
|
2
|
+
|
|
3
|
+
Source: https://github.com/qubvel/classification_models
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from keras import backend, layers
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def slice_tensor(x, start, stop, axis):
|
|
10
|
+
if axis == 3:
|
|
11
|
+
return x[:, :, :, start:stop]
|
|
12
|
+
elif axis == 1:
|
|
13
|
+
return x[:, start:stop, :, :]
|
|
14
|
+
else:
|
|
15
|
+
raise ValueError(f"Slice axis should be in (1, 3), got {axis}.")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def GroupConv2D(
|
|
19
|
+
filters,
|
|
20
|
+
kernel_size,
|
|
21
|
+
strides=(1, 1),
|
|
22
|
+
groups=32,
|
|
23
|
+
kernel_initializer="he_uniform",
|
|
24
|
+
use_bias=True,
|
|
25
|
+
activation="linear",
|
|
26
|
+
padding="valid",
|
|
27
|
+
**kwargs, # noqa: ARG001
|
|
28
|
+
):
|
|
29
|
+
"""Grouped Convolution Layer implemented as a Slice, Conv2D and Concatenate layers.
|
|
30
|
+
|
|
31
|
+
Split filters to groups, apply Conv2D and concatenate back.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
filters: Integer, the dimensionality of the output space
|
|
35
|
+
(i.e. the number of output filters in the convolution).
|
|
36
|
+
kernel_size: An integer or tuple/list of a single integer,
|
|
37
|
+
specifying the length of the 1D convolution window.
|
|
38
|
+
strides: An integer or tuple/list of a single integer, specifying the stride
|
|
39
|
+
length of the convolution.
|
|
40
|
+
groups: Integer, number of groups to split input filters to.
|
|
41
|
+
kernel_initializer: Regularizer function applied to the kernel weights matrix.
|
|
42
|
+
use_bias: Boolean, whether the layer uses a bias vector.
|
|
43
|
+
activation: Activation function to use (see activations).
|
|
44
|
+
If you don't specify anything, no activation is applied
|
|
45
|
+
(ie. "linear" activation: a(x) = x).
|
|
46
|
+
padding: one of "valid" or "same" (case-insensitive).
|
|
47
|
+
|
|
48
|
+
Input shape:
|
|
49
|
+
4D tensor with shape: (batch, rows, cols, channels) if data_format is
|
|
50
|
+
"channels_last".
|
|
51
|
+
|
|
52
|
+
Output shape:
|
|
53
|
+
4D tensor with shape: (batch, new_rows, new_cols, filters) if data_format is
|
|
54
|
+
"channels_last". rows and cols values might have changed due to padding.
|
|
55
|
+
|
|
56
|
+
"""
|
|
57
|
+
slice_axis = 3 if backend.image_data_format() == "channels_last" else 1
|
|
58
|
+
|
|
59
|
+
def layer(input_tensor):
|
|
60
|
+
inp_ch = int(
|
|
61
|
+
backend.int_shape(input_tensor)[-1] // groups
|
|
62
|
+
) # input grouped channels
|
|
63
|
+
out_ch = int(filters // groups) # output grouped channels
|
|
64
|
+
|
|
65
|
+
blocks = []
|
|
66
|
+
for c in range(groups):
|
|
67
|
+
slice_arguments = {
|
|
68
|
+
"start": c * inp_ch,
|
|
69
|
+
"stop": (c + 1) * inp_ch,
|
|
70
|
+
"axis": slice_axis,
|
|
71
|
+
}
|
|
72
|
+
x = layers.Lambda(slice_tensor, arguments=slice_arguments)(input_tensor)
|
|
73
|
+
x = layers.Conv2D(
|
|
74
|
+
out_ch,
|
|
75
|
+
kernel_size,
|
|
76
|
+
strides=strides,
|
|
77
|
+
kernel_initializer=kernel_initializer,
|
|
78
|
+
use_bias=use_bias,
|
|
79
|
+
activation=activation,
|
|
80
|
+
padding=padding,
|
|
81
|
+
)(x)
|
|
82
|
+
blocks.append(x)
|
|
83
|
+
|
|
84
|
+
x = layers.Concatenate(axis=slice_axis)(blocks)
|
|
85
|
+
return x
|
|
86
|
+
|
|
87
|
+
return layer
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def expand_dims(x, channels_axis):
|
|
91
|
+
if channels_axis == 3:
|
|
92
|
+
return x[:, None, None, :]
|
|
93
|
+
elif channels_axis == 1:
|
|
94
|
+
return x[:, :, None, None]
|
|
95
|
+
else:
|
|
96
|
+
raise ValueError(f"Slice axis should be in (1, 3), got {channels_axis}.")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def ChannelSE(reduction=16, **kwargs): # noqa: ARG001
|
|
100
|
+
"""
|
|
101
|
+
Squeeze and Excitation block, reimplementation inspired by
|
|
102
|
+
https://github.com/Cadene/pretrained-models.pytorch/blob/master/pretrainedmodels/models/senet.py
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
reduction: channels squeeze factor
|
|
106
|
+
|
|
107
|
+
"""
|
|
108
|
+
channels_axis = 3 if backend.image_data_format() == "channels_last" else 1
|
|
109
|
+
|
|
110
|
+
def layer(input_tensor):
|
|
111
|
+
# get number of channels/filters
|
|
112
|
+
channels = backend.int_shape(input_tensor)[channels_axis]
|
|
113
|
+
|
|
114
|
+
x = input_tensor
|
|
115
|
+
|
|
116
|
+
# squeeze and excitation block in PyTorch style with
|
|
117
|
+
x = layers.GlobalAveragePooling2D()(x)
|
|
118
|
+
x = layers.Lambda(expand_dims, arguments={"channels_axis": channels_axis})(x)
|
|
119
|
+
x = layers.Conv2D(
|
|
120
|
+
channels // reduction, (1, 1), kernel_initializer="he_uniform"
|
|
121
|
+
)(x)
|
|
122
|
+
x = layers.Activation("relu")(x)
|
|
123
|
+
x = layers.Conv2D(channels, (1, 1), kernel_initializer="he_uniform")(x)
|
|
124
|
+
x = layers.Activation("sigmoid")(x)
|
|
125
|
+
|
|
126
|
+
# apply attention
|
|
127
|
+
x = layers.Multiply()([input_tensor, x])
|
|
128
|
+
|
|
129
|
+
return x
|
|
130
|
+
|
|
131
|
+
return layer
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
"""Helper to download weights for backbones.
|
|
2
|
+
|
|
3
|
+
Source: https://github.com/qubvel/classification_models
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from keras.utils import get_file
|
|
7
|
+
|
|
8
|
+
__all__ = ["load_model_weights"]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _find_weights(model_name, dataset, include_top):
|
|
12
|
+
w = list(filter(lambda x: x["model"] == model_name, WEIGHTS_COLLECTION))
|
|
13
|
+
w = list(filter(lambda x: x["dataset"] == dataset, w))
|
|
14
|
+
w = list(filter(lambda x: x["include_top"] == include_top, w))
|
|
15
|
+
return w
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def load_model_weights(model, model_name, dataset, classes, include_top):
|
|
19
|
+
|
|
20
|
+
weights = _find_weights(model_name, dataset, include_top)
|
|
21
|
+
|
|
22
|
+
if weights:
|
|
23
|
+
weights = weights[0]
|
|
24
|
+
|
|
25
|
+
if include_top and weights["classes"] != classes:
|
|
26
|
+
raise ValueError(
|
|
27
|
+
"If using `weights` and `include_top`"
|
|
28
|
+
" as true, `classes` should be {}".format(weights["classes"])
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
weights_path = get_file(
|
|
32
|
+
weights["name"],
|
|
33
|
+
weights["url"],
|
|
34
|
+
cache_subdir="models",
|
|
35
|
+
md5_hash=weights["md5"],
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
model.load_weights(weights_path)
|
|
39
|
+
|
|
40
|
+
else:
|
|
41
|
+
raise ValueError(
|
|
42
|
+
"There is no weights for such configuration: "
|
|
43
|
+
f"model = {model.name}, dataset = {dataset}, "
|
|
44
|
+
f"classes = {classes}, include_top = {include_top}."
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
WEIGHTS_COLLECTION = [
|
|
49
|
+
# ResNet18
|
|
50
|
+
{
|
|
51
|
+
"model": "resnet18",
|
|
52
|
+
"dataset": "imagenet",
|
|
53
|
+
"classes": 1000,
|
|
54
|
+
"include_top": True,
|
|
55
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnet18_imagenet_1000.h5",
|
|
56
|
+
"name": "resnet18_imagenet_1000.h5",
|
|
57
|
+
"md5": "64da73012bb70e16c901316c201d9803",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"model": "resnet18",
|
|
61
|
+
"dataset": "imagenet",
|
|
62
|
+
"classes": 1000,
|
|
63
|
+
"include_top": False,
|
|
64
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnet18_imagenet_1000_no_top.h5",
|
|
65
|
+
"name": "resnet18_imagenet_1000_no_top.h5",
|
|
66
|
+
"md5": "318e3ac0cd98d51e917526c9f62f0b50",
|
|
67
|
+
},
|
|
68
|
+
# ResNet34
|
|
69
|
+
{
|
|
70
|
+
"model": "resnet34",
|
|
71
|
+
"dataset": "imagenet",
|
|
72
|
+
"classes": 1000,
|
|
73
|
+
"include_top": True,
|
|
74
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnet34_imagenet_1000.h5",
|
|
75
|
+
"name": "resnet34_imagenet_1000.h5",
|
|
76
|
+
"md5": "2ac8277412f65e5d047f255bcbd10383",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"model": "resnet34",
|
|
80
|
+
"dataset": "imagenet",
|
|
81
|
+
"classes": 1000,
|
|
82
|
+
"include_top": False,
|
|
83
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnet34_imagenet_1000_no_top.h5",
|
|
84
|
+
"name": "resnet34_imagenet_1000_no_top.h5",
|
|
85
|
+
"md5": "8caaa0ad39d927cb8ba5385bf945d582",
|
|
86
|
+
},
|
|
87
|
+
# ResNet50
|
|
88
|
+
{
|
|
89
|
+
"model": "resnet50",
|
|
90
|
+
"dataset": "imagenet",
|
|
91
|
+
"classes": 1000,
|
|
92
|
+
"include_top": True,
|
|
93
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnet50_imagenet_1000.h5",
|
|
94
|
+
"name": "resnet50_imagenet_1000.h5",
|
|
95
|
+
"md5": "d0feba4fc650e68ac8c19166ee1ba87f",
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"model": "resnet50",
|
|
99
|
+
"dataset": "imagenet",
|
|
100
|
+
"classes": 1000,
|
|
101
|
+
"include_top": False,
|
|
102
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnet50_imagenet_1000_no_top.h5",
|
|
103
|
+
"name": "resnet50_imagenet_1000_no_top.h5",
|
|
104
|
+
"md5": "db3b217156506944570ac220086f09b6",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"model": "resnet50",
|
|
108
|
+
"dataset": "imagenet11k-places365ch",
|
|
109
|
+
"classes": 11586,
|
|
110
|
+
"include_top": True,
|
|
111
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnet50_imagenet11k-places365ch_11586.h5",
|
|
112
|
+
"name": "resnet50_imagenet11k-places365ch_11586.h5",
|
|
113
|
+
"md5": "bb8963db145bc9906452b3d9c9917275",
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"model": "resnet50",
|
|
117
|
+
"dataset": "imagenet11k-places365ch",
|
|
118
|
+
"classes": 11586,
|
|
119
|
+
"include_top": False,
|
|
120
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnet50_imagenet11k-places365ch_11586_no_top.h5",
|
|
121
|
+
"name": "resnet50_imagenet11k-places365ch_11586_no_top.h5",
|
|
122
|
+
"md5": "d8bf4e7ea082d9d43e37644da217324a",
|
|
123
|
+
},
|
|
124
|
+
# ResNet101
|
|
125
|
+
{
|
|
126
|
+
"model": "resnet101",
|
|
127
|
+
"dataset": "imagenet",
|
|
128
|
+
"classes": 1000,
|
|
129
|
+
"include_top": True,
|
|
130
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnet101_imagenet_1000.h5",
|
|
131
|
+
"name": "resnet101_imagenet_1000.h5",
|
|
132
|
+
"md5": "9489ed2d5d0037538134c880167622ad",
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"model": "resnet101",
|
|
136
|
+
"dataset": "imagenet",
|
|
137
|
+
"classes": 1000,
|
|
138
|
+
"include_top": False,
|
|
139
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnet101_imagenet_1000_no_top.h5",
|
|
140
|
+
"name": "resnet101_imagenet_1000_no_top.h5",
|
|
141
|
+
"md5": "1016e7663980d5597a4e224d915c342d",
|
|
142
|
+
},
|
|
143
|
+
# ResNet152
|
|
144
|
+
{
|
|
145
|
+
"model": "resnet152",
|
|
146
|
+
"dataset": "imagenet",
|
|
147
|
+
"classes": 1000,
|
|
148
|
+
"include_top": True,
|
|
149
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnet152_imagenet_1000.h5",
|
|
150
|
+
"name": "resnet152_imagenet_1000.h5",
|
|
151
|
+
"md5": "1efffbcc0708fb0d46a9d096ae14f905",
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"model": "resnet152",
|
|
155
|
+
"dataset": "imagenet",
|
|
156
|
+
"classes": 1000,
|
|
157
|
+
"include_top": False,
|
|
158
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnet152_imagenet_1000_no_top.h5",
|
|
159
|
+
"name": "resnet152_imagenet_1000_no_top.h5",
|
|
160
|
+
"md5": "5867b94098df4640918941115db93734",
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"model": "resnet152",
|
|
164
|
+
"dataset": "imagenet11k",
|
|
165
|
+
"classes": 11221,
|
|
166
|
+
"include_top": True,
|
|
167
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnet152_imagenet11k_11221.h5",
|
|
168
|
+
"name": "resnet152_imagenet11k_11221.h5",
|
|
169
|
+
"md5": "24791790f6ef32f274430ce4a2ffee5d",
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"model": "resnet152",
|
|
173
|
+
"dataset": "imagenet11k",
|
|
174
|
+
"classes": 11221,
|
|
175
|
+
"include_top": False,
|
|
176
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnet152_imagenet11k_11221_no_top.h5",
|
|
177
|
+
"name": "resnet152_imagenet11k_11221_no_top.h5",
|
|
178
|
+
"md5": "25ab66dec217cb774a27d0f3659cafb3",
|
|
179
|
+
},
|
|
180
|
+
# ResNeXt50
|
|
181
|
+
{
|
|
182
|
+
"model": "resnext50",
|
|
183
|
+
"dataset": "imagenet",
|
|
184
|
+
"classes": 1000,
|
|
185
|
+
"include_top": True,
|
|
186
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnext50_imagenet_1000.h5",
|
|
187
|
+
"name": "resnext50_imagenet_1000.h5",
|
|
188
|
+
"md5": "7c5c40381efb044a8dea5287ab2c83db",
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"model": "resnext50",
|
|
192
|
+
"dataset": "imagenet",
|
|
193
|
+
"classes": 1000,
|
|
194
|
+
"include_top": False,
|
|
195
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnext50_imagenet_1000_no_top.h5",
|
|
196
|
+
"name": "resnext50_imagenet_1000_no_top.h5",
|
|
197
|
+
"md5": "7ade5c8aac9194af79b1724229bdaa50",
|
|
198
|
+
},
|
|
199
|
+
# ResNeXt101
|
|
200
|
+
{
|
|
201
|
+
"model": "resnext101",
|
|
202
|
+
"dataset": "imagenet",
|
|
203
|
+
"classes": 1000,
|
|
204
|
+
"include_top": True,
|
|
205
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnext101_imagenet_1000.h5",
|
|
206
|
+
"name": "resnext101_imagenet_1000.h5",
|
|
207
|
+
"md5": "432536e85ee811568a0851c328182735",
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"model": "resnext101",
|
|
211
|
+
"dataset": "imagenet",
|
|
212
|
+
"classes": 1000,
|
|
213
|
+
"include_top": False,
|
|
214
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/resnext101_imagenet_1000_no_top.h5",
|
|
215
|
+
"name": "resnext101_imagenet_1000_no_top.h5",
|
|
216
|
+
"md5": "91fe0126320e49f6ee607a0719828c7e",
|
|
217
|
+
},
|
|
218
|
+
# SE models
|
|
219
|
+
{
|
|
220
|
+
"model": "seresnet50",
|
|
221
|
+
"dataset": "imagenet",
|
|
222
|
+
"classes": 1000,
|
|
223
|
+
"include_top": True,
|
|
224
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/seresnet50_imagenet_1000.h5",
|
|
225
|
+
"name": "seresnet50_imagenet_1000.h5",
|
|
226
|
+
"md5": "ff0ce1ed5accaad05d113ecef2d29149",
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"model": "seresnet50",
|
|
230
|
+
"dataset": "imagenet",
|
|
231
|
+
"classes": 1000,
|
|
232
|
+
"include_top": False,
|
|
233
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/seresnet50_imagenet_1000_no_top.h5",
|
|
234
|
+
"name": "seresnet50_imagenet_1000_no_top.h5",
|
|
235
|
+
"md5": "043777781b0d5ca756474d60bf115ef1",
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"model": "seresnet101",
|
|
239
|
+
"dataset": "imagenet",
|
|
240
|
+
"classes": 1000,
|
|
241
|
+
"include_top": True,
|
|
242
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/seresnet101_imagenet_1000.h5",
|
|
243
|
+
"name": "seresnet101_imagenet_1000.h5",
|
|
244
|
+
"md5": "5c31adee48c82a66a32dee3d442f5be8",
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"model": "seresnet101",
|
|
248
|
+
"dataset": "imagenet",
|
|
249
|
+
"classes": 1000,
|
|
250
|
+
"include_top": False,
|
|
251
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/seresnet101_imagenet_1000_no_top.h5",
|
|
252
|
+
"name": "seresnet101_imagenet_1000_no_top.h5",
|
|
253
|
+
"md5": "1c373b0c196918713da86951d1239007",
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"model": "seresnet152",
|
|
257
|
+
"dataset": "imagenet",
|
|
258
|
+
"classes": 1000,
|
|
259
|
+
"include_top": True,
|
|
260
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/seresnet152_imagenet_1000.h5",
|
|
261
|
+
"name": "seresnet152_imagenet_1000.h5",
|
|
262
|
+
"md5": "96fc14e3a939d4627b0174a0e80c7371",
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"model": "seresnet152",
|
|
266
|
+
"dataset": "imagenet",
|
|
267
|
+
"classes": 1000,
|
|
268
|
+
"include_top": False,
|
|
269
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/seresnet152_imagenet_1000_no_top.h5",
|
|
270
|
+
"name": "seresnet152_imagenet_1000_no_top.h5",
|
|
271
|
+
"md5": "f58d4c1a511c7445ab9a2c2b83ee4e7b",
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"model": "seresnext50",
|
|
275
|
+
"dataset": "imagenet",
|
|
276
|
+
"classes": 1000,
|
|
277
|
+
"include_top": True,
|
|
278
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/seresnext50_imagenet_1000.h5",
|
|
279
|
+
"name": "seresnext50_imagenet_1000.h5",
|
|
280
|
+
"md5": "5310dcd58ed573aecdab99f8df1121d5",
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"model": "seresnext50",
|
|
284
|
+
"dataset": "imagenet",
|
|
285
|
+
"classes": 1000,
|
|
286
|
+
"include_top": False,
|
|
287
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/seresnext50_imagenet_1000_no_top.h5",
|
|
288
|
+
"name": "seresnext50_imagenet_1000_no_top.h5",
|
|
289
|
+
"md5": "b0f23d2e1cd406d67335fb92d85cc279",
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"model": "seresnext101",
|
|
293
|
+
"dataset": "imagenet",
|
|
294
|
+
"classes": 1000,
|
|
295
|
+
"include_top": True,
|
|
296
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/seresnext101_imagenet_1000.h5",
|
|
297
|
+
"name": "seresnext101_imagenet_1000.h5",
|
|
298
|
+
"md5": "be5b26b697a0f7f11efaa1bb6272fc84",
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
"model": "seresnext101",
|
|
302
|
+
"dataset": "imagenet",
|
|
303
|
+
"classes": 1000,
|
|
304
|
+
"include_top": False,
|
|
305
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/seresnext101_imagenet_1000_no_top.h5",
|
|
306
|
+
"name": "seresnext101_imagenet_1000_no_top.h5",
|
|
307
|
+
"md5": "e48708cbe40071cc3356016c37f6c9c7",
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
"model": "senet154",
|
|
311
|
+
"dataset": "imagenet",
|
|
312
|
+
"classes": 1000,
|
|
313
|
+
"include_top": True,
|
|
314
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/senet154_imagenet_1000.h5",
|
|
315
|
+
"name": "senet154_imagenet_1000.h5",
|
|
316
|
+
"md5": "c8eac0e1940ea4d8a2e0b2eb0cdf4e75",
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
"model": "senet154",
|
|
320
|
+
"dataset": "imagenet",
|
|
321
|
+
"classes": 1000,
|
|
322
|
+
"include_top": False,
|
|
323
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/senet154_imagenet_1000_no_top.h5",
|
|
324
|
+
"name": "senet154_imagenet_1000_no_top.h5",
|
|
325
|
+
"md5": "d854ff2cd7e6a87b05a8124cd283e0f2",
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
"model": "seresnet18",
|
|
329
|
+
"dataset": "imagenet",
|
|
330
|
+
"classes": 1000,
|
|
331
|
+
"include_top": True,
|
|
332
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/seresnet18_imagenet_1000.h5",
|
|
333
|
+
"name": "seresnet18_imagenet_1000.h5",
|
|
334
|
+
"md5": "9a925fd96d050dbf7cc4c54aabfcf749",
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
"model": "seresnet18",
|
|
338
|
+
"dataset": "imagenet",
|
|
339
|
+
"classes": 1000,
|
|
340
|
+
"include_top": False,
|
|
341
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/seresnet18_imagenet_1000_no_top.h5",
|
|
342
|
+
"name": "seresnet18_imagenet_1000_no_top.h5",
|
|
343
|
+
"md5": "a46e5cd4114ac946ecdc58741e8d92ea",
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
"model": "seresnet34",
|
|
347
|
+
"dataset": "imagenet",
|
|
348
|
+
"classes": 1000,
|
|
349
|
+
"include_top": True,
|
|
350
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/seresnet34_imagenet_1000.h5",
|
|
351
|
+
"name": "seresnet34_imagenet_1000.h5",
|
|
352
|
+
"md5": "863976b3bd439ff0cc05c91821218a6b",
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
"model": "seresnet34",
|
|
356
|
+
"dataset": "imagenet",
|
|
357
|
+
"classes": 1000,
|
|
358
|
+
"include_top": False,
|
|
359
|
+
"url": "https://github.com/qubvel/classification_models/releases/download/0.0.1/seresnet34_imagenet_1000_no_top.h5",
|
|
360
|
+
"name": "seresnet34_imagenet_1000_no_top.h5",
|
|
361
|
+
"md5": "3348fd049f1f9ad307c070ff2b6ec4cb",
|
|
362
|
+
},
|
|
363
|
+
]
|
|
@@ -2,6 +2,7 @@ import keras.applications as ka
|
|
|
2
2
|
|
|
3
3
|
from . import inception_resnet_v2 as irv2
|
|
4
4
|
from . import inception_v3 as iv3
|
|
5
|
+
from . import resnet_18_34
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class BackbonesFactory:
|
|
@@ -16,39 +17,42 @@ class BackbonesFactory:
|
|
|
16
17
|
"""
|
|
17
18
|
|
|
18
19
|
_models = { # noqa: RUF012
|
|
19
|
-
# ResNets
|
|
20
|
+
# ResNets < 50 layers are NOT available via keras.applications, so use a
|
|
21
|
+
# torchvision-compatible post-activation BasicBlock implementation.
|
|
22
|
+
# Layer names follow the keras.applications ResNet50+ naming convention.
|
|
23
|
+
"resnet18": (
|
|
24
|
+
resnet_18_34.ResNet18,
|
|
25
|
+
resnet_18_34.preprocess_input,
|
|
26
|
+
# resnet18: layer1=2, layer2=2, layer3=2, layer4=2 blocks
|
|
27
|
+
# backbone output = conv5_block2_out (512ch); skips are the 4 stages before it
|
|
28
|
+
("conv4_block2_out", "conv3_block2_out", "conv2_block2_out", "conv1_relu"),
|
|
29
|
+
),
|
|
30
|
+
"resnet34": (
|
|
31
|
+
resnet_18_34.ResNet34,
|
|
32
|
+
resnet_18_34.preprocess_input,
|
|
33
|
+
# resnet34: layer1=3, layer2=4, layer3=6, layer4=3 blocks
|
|
34
|
+
# backbone output = conv5_block3_out (512ch); skips are the 4 stages before it
|
|
35
|
+
("conv4_block6_out", "conv3_block4_out", "conv2_block3_out", "conv1_relu"),
|
|
36
|
+
),
|
|
37
|
+
# ResNets > 50 layers are available via keras.applications, so use those.
|
|
38
|
+
# Skip layers (inverted) from https://github.com/yingkaisha/keras-unet-collection
|
|
20
39
|
"resnet50": (
|
|
21
40
|
ka.ResNet50,
|
|
22
41
|
ka.resnet.preprocess_input,
|
|
23
|
-
(
|
|
24
|
-
"conv4_block6_out",
|
|
25
|
-
"conv3_block4_out",
|
|
26
|
-
"conv2_block3_out",
|
|
27
|
-
"conv1_relu",
|
|
28
|
-
),
|
|
42
|
+
("conv4_block6_out", "conv3_block4_out", "conv2_block3_out", "conv1_relu"),
|
|
29
43
|
),
|
|
30
44
|
"resnet101": (
|
|
31
45
|
ka.ResNet101,
|
|
32
46
|
ka.resnet.preprocess_input,
|
|
33
|
-
(
|
|
34
|
-
"conv4_block23_out",
|
|
35
|
-
"conv3_block4_out",
|
|
36
|
-
"conv2_block3_out",
|
|
37
|
-
"conv1_relu",
|
|
38
|
-
),
|
|
47
|
+
("conv4_block23_out", "conv3_block4_out", "conv2_block3_out", "conv1_relu"),
|
|
39
48
|
),
|
|
40
49
|
"resnet152": (
|
|
41
50
|
ka.ResNet152,
|
|
42
51
|
ka.resnet.preprocess_input,
|
|
43
|
-
(
|
|
44
|
-
"conv4_block36_out",
|
|
45
|
-
"conv3_block8_out",
|
|
46
|
-
"conv2_block3_out",
|
|
47
|
-
"conv1_relu",
|
|
48
|
-
),
|
|
52
|
+
("conv4_block36_out", "conv3_block8_out", "conv2_block3_out", "conv1_relu"),
|
|
49
53
|
),
|
|
50
54
|
# ResNetV2
|
|
51
|
-
#
|
|
55
|
+
# Skip layers (inverted) from https://github.com/yingkaisha/keras-unet-collection
|
|
52
56
|
"resnet50v2": (
|
|
53
57
|
ka.ResNet50V2,
|
|
54
58
|
ka.resnet_v2.preprocess_input,
|
|
@@ -80,6 +84,7 @@ class BackbonesFactory:
|
|
|
80
84
|
),
|
|
81
85
|
),
|
|
82
86
|
# VGG
|
|
87
|
+
# Skip layers from segmentation_models
|
|
83
88
|
"vgg16": (
|
|
84
89
|
ka.vgg16.VGG16,
|
|
85
90
|
ka.vgg16.preprocess_input,
|
|
@@ -103,6 +108,7 @@ class BackbonesFactory:
|
|
|
103
108
|
),
|
|
104
109
|
),
|
|
105
110
|
# DenseNet
|
|
111
|
+
# Skip layers (inverted) from https://github.com/yingkaisha/keras-unet-collection
|
|
106
112
|
"densenet121": (
|
|
107
113
|
ka.densenet.DenseNet121,
|
|
108
114
|
ka.densenet.preprocess_input,
|
|
@@ -122,6 +128,7 @@ class BackbonesFactory:
|
|
|
122
128
|
("pool4_conv", "pool3_conv", "pool2_conv", "conv1/relu"),
|
|
123
129
|
),
|
|
124
130
|
# Inception
|
|
131
|
+
# Skip layers from segmentation_models
|
|
125
132
|
"inceptionresnetv2": (
|
|
126
133
|
irv2.InceptionResNetV2,
|
|
127
134
|
irv2.preprocess_input,
|
|
@@ -138,6 +145,7 @@ class BackbonesFactory:
|
|
|
138
145
|
),
|
|
139
146
|
"inceptionv3": (iv3.InceptionV3, iv3.preprocess_input, (228, 86, 16, 9)),
|
|
140
147
|
# MobileNet
|
|
148
|
+
# Skip layers from segmentation_models
|
|
141
149
|
"mobilenet": (
|
|
142
150
|
ka.mobilenet.MobileNet,
|
|
143
151
|
ka.mobilenet.preprocess_input,
|
|
@@ -158,6 +166,8 @@ class BackbonesFactory:
|
|
|
158
166
|
"block_1_expand_relu",
|
|
159
167
|
),
|
|
160
168
|
),
|
|
169
|
+
# EfficientNet
|
|
170
|
+
# Skip layers from segmentation_models
|
|
161
171
|
"efficientnetb0": [
|
|
162
172
|
ka.EfficientNetB0,
|
|
163
173
|
ka.efficientnet.preprocess_input,
|
|
@@ -239,7 +249,7 @@ class BackbonesFactory:
|
|
|
239
249
|
),
|
|
240
250
|
],
|
|
241
251
|
# EfficientNetV2
|
|
242
|
-
#
|
|
252
|
+
# Skip layers from https://github.com/chinefed/segmentation_models_fork
|
|
243
253
|
"efficientnetv2m": (
|
|
244
254
|
ka.EfficientNetV2M,
|
|
245
255
|
ka.efficientnet_v2.preprocess_input,
|