segmodels-keras 0.1.0.dev9__tar.gz → 0.1.0.dev10__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.dev9 → segmodels_keras-0.1.0.dev10}/PKG-INFO +1 -1
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/pyproject.toml +4 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/__init__.py +20 -16
- segmodels_keras-0.1.0.dev10/segmodels_keras/_compat.py +6 -0
- segmodels_keras-0.1.0.dev10/segmodels_keras/_version.py +2 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/backbones/_weights.py +2 -1
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/backbones/backbones_factory.py +2 -2
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/backbones/inception_resnet_v2.py +1 -2
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/backbones/inception_v3.py +1 -1
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/backbones/resnet_18_34.py +2 -3
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/base/functional.py +9 -5
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/base/objects.py +26 -23
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/losses.py +27 -19
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/metrics.py +37 -35
- segmodels_keras-0.1.0.dev10/segmodels_keras/models/__init__.py +5 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/models/fpn.py +46 -34
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/models/linknet.py +53 -33
- segmodels_keras-0.1.0.dev10/segmodels_keras/models/model_factory.py +96 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/models/pspnet.py +51 -36
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/models/unet.py +48 -32
- segmodels_keras-0.1.0.dev10/segmodels_keras/utils.py +311 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras.egg-info/PKG-INFO +1 -1
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras.egg-info/SOURCES.txt +3 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/setup.py +2 -1
- segmodels_keras-0.1.0.dev10/tests/test_helper.py +3 -0
- segmodels_keras-0.1.0.dev10/tests/test_models.py +115 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/tests/test_utils.py +15 -23
- segmodels_keras-0.1.0.dev9/segmodels_keras/_compat.py +0 -123
- segmodels_keras-0.1.0.dev9/segmodels_keras/_version.py +0 -2
- segmodels_keras-0.1.0.dev9/segmodels_keras/utils.py +0 -117
- segmodels_keras-0.1.0.dev9/tests/test_models.py +0 -128
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/LICENSE +0 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/MANIFEST.in +0 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/README.rst +0 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/backbones/__init__.py +0 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/backbones/_common_blocks.py +0 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/backbones/resnet_common.py +0 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/base/__init__.py +0 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/models/_common_blocks.py +0 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/models/_utils.py +0 -0
- /segmodels_keras-0.1.0.dev9/segmodels_keras/models/__init__.py → /segmodels_keras-0.1.0.dev10/segmodels_keras/py.typed +0 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras.egg-info/dependency_links.txt +0 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras.egg-info/requires.txt +0 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras.egg-info/top_level.txt +0 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/setup.cfg +0 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/tests/test_backbones.py +0 -0
- {segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/tests/test_metrics.py +0 -0
|
@@ -1,35 +1,37 @@
|
|
|
1
1
|
import functools # noqa: I001
|
|
2
2
|
import os
|
|
3
|
+
from typing import Any
|
|
4
|
+
from collections.abc import Callable
|
|
3
5
|
|
|
4
6
|
# __version__ should be defined as soon as possible
|
|
5
7
|
from ._version import __version__
|
|
6
8
|
|
|
7
9
|
from . import base
|
|
8
10
|
|
|
9
|
-
_KERAS_FRAMEWORK_NAME = "keras"
|
|
10
|
-
_TF_KERAS_FRAMEWORK_NAME = "tf.keras"
|
|
11
|
+
_KERAS_FRAMEWORK_NAME: str = "keras"
|
|
12
|
+
_TF_KERAS_FRAMEWORK_NAME: str = "tf.keras"
|
|
11
13
|
|
|
12
|
-
_DEFAULT_KERAS_FRAMEWORK = _KERAS_FRAMEWORK_NAME
|
|
13
|
-
_KERAS_FRAMEWORK = None
|
|
14
|
-
_KERAS_BACKEND = None
|
|
15
|
-
_KERAS_LAYERS = None
|
|
16
|
-
_KERAS_MODELS = None
|
|
17
|
-
_KERAS_UTILS = None
|
|
18
|
-
_KERAS_LOSSES = None
|
|
14
|
+
_DEFAULT_KERAS_FRAMEWORK: str = _KERAS_FRAMEWORK_NAME
|
|
15
|
+
_KERAS_FRAMEWORK: str | None = None
|
|
16
|
+
_KERAS_BACKEND: Any = None
|
|
17
|
+
_KERAS_LAYERS: Any = None
|
|
18
|
+
_KERAS_MODELS: Any = None
|
|
19
|
+
_KERAS_UTILS: Any = None
|
|
20
|
+
_KERAS_LOSSES: Any = None
|
|
19
21
|
|
|
20
22
|
|
|
21
|
-
def inject_global_losses(func):
|
|
23
|
+
def inject_global_losses(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
22
24
|
@functools.wraps(func)
|
|
23
|
-
def wrapper(*args, **kwargs):
|
|
25
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
24
26
|
kwargs["losses"] = _KERAS_LOSSES
|
|
25
27
|
return func(*args, **kwargs)
|
|
26
28
|
|
|
27
29
|
return wrapper
|
|
28
30
|
|
|
29
31
|
|
|
30
|
-
def filter_kwargs(func):
|
|
32
|
+
def filter_kwargs(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
31
33
|
@functools.wraps(func)
|
|
32
|
-
def wrapper(*args, **kwargs):
|
|
34
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
33
35
|
new_kwargs = {
|
|
34
36
|
k: v
|
|
35
37
|
for k, v in kwargs.items()
|
|
@@ -40,12 +42,12 @@ def filter_kwargs(func):
|
|
|
40
42
|
return wrapper
|
|
41
43
|
|
|
42
44
|
|
|
43
|
-
def framework():
|
|
45
|
+
def framework() -> str | None:
|
|
44
46
|
"""Return name of Segmentation Models framework"""
|
|
45
47
|
return _KERAS_FRAMEWORK
|
|
46
48
|
|
|
47
49
|
|
|
48
|
-
def set_framework(name):
|
|
50
|
+
def set_framework(name: str) -> None:
|
|
49
51
|
"""Set framework for Segmentation Models
|
|
50
52
|
|
|
51
53
|
Args:
|
|
@@ -108,13 +110,14 @@ from . import losses, metrics, utils
|
|
|
108
110
|
from .backbones.backbones_factory import Backbones
|
|
109
111
|
from .models.fpn import FPN
|
|
110
112
|
from .models.linknet import Linknet
|
|
113
|
+
from .models.model_factory import get_model
|
|
111
114
|
from .models.pspnet import PSPNet
|
|
112
115
|
from .models.unet import Unet
|
|
113
116
|
|
|
114
117
|
get_available_backbone_names = Backbones.models_names
|
|
115
118
|
|
|
116
119
|
|
|
117
|
-
def get_preprocessing(name):
|
|
120
|
+
def get_preprocessing(name: str) -> Callable[[Any], Any]:
|
|
118
121
|
return Backbones.get_preprocessing(name)
|
|
119
122
|
|
|
120
123
|
|
|
@@ -126,6 +129,7 @@ __all__ = [
|
|
|
126
129
|
"__version__",
|
|
127
130
|
"framework",
|
|
128
131
|
"get_available_backbone_names",
|
|
132
|
+
"get_model",
|
|
129
133
|
"get_preprocessing",
|
|
130
134
|
"losses",
|
|
131
135
|
"metrics",
|
|
@@ -24,14 +24,14 @@ class BackbonesFactory:
|
|
|
24
24
|
resnet_18_34.ResNet18,
|
|
25
25
|
resnet_18_34.preprocess_input,
|
|
26
26
|
# resnet18: layer1=2, layer2=2, layer3=2, layer4=2 blocks
|
|
27
|
-
# backbone output = conv5_block2_out (512ch); skips are the 4 stages before
|
|
27
|
+
# backbone output = conv5_block2_out (512ch); skips are the 4 stages before
|
|
28
28
|
("conv4_block2_out", "conv3_block2_out", "conv2_block2_out", "conv1_relu"),
|
|
29
29
|
),
|
|
30
30
|
"resnet34": (
|
|
31
31
|
resnet_18_34.ResNet34,
|
|
32
32
|
resnet_18_34.preprocess_input,
|
|
33
33
|
# resnet34: layer1=3, layer2=4, layer3=6, layer4=3 blocks
|
|
34
|
-
# backbone output = conv5_block3_out (512ch); skips are the 4 stages before
|
|
34
|
+
# backbone output = conv5_block3_out (512ch); skips are the 4 stages before
|
|
35
35
|
("conv4_block6_out", "conv3_block4_out", "conv2_block3_out", "conv1_relu"),
|
|
36
36
|
),
|
|
37
37
|
# ResNets > 50 layers are available via keras.applications, so use those.
|
|
@@ -38,8 +38,7 @@ from keras import backend, layers, models
|
|
|
38
38
|
from keras.applications import imagenet_utils
|
|
39
39
|
from keras.utils import get_file, get_source_inputs
|
|
40
40
|
|
|
41
|
-
from
|
|
42
|
-
|
|
41
|
+
from ..utils import load_weights
|
|
43
42
|
from .resnet_common import _obtain_input_shape
|
|
44
43
|
|
|
45
44
|
BASE_WEIGHT_URL = (
|
{segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/backbones/inception_v3.py
RENAMED
|
@@ -14,7 +14,7 @@ from keras import backend, layers, models
|
|
|
14
14
|
from keras import utils as keras_utils
|
|
15
15
|
from keras.applications import imagenet_utils
|
|
16
16
|
|
|
17
|
-
from
|
|
17
|
+
from ..utils import load_weights
|
|
18
18
|
|
|
19
19
|
WEIGHTS_PATH = (
|
|
20
20
|
"https://github.com/fchollet/deep-learning-models/"
|
{segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/backbones/resnet_18_34.py
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
"""ResNet18 and ResNet34 Keras models.
|
|
2
2
|
|
|
3
3
|
Complements keras.applications (which provides ResNet50+) with BasicBlock-based
|
|
4
4
|
ResNet18 and ResNet34. The implementation follows the keras.applications structure
|
|
@@ -38,8 +38,7 @@ from keras import backend, layers, models
|
|
|
38
38
|
from keras.applications import imagenet_utils
|
|
39
39
|
from keras.utils import get_source_inputs
|
|
40
40
|
|
|
41
|
-
from
|
|
42
|
-
|
|
41
|
+
from ..utils import load_weights
|
|
43
42
|
from .resnet_common import _obtain_input_shape
|
|
44
43
|
|
|
45
44
|
momentum = 0.99
|
{segmodels_keras-0.1.0.dev9 → segmodels_keras-0.1.0.dev10}/segmodels_keras/base/functional.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
1
3
|
import keras
|
|
2
4
|
|
|
3
5
|
from segmodels_keras._compat import KERAS_GTE_3
|
|
@@ -7,7 +9,7 @@ if KERAS_GTE_3:
|
|
|
7
9
|
else:
|
|
8
10
|
from keras import backend as ops
|
|
9
11
|
|
|
10
|
-
SMOOTH = 1e-5
|
|
12
|
+
SMOOTH: float = 1e-5
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
# ----------------------------------------------------------------
|
|
@@ -15,7 +17,7 @@ SMOOTH = 1e-5
|
|
|
15
17
|
# ----------------------------------------------------------------
|
|
16
18
|
|
|
17
19
|
|
|
18
|
-
def _gather_channels(x, indexes, **kwargs):
|
|
20
|
+
def _gather_channels(x: Any, indexes: Any, **kwargs: Any) -> Any:
|
|
19
21
|
backend = kwargs["backend"]
|
|
20
22
|
|
|
21
23
|
"""Slice tensor along channels axis by given indexes"""
|
|
@@ -30,7 +32,7 @@ def _gather_channels(x, indexes, **kwargs):
|
|
|
30
32
|
return x
|
|
31
33
|
|
|
32
34
|
|
|
33
|
-
def get_reduce_axes(per_image, **kwargs):
|
|
35
|
+
def get_reduce_axes(per_image: bool, **kwargs: Any) -> list[int]:
|
|
34
36
|
backend = kwargs["backend"]
|
|
35
37
|
|
|
36
38
|
axes = [1, 2] if backend.image_data_format() == "channels_last" else [2, 3]
|
|
@@ -39,13 +41,15 @@ def get_reduce_axes(per_image, **kwargs):
|
|
|
39
41
|
return axes
|
|
40
42
|
|
|
41
43
|
|
|
42
|
-
def gather_channels(
|
|
44
|
+
def gather_channels(
|
|
45
|
+
*xs: Any, indexes: int | list[int] | None = None, **kwargs: Any
|
|
46
|
+
) -> tuple[Any, ...] | tuple[Any]:
|
|
43
47
|
"""Slice tensors along channels axis by given indexes"""
|
|
44
48
|
if indexes is None:
|
|
45
49
|
return xs
|
|
46
50
|
elif isinstance(indexes, (int)):
|
|
47
51
|
indexes = [indexes]
|
|
48
|
-
xs =
|
|
52
|
+
xs = tuple(_gather_channels(x, indexes=indexes, **kwargs) for x in xs)
|
|
49
53
|
return xs
|
|
50
54
|
|
|
51
55
|
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
class KerasObject:
|
|
2
|
-
_backend = None
|
|
3
|
-
_models = None
|
|
4
|
-
_layers = None
|
|
5
|
-
_utils = None
|
|
5
|
+
_backend: Any = None
|
|
6
|
+
_models: Any = None
|
|
7
|
+
_layers: Any = None
|
|
8
|
+
_utils: Any = None
|
|
6
9
|
|
|
7
|
-
def __init__(self, name=None):
|
|
10
|
+
def __init__(self, name: str | None = None) -> None:
|
|
8
11
|
if (
|
|
9
12
|
self.backend is None
|
|
10
13
|
or self.utils is None
|
|
@@ -16,28 +19,28 @@ class KerasObject:
|
|
|
16
19
|
self._name = name
|
|
17
20
|
|
|
18
21
|
@property
|
|
19
|
-
def __name__(self):
|
|
22
|
+
def __name__(self) -> str:
|
|
20
23
|
if self._name is None:
|
|
21
|
-
return self.__class__.__name__
|
|
24
|
+
return self.__class__.__name__ # type: ignore[return-value]
|
|
22
25
|
return self._name
|
|
23
26
|
|
|
24
27
|
@property
|
|
25
|
-
def name(self):
|
|
28
|
+
def name(self) -> str:
|
|
26
29
|
return self.__name__
|
|
27
30
|
|
|
28
31
|
@name.setter
|
|
29
|
-
def name(self, name):
|
|
32
|
+
def name(self, name: str) -> None:
|
|
30
33
|
self._name = name
|
|
31
34
|
|
|
32
35
|
@classmethod
|
|
33
|
-
def set_submodules(cls, backend, layers, models, utils):
|
|
36
|
+
def set_submodules(cls, backend: Any, layers: Any, models: Any, utils: Any) -> None:
|
|
34
37
|
cls._backend = backend
|
|
35
38
|
cls._layers = layers
|
|
36
39
|
cls._models = models
|
|
37
40
|
cls._utils = utils
|
|
38
41
|
|
|
39
42
|
@property
|
|
40
|
-
def submodules(self):
|
|
43
|
+
def submodules(self) -> dict[str, Any]:
|
|
41
44
|
return {
|
|
42
45
|
"backend": self.backend,
|
|
43
46
|
"layers": self.layers,
|
|
@@ -46,19 +49,19 @@ class KerasObject:
|
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
@property
|
|
49
|
-
def backend(self):
|
|
52
|
+
def backend(self) -> Any:
|
|
50
53
|
return self._backend
|
|
51
54
|
|
|
52
55
|
@property
|
|
53
|
-
def layers(self):
|
|
56
|
+
def layers(self) -> Any:
|
|
54
57
|
return self._layers
|
|
55
58
|
|
|
56
59
|
@property
|
|
57
|
-
def models(self):
|
|
60
|
+
def models(self) -> Any:
|
|
58
61
|
return self._models
|
|
59
62
|
|
|
60
63
|
@property
|
|
61
|
-
def utils(self):
|
|
64
|
+
def utils(self) -> Any:
|
|
62
65
|
return self._utils
|
|
63
66
|
|
|
64
67
|
|
|
@@ -67,27 +70,27 @@ class Metric(KerasObject):
|
|
|
67
70
|
|
|
68
71
|
|
|
69
72
|
class Loss(KerasObject):
|
|
70
|
-
def __add__(self, other):
|
|
73
|
+
def __add__(self, other: Any) -> Any:
|
|
71
74
|
if isinstance(other, Loss):
|
|
72
75
|
return SumOfLosses(self, other)
|
|
73
76
|
else:
|
|
74
77
|
raise ValueError("Loss should be inherited from `Loss` class")
|
|
75
78
|
|
|
76
|
-
def __radd__(self, other):
|
|
79
|
+
def __radd__(self, other: Any) -> Any:
|
|
77
80
|
return self.__add__(other)
|
|
78
81
|
|
|
79
|
-
def __mul__(self, value):
|
|
82
|
+
def __mul__(self, value: int | float) -> Any:
|
|
80
83
|
if isinstance(value, (int, float)):
|
|
81
84
|
return MultipliedLoss(self, value)
|
|
82
85
|
else:
|
|
83
86
|
raise ValueError("Loss should be inherited from `BaseLoss` class")
|
|
84
87
|
|
|
85
|
-
def __rmul__(self, other):
|
|
88
|
+
def __rmul__(self, other: Any) -> Any:
|
|
86
89
|
return self.__mul__(other)
|
|
87
90
|
|
|
88
91
|
|
|
89
92
|
class MultipliedLoss(Loss):
|
|
90
|
-
def __init__(self, loss, multiplier):
|
|
93
|
+
def __init__(self, loss: Any, multiplier: int | float) -> None:
|
|
91
94
|
|
|
92
95
|
# resolve name
|
|
93
96
|
if len(loss.__name__.split("+")) > 1:
|
|
@@ -98,16 +101,16 @@ class MultipliedLoss(Loss):
|
|
|
98
101
|
self.loss = loss
|
|
99
102
|
self.multiplier = multiplier
|
|
100
103
|
|
|
101
|
-
def __call__(self, gt, pr):
|
|
104
|
+
def __call__(self, gt: Any, pr: Any) -> Any:
|
|
102
105
|
return self.multiplier * self.loss(gt, pr)
|
|
103
106
|
|
|
104
107
|
|
|
105
108
|
class SumOfLosses(Loss):
|
|
106
|
-
def __init__(self, l1, l2):
|
|
109
|
+
def __init__(self, l1: Any, l2: Any) -> None:
|
|
107
110
|
name = f"{l1.__name__}_plus_{l2.__name__}"
|
|
108
111
|
super().__init__(name=name)
|
|
109
112
|
self.l1 = l1
|
|
110
113
|
self.l2 = l2
|
|
111
114
|
|
|
112
|
-
def __call__(self, gt, pr):
|
|
115
|
+
def __call__(self, gt: Any, pr: Any) -> Any:
|
|
113
116
|
return self.l1(gt, pr) + self.l2(gt, pr)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
1
3
|
from .base import Loss
|
|
2
4
|
from .base import functional as F
|
|
3
5
|
|
|
4
|
-
SMOOTH = 1e-5
|
|
6
|
+
SMOOTH: float = 1e-5
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
class JaccardLoss(Loss):
|
|
@@ -32,8 +34,12 @@ class JaccardLoss(Loss):
|
|
|
32
34
|
"""
|
|
33
35
|
|
|
34
36
|
def __init__(
|
|
35
|
-
self,
|
|
36
|
-
|
|
37
|
+
self,
|
|
38
|
+
class_weights: Any = None,
|
|
39
|
+
class_indexes: Any = None,
|
|
40
|
+
per_image: bool = False,
|
|
41
|
+
smooth: float = SMOOTH,
|
|
42
|
+
) -> None:
|
|
37
43
|
super().__init__(name="jaccard_loss")
|
|
38
44
|
self.class_weights = class_weights if class_weights is not None else 1
|
|
39
45
|
self.class_indexes = class_indexes
|
|
@@ -92,12 +98,12 @@ class DiceLoss(Loss):
|
|
|
92
98
|
|
|
93
99
|
def __init__(
|
|
94
100
|
self,
|
|
95
|
-
beta=1,
|
|
96
|
-
class_weights=None,
|
|
97
|
-
class_indexes=None,
|
|
98
|
-
per_image=False,
|
|
99
|
-
smooth=SMOOTH,
|
|
100
|
-
):
|
|
101
|
+
beta: int | float = 1,
|
|
102
|
+
class_weights: Any = None,
|
|
103
|
+
class_indexes: Any = None,
|
|
104
|
+
per_image: bool = False,
|
|
105
|
+
smooth: float = SMOOTH,
|
|
106
|
+
) -> None:
|
|
101
107
|
super().__init__(name="dice_loss")
|
|
102
108
|
self.beta = beta
|
|
103
109
|
self.class_weights = class_weights if class_weights is not None else 1
|
|
@@ -137,7 +143,7 @@ class BinaryCELoss(Loss):
|
|
|
137
143
|
model.compile('SGD', loss=loss)
|
|
138
144
|
"""
|
|
139
145
|
|
|
140
|
-
def __init__(self):
|
|
146
|
+
def __init__(self) -> None:
|
|
141
147
|
super().__init__(name="binary_crossentropy")
|
|
142
148
|
|
|
143
149
|
def __call__(self, gt, pr):
|
|
@@ -168,7 +174,7 @@ class CategoricalCELoss(Loss):
|
|
|
168
174
|
model.compile('SGD', loss=loss)
|
|
169
175
|
"""
|
|
170
176
|
|
|
171
|
-
def __init__(self, class_weights=None, class_indexes=None):
|
|
177
|
+
def __init__(self, class_weights: Any = None, class_indexes: Any = None) -> None:
|
|
172
178
|
super().__init__(name="categorical_crossentropy")
|
|
173
179
|
self.class_weights = class_weights if class_weights is not None else 1
|
|
174
180
|
self.class_indexes = class_indexes
|
|
@@ -209,7 +215,9 @@ class CategoricalFocalLoss(Loss):
|
|
|
209
215
|
model.compile('SGD', loss=loss)
|
|
210
216
|
"""
|
|
211
217
|
|
|
212
|
-
def __init__(
|
|
218
|
+
def __init__(
|
|
219
|
+
self, alpha: float = 0.25, gamma: float = 2.0, class_indexes: Any = None
|
|
220
|
+
) -> None:
|
|
213
221
|
super().__init__(name="focal_loss")
|
|
214
222
|
self.alpha = alpha
|
|
215
223
|
self.gamma = gamma
|
|
@@ -250,7 +258,7 @@ class BinaryFocalLoss(Loss):
|
|
|
250
258
|
model.compile('SGD', loss=loss)
|
|
251
259
|
""" # noqa: E501
|
|
252
260
|
|
|
253
|
-
def __init__(self, alpha=0.25, gamma=2.0):
|
|
261
|
+
def __init__(self, alpha: float = 0.25, gamma: float = 2.0) -> None:
|
|
254
262
|
super().__init__(name="binary_focal_loss")
|
|
255
263
|
self.alpha = alpha
|
|
256
264
|
self.gamma = gamma
|
|
@@ -262,14 +270,14 @@ class BinaryFocalLoss(Loss):
|
|
|
262
270
|
|
|
263
271
|
|
|
264
272
|
# aliases
|
|
265
|
-
jaccard_loss = JaccardLoss()
|
|
266
|
-
dice_loss = DiceLoss()
|
|
273
|
+
jaccard_loss: JaccardLoss = JaccardLoss()
|
|
274
|
+
dice_loss: DiceLoss = DiceLoss()
|
|
267
275
|
|
|
268
|
-
binary_focal_loss = BinaryFocalLoss()
|
|
269
|
-
categorical_focal_loss = CategoricalFocalLoss()
|
|
276
|
+
binary_focal_loss: BinaryFocalLoss = BinaryFocalLoss()
|
|
277
|
+
categorical_focal_loss: CategoricalFocalLoss = CategoricalFocalLoss()
|
|
270
278
|
|
|
271
|
-
binary_crossentropy = BinaryCELoss()
|
|
272
|
-
categorical_crossentropy = CategoricalCELoss()
|
|
279
|
+
binary_crossentropy: BinaryCELoss = BinaryCELoss()
|
|
280
|
+
categorical_crossentropy: CategoricalCELoss = CategoricalCELoss()
|
|
273
281
|
|
|
274
282
|
# loss combinations
|
|
275
283
|
bce_dice_loss = binary_crossentropy + dice_loss
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
1
3
|
from .base import Metric
|
|
2
4
|
from .base import functional as F
|
|
3
5
|
|
|
4
|
-
SMOOTH = 1e-5
|
|
6
|
+
SMOOTH: float = 1e-5
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
class IOUScore(Metric):
|
|
@@ -41,13 +43,13 @@ class IOUScore(Metric):
|
|
|
41
43
|
|
|
42
44
|
def __init__(
|
|
43
45
|
self,
|
|
44
|
-
class_weights=None,
|
|
45
|
-
class_indexes=None,
|
|
46
|
-
threshold=None,
|
|
47
|
-
per_image=False,
|
|
48
|
-
smooth=SMOOTH,
|
|
49
|
-
name=None,
|
|
50
|
-
):
|
|
46
|
+
class_weights: Any = None,
|
|
47
|
+
class_indexes: Any = None,
|
|
48
|
+
threshold: int | float | None = None,
|
|
49
|
+
per_image: bool = False,
|
|
50
|
+
smooth: float = SMOOTH,
|
|
51
|
+
name: str | None = None,
|
|
52
|
+
) -> None:
|
|
51
53
|
name = name or "iou_score"
|
|
52
54
|
super().__init__(name=name)
|
|
53
55
|
self.class_weights = class_weights if class_weights is not None else 1
|
|
@@ -115,14 +117,14 @@ class FScore(Metric):
|
|
|
115
117
|
|
|
116
118
|
def __init__(
|
|
117
119
|
self,
|
|
118
|
-
beta=1,
|
|
119
|
-
class_weights=None,
|
|
120
|
-
class_indexes=None,
|
|
121
|
-
threshold=None,
|
|
122
|
-
per_image=False,
|
|
123
|
-
smooth=SMOOTH,
|
|
124
|
-
name=None,
|
|
125
|
-
):
|
|
120
|
+
beta: int | float = 1,
|
|
121
|
+
class_weights: Any = None,
|
|
122
|
+
class_indexes: Any = None,
|
|
123
|
+
threshold: int | float | None = None,
|
|
124
|
+
per_image: bool = False,
|
|
125
|
+
smooth: float = SMOOTH,
|
|
126
|
+
name: str | None = None,
|
|
127
|
+
) -> None:
|
|
126
128
|
name = name or f"f{beta}-score"
|
|
127
129
|
super().__init__(name=name)
|
|
128
130
|
self.beta = beta
|
|
@@ -182,13 +184,13 @@ class Precision(Metric):
|
|
|
182
184
|
|
|
183
185
|
def __init__(
|
|
184
186
|
self,
|
|
185
|
-
class_weights=None,
|
|
186
|
-
class_indexes=None,
|
|
187
|
-
threshold=None,
|
|
188
|
-
per_image=False,
|
|
189
|
-
smooth=SMOOTH,
|
|
190
|
-
name=None,
|
|
191
|
-
):
|
|
187
|
+
class_weights: Any = None,
|
|
188
|
+
class_indexes: Any = None,
|
|
189
|
+
threshold: int | float | None = None,
|
|
190
|
+
per_image: bool = False,
|
|
191
|
+
smooth: float = SMOOTH,
|
|
192
|
+
name: str | None = None,
|
|
193
|
+
) -> None:
|
|
192
194
|
name = name or "precision"
|
|
193
195
|
super().__init__(name=name)
|
|
194
196
|
self.class_weights = class_weights if class_weights is not None else 1
|
|
@@ -245,13 +247,13 @@ class Recall(Metric):
|
|
|
245
247
|
|
|
246
248
|
def __init__(
|
|
247
249
|
self,
|
|
248
|
-
class_weights=None,
|
|
249
|
-
class_indexes=None,
|
|
250
|
-
threshold=None,
|
|
251
|
-
per_image=False,
|
|
252
|
-
smooth=SMOOTH,
|
|
253
|
-
name=None,
|
|
254
|
-
):
|
|
250
|
+
class_weights: Any = None,
|
|
251
|
+
class_indexes: Any = None,
|
|
252
|
+
threshold: int | float | None = None,
|
|
253
|
+
per_image: bool = False,
|
|
254
|
+
smooth: float = SMOOTH,
|
|
255
|
+
name: str | None = None,
|
|
256
|
+
) -> None:
|
|
255
257
|
name = name or "recall"
|
|
256
258
|
super().__init__(name=name)
|
|
257
259
|
self.class_weights = class_weights if class_weights is not None else 1
|
|
@@ -274,8 +276,8 @@ class Recall(Metric):
|
|
|
274
276
|
|
|
275
277
|
|
|
276
278
|
# aliases
|
|
277
|
-
iou_score = IOUScore()
|
|
278
|
-
f1_score = FScore(beta=1)
|
|
279
|
-
f2_score = FScore(beta=2)
|
|
280
|
-
precision = Precision()
|
|
281
|
-
recall = Recall()
|
|
279
|
+
iou_score: IOUScore = IOUScore()
|
|
280
|
+
f1_score: FScore = FScore(beta=1)
|
|
281
|
+
f2_score: FScore = FScore(beta=2)
|
|
282
|
+
precision: Precision = Precision()
|
|
283
|
+
recall: Recall = Recall()
|