segmodels-keras 0.1.0.dev0__tar.gz → 0.1.0.dev2__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.
Files changed (39) hide show
  1. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/PKG-INFO +3 -2
  2. segmodels_keras-0.1.0.dev2/README.rst +53 -0
  3. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/__init__.py +5 -3
  4. segmodels_keras-0.1.0.dev2/segmodels_keras/_compat.py +4 -0
  5. segmodels_keras-0.1.0.dev2/segmodels_keras/_version.py +2 -0
  6. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/backbones/backbones_factory.py +8 -1
  7. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/backbones/inception_resnet_v2.py +298 -217
  8. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/base/functional.py +2 -1
  9. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras.egg-info/PKG-INFO +3 -2
  10. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras.egg-info/SOURCES.txt +1 -1
  11. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras.egg-info/requires.txt +1 -0
  12. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/setup.py +4 -4
  13. segmodels_keras-0.1.0.dev0/README.rst +0 -260
  14. segmodels_keras-0.1.0.dev0/segmodels_keras/__version__.py +0 -3
  15. segmodels_keras-0.1.0.dev0/segmodels_keras/_compat.py +0 -3
  16. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/LICENSE +0 -0
  17. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/MANIFEST.in +0 -0
  18. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/pyproject.toml +0 -0
  19. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/backbones/__init__.py +0 -0
  20. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/backbones/inception_v3.py +0 -0
  21. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/base/__init__.py +0 -0
  22. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/base/objects.py +0 -0
  23. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/losses.py +0 -0
  24. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/metrics.py +0 -0
  25. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/models/__init__.py +0 -0
  26. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/models/_common_blocks.py +0 -0
  27. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/models/_utils.py +0 -0
  28. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/models/fpn.py +0 -0
  29. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/models/linknet.py +0 -0
  30. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/models/pspnet.py +0 -0
  31. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/models/unet.py +0 -0
  32. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras/utils.py +0 -0
  33. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras.egg-info/dependency_links.txt +0 -0
  34. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/segmodels_keras.egg-info/top_level.txt +0 -0
  35. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/setup.cfg +0 -0
  36. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/tests/test_backbones.py +0 -0
  37. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/tests/test_metrics.py +0 -0
  38. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/tests/test_models.py +0 -0
  39. {segmodels_keras-0.1.0.dev0 → segmodels_keras-0.1.0.dev2}/tests/test_utils.py +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: segmodels_keras
3
- Version: 0.1.0.dev0
3
+ Version: 0.1.0.dev2
4
4
  Summary: Image segmentation models with pre-trained backbones with Keras.
5
- Home-page: https://github.com/theroggy/segmodels_keras
5
+ Home-page: https://github.com/orthoseg/segmodels_keras
6
6
  Author: Pieter Roggemans
7
7
  Author-email: pieter.roggemans@gmail.com
8
8
  License: MIT
@@ -15,6 +15,7 @@ Requires-Python: >=3.0.0
15
15
  Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
17
  Requires-Dist: keras
18
+ Requires-Dist: packaging
18
19
  Provides-Extra: tests
19
20
  Requires-Dist: numpy; extra == "tests"
20
21
  Requires-Dist: pytest; extra == "tests"
@@ -0,0 +1,53 @@
1
+ |Actions Status| |PyPI version|
2
+
3
+ .. |Actions Status| image:: https://github.com/orthoseg/segmodels_keras/actions/workflows/tests.yml/badge.svg?branch=main
4
+ :target: https://github.com/orthoseg/segmodels_keras/actions/workflows/tests.yml?query=workflow%3ATests
5
+
6
+ .. |PyPI version| image:: https://img.shields.io/pypi/v/segmodels-keras.svg
7
+ :target: https://pypi.org/project/segmodels-keras
8
+
9
+
10
+ ###############
11
+ segmodels_keras
12
+ ###############
13
+
14
+ This is a fork of the
15
+ `segmentation_models <https://github.com/qubvel/segmentation_models>`__ library by
16
+ Pavel Iakubovskii, which is not maintained anymore.
17
+
18
+ This fork is updated to support Keras 3, and also contains some bug fixes, some
19
+ improvements and support for some extra backbone models.
20
+
21
+ It is not meant as a full replacement of the original library, but rather as a
22
+ solution for a library I developed and depended on segmentation_models:
23
+ `orthoseg <https://github.com/orthoseg/orthoseg>`__ . Hence, full backwards
24
+ compatibility,... or support for all features is not guaranteed.
25
+
26
+
27
+ **The main features** of this library are:
28
+
29
+ - High level API (just two lines of code to create model for segmentation)
30
+ - **4** models architectures for binary and multi-class image segmentation
31
+ (including legendary **Unet**)
32
+ - **20+** available backbones for each architecture
33
+ - All backbones have **pre-trained** weights for faster and better convergence
34
+ - Helpful segmentation losses (Jaccard, Dice, Focal) and metrics (IoU, F-score)
35
+
36
+ Documentation
37
+ ~~~~~~~~~~~~~
38
+ The **documentation** of the current stable version is available here:
39
+ `Read the docs, stable <https://segmodels_keras.readthedocs.io/en/stable/>`__.
40
+
41
+ The lastest version of the documentation (= of the main branch) can be found here:
42
+ `Read the docs, latest <https://segmodels_keras.readthedocs.io/en/latest/>`__.
43
+
44
+ Change Log
45
+ ~~~~~~~~~~
46
+ To see important changes between versions look at CHANGELOG.md_
47
+
48
+ License
49
+ ~~~~~~~
50
+ Project is distributed under `MIT Licence`_.
51
+
52
+ .. _CHANGELOG.md: https://github.com/orthoseg/segmodels_keras/blob/main/CHANGELOG.md
53
+ .. _`MIT Licence`: https://github.com/orthoseg/segmodels_keras/blob/main/LICENSE
@@ -1,8 +1,10 @@
1
- import functools
1
+ import functools # noqa: I001
2
2
  import os
3
3
 
4
- from . import base
5
- from .__version__ import __version__
4
+ # __version__ should be defined as soon as possible
5
+ from segmodels_keras._version import __version__
6
+
7
+ from segmodels_keras import base
6
8
 
7
9
  _KERAS_FRAMEWORK_NAME = "keras"
8
10
  _TF_KERAS_FRAMEWORK_NAME = "tf.keras"
@@ -0,0 +1,4 @@
1
+ import keras
2
+ from packaging.version import parse as parse_version
3
+
4
+ KERAS_GTE_3 = parse_version(keras.__version__) >= parse_version("3.0.0")
@@ -0,0 +1,2 @@
1
+ __versioninfo__ = (0, 1, 0, "dev2")
2
+ __version__ = ".".join(map(str, __versioninfo__))
@@ -125,7 +125,14 @@ class BackbonesFactory:
125
125
  "inceptionresnetv2": (
126
126
  irv2.InceptionResNetV2,
127
127
  irv2.preprocess_input,
128
- (594, 260, 16, 9),
128
+ (
129
+ "activation_161",
130
+ "activation_74",
131
+ "activation_3",
132
+ "activation",
133
+ # "input_1",
134
+ ),
135
+ # (594, 260, 16, 9),
129
136
  ),
130
137
  "inceptionv3": (iv3.InceptionV3, iv3.preprocess_input, (228, 86, 16, 9)),
131
138
  # MobileNet
@@ -1,166 +1,49 @@
1
1
  """Inception-ResNet V2 model for Keras.
2
+
2
3
  Model naming and structure follows TF-slim implementation
3
4
  (which has some additional layers and different number of
4
5
  filters from the original arXiv paper):
5
6
  https://github.com/tensorflow/models/blob/master/research/slim/nets/inception_resnet_v2.py
7
+
6
8
  Pre-trained ImageNet weights are also converted from TF-slim,
7
9
  which can be found in:
8
10
  https://github.com/tensorflow/models/tree/master/research/slim#pre-trained-models
11
+
9
12
  # Reference
10
13
  - [Inception-v4, Inception-ResNet and the Impact of
11
14
  Residual Connections on Learning](https://arxiv.org/abs/1602.07261) (AAAI 2017)
15
+
16
+ Differences with the original implementation in keras.applications:
17
+ - For e.g. in the `conv2d_bn` blocks, padding="same" is used instead of "valid". This is
18
+ to make the sizes of the outputs of the layers the correct size for the skip
19
+ connections for the decoders in the segmentation models. It does not affect the
20
+ weights of the layers, so we can still use the pre-trained weights from the original
21
+ implementation.
22
+ An alternative solution is to add a padding layer before the skip connections, but
23
+ that would add extra parameters to the model, which we want to avoid as that might
24
+ also give issues when loading weights that were saved with an older version. An
25
+ example where this solution is used/shown can be found here:
26
+ https://github.com/ayushdabra/dubai-satellite-imagery-segmentation/blob/9446e16134e752dda080ba9d65be18ea47fa26a9/get_activations.py#L40
27
+ - The original implementation uses different imports as it is internal in keras, and
28
+ here we need to use the public API of keras.
29
+ - Use Lambda layer instead of CustomScaleLayer because:
30
+ - it avoids having to define + pass in a custom layer when loading the model
31
+ - otherwise "old" weights cannot be loaded when using keras 3
12
32
  """
13
33
 
14
- import os
15
34
  import warnings
35
+ from pathlib import Path
16
36
 
17
37
  from keras import backend, layers, models
18
- from keras import utils as keras_utils
19
38
  from keras.applications import imagenet_utils
39
+ from keras.layers import Layer
40
+ from keras.utils import get_file, get_source_inputs
20
41
 
21
42
  BASE_WEIGHT_URL = (
22
- "https://github.com/fchollet/deep-learning-models/releases/download/v0.7/"
43
+ "https://storage.googleapis.com/tensorflow/keras-applications/inception_resnet_v2/"
23
44
  )
24
45
 
25
46
 
26
- def preprocess_input(x, **kwargs):
27
- """Preprocesses a numpy array encoding a batch of images.
28
- # Arguments
29
- x: a 4D numpy array consists of RGB values within [0, 255].
30
- # Returns
31
- Preprocessed array.
32
- """
33
- return imagenet_utils.preprocess_input(x, mode="tf", **kwargs)
34
-
35
-
36
- def conv2d_bn(
37
- x,
38
- filters,
39
- kernel_size,
40
- strides=1,
41
- padding="same",
42
- activation="relu",
43
- use_bias=False,
44
- name=None,
45
- ):
46
- """Utility function to apply conv + BN.
47
- # Arguments
48
- x: input tensor.
49
- filters: filters in `Conv2D`.
50
- kernel_size: kernel size as in `Conv2D`.
51
- strides: strides in `Conv2D`.
52
- padding: padding mode in `Conv2D`.
53
- activation: activation in `Conv2D`.
54
- use_bias: whether to use a bias in `Conv2D`.
55
- name: name of the ops; will become `name + '_ac'` for the activation
56
- and `name + '_bn'` for the batch norm layer.
57
- # Returns
58
- Output tensor after applying `Conv2D` and `BatchNormalization`.
59
- """
60
- x = layers.Conv2D(
61
- filters,
62
- kernel_size,
63
- strides=strides,
64
- padding=padding,
65
- use_bias=use_bias,
66
- name=name,
67
- )(x)
68
- if not use_bias:
69
- bn_axis = 1 if backend.image_data_format() == "channels_first" else 3
70
- bn_name = None if name is None else name + "_bn"
71
- x = layers.BatchNormalization(axis=bn_axis, scale=False, name=bn_name)(x)
72
- if activation is not None:
73
- ac_name = None if name is None else name + "_ac"
74
- x = layers.Activation(activation, name=ac_name)(x)
75
- return x
76
-
77
-
78
- def inception_resnet_block(x, scale, block_type, block_idx, activation="relu"):
79
- """Adds a Inception-ResNet block.
80
- This function builds 3 types of Inception-ResNet blocks mentioned
81
- in the paper, controlled by the `block_type` argument (which is the
82
- block name used in the official TF-slim implementation):
83
- - Inception-ResNet-A: `block_type='block35'`
84
- - Inception-ResNet-B: `block_type='block17'`
85
- - Inception-ResNet-C: `block_type='block8'`
86
- # Arguments
87
- x: input tensor.
88
- scale: scaling factor to scale the residuals (i.e., the output of
89
- passing `x` through an inception module) before adding them
90
- to the shortcut branch.
91
- Let `r` be the output from the residual branch,
92
- the output of this block will be `x + scale * r`.
93
- block_type: `'block35'`, `'block17'` or `'block8'`, determines
94
- the network structure in the residual branch.
95
- block_idx: an `int` used for generating layer names.
96
- The Inception-ResNet blocks
97
- are repeated many times in this network.
98
- We use `block_idx` to identify
99
- each of the repetitions. For example,
100
- the first Inception-ResNet-A block
101
- will have `block_type='block35', block_idx=0`,
102
- and the layer names will have
103
- a common prefix `'block35_0'`.
104
- activation: activation function to use at the end of the block
105
- (see [activations](../activations.md)).
106
- When `activation=None`, no activation is applied
107
- (i.e., "linear" activation: `a(x) = x`).
108
- # Returns
109
- Output tensor for the block.
110
- # Raises
111
- ValueError: if `block_type` is not one of `'block35'`,
112
- `'block17'` or `'block8'`.
113
- """
114
- if block_type == "block35":
115
- branch_0 = conv2d_bn(x, 32, 1)
116
- branch_1 = conv2d_bn(x, 32, 1)
117
- branch_1 = conv2d_bn(branch_1, 32, 3)
118
- branch_2 = conv2d_bn(x, 32, 1)
119
- branch_2 = conv2d_bn(branch_2, 48, 3)
120
- branch_2 = conv2d_bn(branch_2, 64, 3)
121
- branches = [branch_0, branch_1, branch_2]
122
- elif block_type == "block17":
123
- branch_0 = conv2d_bn(x, 192, 1)
124
- branch_1 = conv2d_bn(x, 128, 1)
125
- branch_1 = conv2d_bn(branch_1, 160, [1, 7])
126
- branch_1 = conv2d_bn(branch_1, 192, [7, 1])
127
- branches = [branch_0, branch_1]
128
- elif block_type == "block8":
129
- branch_0 = conv2d_bn(x, 192, 1)
130
- branch_1 = conv2d_bn(x, 192, 1)
131
- branch_1 = conv2d_bn(branch_1, 224, [1, 3])
132
- branch_1 = conv2d_bn(branch_1, 256, [3, 1])
133
- branches = [branch_0, branch_1]
134
- else:
135
- raise ValueError(
136
- "Unknown Inception-ResNet block type. "
137
- 'Expects "block35", "block17" or "block8", '
138
- "but got: " + str(block_type)
139
- )
140
-
141
- block_name = block_type + "_" + str(block_idx)
142
- channel_axis = 1 if backend.image_data_format() == "channels_first" else 3
143
- mixed = layers.Concatenate(axis=channel_axis, name=block_name + "_mixed")(branches)
144
- up = conv2d_bn(
145
- mixed,
146
- x.shape[channel_axis],
147
- 1,
148
- activation=None,
149
- use_bias=True,
150
- name=block_name + "_conv",
151
- )
152
-
153
- x = layers.Lambda(
154
- lambda inputs, scale: inputs[0] + inputs[1] * scale,
155
- output_shape=x.shape[1:],
156
- arguments={"scale": scale},
157
- name=block_name,
158
- )([x, up])
159
- if activation is not None:
160
- x = layers.Activation(activation, name=block_name + "_ac")(x)
161
- return x
162
-
163
-
164
47
  def InceptionResNetV2(
165
48
  include_top=True,
166
49
  weights="imagenet",
@@ -168,23 +51,47 @@ def InceptionResNetV2(
168
51
  input_shape=None,
169
52
  pooling=None,
170
53
  classes=1000,
171
- **kwargs, # noqa: ARG001
54
+ classifier_activation="softmax",
55
+ name="inception_resnet_v2",
172
56
  ):
173
57
  """Instantiates the Inception-ResNet v2 architecture.
174
- Optionally loads weights pre-trained on ImageNet.
175
- Note that the data format convention used by the model is
176
- the one specified in your Keras config at `~/.keras/keras.json`.
177
- # Arguments
58
+
59
+ Reference:
60
+ - [Inception-v4, Inception-ResNet and the Impact of
61
+ Residual Connections on Learning](https://arxiv.org/abs/1602.07261)
62
+ (AAAI 2017)
63
+
64
+ This function returns a Keras image classification model,
65
+ optionally loaded with weights pre-trained on ImageNet.
66
+
67
+ For image classification use cases, see
68
+ [this page for detailed examples](
69
+ https://keras.io/api/applications/#usage-examples-for-image-classification-models).
70
+
71
+ For transfer learning use cases, make sure to read the
72
+ [guide to transfer learning & fine-tuning](
73
+ https://keras.io/guides/transfer_learning/).
74
+
75
+ Note: each Keras Application expects a specific kind of
76
+ input preprocessing. For InceptionResNetV2, call
77
+ `keras.applications.inception_resnet_v2.preprocess_input`
78
+ on your inputs before passing them to the model.
79
+ `inception_resnet_v2.preprocess_input`
80
+ will scale input pixels between -1 and 1.
81
+
82
+ Args:
178
83
  include_top: whether to include the fully-connected
179
84
  layer at the top of the network.
180
85
  weights: one of `None` (random initialization),
181
- 'imagenet' (pre-training on ImageNet),
182
- or the path to the weights file to be loaded.
183
- input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)
86
+ `"imagenet"` (pre-training on ImageNet),
87
+ or the path to the weights file to be loaded.
88
+ input_tensor: optional Keras tensor
89
+ (i.e. output of `layers.Input()`)
184
90
  to use as image input for the model.
185
91
  input_shape: optional shape tuple, only to be specified
186
92
  if `include_top` is `False` (otherwise the input shape
187
- has to be `(299, 299, 3)` (with `'channels_last'` data format)
93
+ has to be `(299, 299, 3)`
94
+ (with `'channels_last'` data format)
188
95
  or `(3, 299, 299)` (with `'channels_first'` data format).
189
96
  It should have exactly 3 inputs channels,
190
97
  and width and height should be no smaller than 75.
@@ -199,15 +106,20 @@ def InceptionResNetV2(
199
106
  the output of the model will be a 2D tensor.
200
107
  - `'max'` means that global max pooling will be applied.
201
108
  classes: optional number of classes to classify images
202
- into, only to be specified if `include_top` is `True`, and
203
- if no `weights` argument is specified.
204
- # Returns
205
- A Keras `Model` instance.
206
- # Raises
207
- ValueError: in case of invalid argument for `weights`,
208
- or invalid input shape.
109
+ into, only to be specified if `include_top` is `True`,
110
+ and if no `weights` argument is specified.
111
+ classifier_activation: A `str` or callable.
112
+ The activation function to use on the "top" layer.
113
+ Ignored unless `include_top=True`.
114
+ Set `classifier_activation=None` to return the logits
115
+ of the "top" layer. When loading pretrained weights,
116
+ `classifier_activation` can only be `None` or `"softmax"`.
117
+ name: The name of the model (string).
118
+
119
+ Returns:
120
+ A model instance.
209
121
  """
210
- if not (weights in {"imagenet", None} or os.path.exists(weights)):
122
+ if not (weights in {"imagenet", None} or Path(weights).exists()):
211
123
  raise ValueError(
212
124
  "The `weights` argument should be either "
213
125
  "`None` (random initialization), `imagenet` "
@@ -217,8 +129,9 @@ def InceptionResNetV2(
217
129
 
218
130
  if weights == "imagenet" and include_top and classes != 1000:
219
131
  raise ValueError(
220
- 'If using `weights` as `"imagenet"` with `include_top`'
221
- " as true, `classes` should be 1000"
132
+ 'If using `weights="imagenet"` with `include_top=True`, '
133
+ "`classes` should be 1000. "
134
+ f"Received classes={classes}"
222
135
  )
223
136
 
224
137
  # Determine proper input shape
@@ -233,10 +146,11 @@ def InceptionResNetV2(
233
146
 
234
147
  if input_tensor is None:
235
148
  img_input = layers.Input(shape=input_shape)
236
- elif not backend.is_keras_tensor(input_tensor):
237
- img_input = layers.Input(tensor=input_tensor, shape=input_shape)
238
149
  else:
239
- img_input = input_tensor
150
+ if not backend.is_keras_tensor(input_tensor):
151
+ img_input = layers.Input(tensor=input_tensor, shape=input_shape)
152
+ else:
153
+ img_input = input_tensor
240
154
 
241
155
  # Stem block: 35 x 35 x 192
242
156
  x = conv2d_bn(img_input, 32, 3, strides=2, padding="same")
@@ -308,27 +222,31 @@ def InceptionResNetV2(
308
222
  if include_top:
309
223
  # Classification block
310
224
  x = layers.GlobalAveragePooling2D(name="avg_pool")(x)
311
- x = layers.Dense(classes, activation="softmax", name="predictions")(x)
312
- elif pooling == "avg":
313
- x = layers.GlobalAveragePooling2D()(x)
314
- elif pooling == "max":
315
- x = layers.GlobalMaxPooling2D()(x)
225
+ imagenet_utils.validate_activation(classifier_activation, weights)
226
+ x = layers.Dense(classes, activation=classifier_activation, name="predictions")(
227
+ x
228
+ )
229
+ else:
230
+ if pooling == "avg":
231
+ x = layers.GlobalAveragePooling2D()(x)
232
+ elif pooling == "max":
233
+ x = layers.GlobalMaxPooling2D()(x)
316
234
 
317
235
  # Ensure that the model takes into account
318
236
  # any potential predecessors of `input_tensor`.
319
237
  if input_tensor is not None:
320
- inputs = keras_utils.get_source_inputs(input_tensor)
238
+ inputs = get_source_inputs(input_tensor)
321
239
  else:
322
240
  inputs = img_input
323
241
 
324
242
  # Create model.
325
- model = models.Model(inputs, x, name="inception_resnet_v2")
243
+ model = models.Model(inputs, x, name=name)
326
244
 
327
245
  # Load weights.
328
246
  if weights == "imagenet":
329
247
  if include_top:
330
248
  fname = "inception_resnet_v2_weights_tf_dim_ordering_tf_kernels.h5"
331
- weights_path = keras_utils.get_file(
249
+ weights_path = get_file(
332
250
  fname,
333
251
  BASE_WEIGHT_URL + fname,
334
252
  cache_subdir="models",
@@ -336,7 +254,7 @@ def InceptionResNetV2(
336
254
  )
337
255
  else:
338
256
  fname = "inception_resnet_v2_weights_tf_dim_ordering_tf_kernels_notop.h5"
339
- weights_path = keras_utils.get_file(
257
+ weights_path = get_file(
340
258
  fname,
341
259
  BASE_WEIGHT_URL + fname,
342
260
  cache_subdir="models",
@@ -349,46 +267,216 @@ def InceptionResNetV2(
349
267
  return model
350
268
 
351
269
 
352
- def _obtain_input_shape(
353
- input_shape, default_size, min_size, data_format, require_flatten, weights=None
270
+ def conv2d_bn(
271
+ x,
272
+ filters,
273
+ kernel_size,
274
+ strides=1,
275
+ padding="same",
276
+ activation="relu",
277
+ use_bias=False,
278
+ name=None,
354
279
  ):
355
- """Internal utility to compute/validate a model's input shape.
280
+ """Utility function to apply conv + BN.
356
281
 
357
- # Arguments
358
- input_shape: Either None (will return the default network input shape),
359
- or a user-provided shape to be validated.
360
- default_size: Default input width/height for the model.
361
- min_size: Minimum input width/height accepted by the model.
362
- data_format: Image data format to use.
363
- require_flatten: Whether the model is expected to
364
- be linked to a classifier via a Flatten layer.
365
- weights: One of `None` (random initialization)
366
- or 'imagenet' (pre-training on ImageNet).
367
- If weights='imagenet' input channels must be equal to 3.
282
+ Args:
283
+ x: input tensor.
284
+ filters: filters in `Conv2D`.
285
+ kernel_size: kernel size as in `Conv2D`.
286
+ strides: strides in `Conv2D`.
287
+ padding: padding mode in `Conv2D`.
288
+ activation: activation in `Conv2D`.
289
+ use_bias: whether to use a bias in `Conv2D`.
290
+ name: name of the ops; will become `name + '_ac'`
291
+ for the activation and `name + '_bn'` for the batch norm layer.
368
292
 
369
- # Returns
370
- An integer shape tuple (may include None entries).
293
+ Returns:
294
+ Output tensor after applying `Conv2D` and `BatchNormalization`.
295
+ """
296
+ x = layers.Conv2D(
297
+ filters,
298
+ kernel_size,
299
+ strides=strides,
300
+ padding=padding,
301
+ use_bias=use_bias,
302
+ name=name,
303
+ )(x)
304
+ if not use_bias:
305
+ bn_axis = 1 if backend.image_data_format() == "channels_first" else 3
306
+ bn_name = None if name is None else f"{name}_bn"
307
+ x = layers.BatchNormalization(axis=bn_axis, scale=False, name=bn_name)(x)
308
+ if activation is not None:
309
+ ac_name = None if name is None else f"{name}_ac"
310
+ x = layers.Activation(activation, name=ac_name)(x)
311
+ return x
312
+
313
+
314
+ def inception_resnet_block(x, scale, block_type, block_idx, activation="relu"):
315
+ """Adds a Inception-ResNet block.
371
316
 
317
+ This function builds 3 types of Inception-ResNet blocks mentioned
318
+ in the paper, controlled by the `block_type` argument (which is the
319
+ block name used in the official TF-slim implementation):
320
+ - Inception-ResNet-A: `block_type='block35'`
321
+ - Inception-ResNet-B: `block_type='block17'`
322
+ - Inception-ResNet-C: `block_type='block8'`
323
+
324
+ Args:
325
+ x: input tensor.
326
+ scale: scaling factor to scale the residuals
327
+ (i.e., the output of passing `x` through an inception module)
328
+ before adding them to the shortcut
329
+ branch. Let `r` be the output from the residual branch,
330
+ the output of this block will be `x + scale * r`.
331
+ block_type: `'block35'`, `'block17'` or `'block8'`,
332
+ determines the network structure in the residual branch.
333
+ block_idx: an `int` used for generating layer names.
334
+ The Inception-ResNet blocks are repeated many times
335
+ in this network. We use `block_idx` to identify each
336
+ of the repetitions. For example, the first
337
+ Inception-ResNet-A block will have
338
+ `block_type='block35', block_idx=0`, and the layer names
339
+ will have a common prefix `'block35_0'`.
340
+ activation: activation function to use at the end of the block.
341
+ (see [activations](../activations.md)).
342
+ When `activation=None`, no activation is applied
343
+ (i.e., "linear" activation: `a(x) = x`).
344
+ # Returns
345
+ Output tensor for the block.
372
346
  # Raises
373
- ValueError: In case of invalid argument values.
347
+ ValueError: if `block_type` is not one of `'block35'`,
348
+ `'block17'` or `'block8'`.
349
+ Output tensor for the block.
350
+ """
351
+ if block_type == "block35":
352
+ branch_0 = conv2d_bn(x, 32, 1)
353
+ branch_1 = conv2d_bn(x, 32, 1)
354
+ branch_1 = conv2d_bn(branch_1, 32, 3)
355
+ branch_2 = conv2d_bn(x, 32, 1)
356
+ branch_2 = conv2d_bn(branch_2, 48, 3)
357
+ branch_2 = conv2d_bn(branch_2, 64, 3)
358
+ branches = [branch_0, branch_1, branch_2]
359
+ elif block_type == "block17":
360
+ branch_0 = conv2d_bn(x, 192, 1)
361
+ branch_1 = conv2d_bn(x, 128, 1)
362
+ branch_1 = conv2d_bn(branch_1, 160, [1, 7])
363
+ branch_1 = conv2d_bn(branch_1, 192, [7, 1])
364
+ branches = [branch_0, branch_1]
365
+ elif block_type == "block8":
366
+ branch_0 = conv2d_bn(x, 192, 1)
367
+ branch_1 = conv2d_bn(x, 192, 1)
368
+ branch_1 = conv2d_bn(branch_1, 224, [1, 3])
369
+ branch_1 = conv2d_bn(branch_1, 256, [3, 1])
370
+ branches = [branch_0, branch_1]
371
+ else:
372
+ raise ValueError(
373
+ "Unknown Inception-ResNet block type. "
374
+ 'Expects "block35", "block17" or "block8", '
375
+ f"but got: {block_type}"
376
+ )
377
+
378
+ block_name = f"{block_type}_{block_idx}"
379
+ channel_axis = 1 if backend.image_data_format() == "channels_first" else 3
380
+ mixed = layers.Concatenate(axis=channel_axis, name=f"{block_name}_mixed")(branches)
381
+ up = conv2d_bn(
382
+ mixed,
383
+ x.shape[channel_axis],
384
+ 1,
385
+ activation=None,
386
+ use_bias=True,
387
+ name=f"{block_name}_conv",
388
+ )
389
+
390
+ x = layers.Lambda(
391
+ lambda inputs, scale: inputs[0] + inputs[1] * scale,
392
+ output_shape=x.shape[1:],
393
+ arguments={"scale": scale},
394
+ name=block_name,
395
+ )([x, up])
396
+
397
+ if activation is not None:
398
+ x = layers.Activation(activation, name=f"{block_name}_ac")(x)
399
+
400
+ return x
401
+
402
+
403
+ def preprocess_input(x, data_format=None):
404
+ """Preprocesses a numpy array encoding a batch of images.
405
+
406
+ Args:
407
+ x: a 4D numpy array consists of RGB values within [0, 255].
408
+
409
+ Returns:
410
+ Preprocessed array.
411
+ """
412
+ return imagenet_utils.preprocess_input(x, data_format=data_format, mode="tf")
413
+
414
+
415
+ def decode_predictions(preds, top=5):
416
+ """Decodes the prediction of an ImageNet model.
417
+
418
+ Args:
419
+ preds: NumPy array encoding a batch of predictions.
420
+ top: Integer, how many top-guesses to return. Defaults to `5`.
421
+
422
+ Returns:
423
+ A list of lists of top class prediction tuples
424
+ `(class_name, class_description, score)`.
425
+ One list of tuples per sample in batch input.
426
+
427
+ Raises:
428
+ ValueError: In case of invalid shape of the `pred` array
429
+ (must be 2D).
430
+ """
431
+ return imagenet_utils.decode_predictions(preds, top=top)
432
+
433
+
434
+ def _obtain_input_shape(
435
+ input_shape,
436
+ default_size,
437
+ min_size,
438
+ data_format,
439
+ require_flatten,
440
+ weights=None,
441
+ ):
442
+ """Internal utility to compute/validate a model's input shape.
443
+
444
+ Args:
445
+ input_shape: Either None (will return the default network input shape),
446
+ or a user-provided shape to be validated.
447
+ default_size: Default input width/height for the model.
448
+ min_size: Minimum input width/height accepted by the model.
449
+ data_format: Image data format to use.
450
+ require_flatten: Whether the model is expected to
451
+ be linked to a classifier via a Flatten layer.
452
+ weights: One of `None` (random initialization)
453
+ or 'imagenet' (pre-training on ImageNet).
454
+ If weights='imagenet' input channels must be equal to 3.
455
+
456
+ Returns:
457
+ An integer shape tuple (may include None entries).
458
+
459
+ Raises:
460
+ ValueError: In case of invalid argument values.
374
461
  """
375
462
  if weights != "imagenet" and input_shape and len(input_shape) == 3:
376
463
  if data_format == "channels_first":
377
- if input_shape[0] not in {1, 3}:
378
- warnings.warn( # noqa: B028
464
+ correct_channel_axis = 1 if len(input_shape) == 4 else 0
465
+ if input_shape[correct_channel_axis] not in {1, 3}:
466
+ warnings.warn(
379
467
  "This model usually expects 1 or 3 input channels. "
380
- "However, it was passed an input_shape with "
381
- + str(input_shape[0])
382
- + " input channels."
468
+ "However, it was passed an input_shape "
469
+ f"with {input_shape[0]} input channels.",
470
+ stacklevel=2,
383
471
  )
384
472
  default_shape = (input_shape[0], default_size, default_size)
385
473
  else:
386
474
  if input_shape[-1] not in {1, 3}:
387
- warnings.warn( # noqa: B028
475
+ warnings.warn(
388
476
  "This model usually expects 1 or 3 input channels. "
389
- "However, it was passed an input_shape with "
390
- + str(input_shape[-1])
391
- + " input channels."
477
+ "However, it was passed an input_shape "
478
+ f"with {input_shape[-1]} input channels.",
479
+ stacklevel=2,
392
480
  )
393
481
  default_shape = (default_size, default_size, input_shape[-1])
394
482
  else:
@@ -402,7 +490,8 @@ def _obtain_input_shape(
402
490
  raise ValueError(
403
491
  "When setting `include_top=True` "
404
492
  "and loading `imagenet` weights, "
405
- "`input_shape` should be " + str(default_shape) + "."
493
+ f"`input_shape` should be {default_shape}. "
494
+ f"Received: input_shape={input_shape}"
406
495
  )
407
496
  return default_shape
408
497
  if input_shape:
@@ -412,20 +501,16 @@ def _obtain_input_shape(
412
501
  raise ValueError("`input_shape` must be a tuple of three integers.")
413
502
  if input_shape[0] != 3 and weights == "imagenet":
414
503
  raise ValueError(
415
- "The input must have 3 channels; got "
416
- "`input_shape=" + str(input_shape) + "`"
504
+ "The input must have 3 channels; Received "
505
+ f"`input_shape={input_shape}`"
417
506
  )
418
507
  if (input_shape[1] is not None and input_shape[1] < min_size) or (
419
508
  input_shape[2] is not None and input_shape[2] < min_size
420
509
  ):
421
510
  raise ValueError(
422
- "Input size must be at least "
423
- + str(min_size)
424
- + "x"
425
- + str(min_size)
426
- + "; got `input_shape="
427
- + str(input_shape)
428
- + "`"
511
+ f"Input size must be at least {min_size}"
512
+ f"x{min_size}; Received: "
513
+ f"input_shape={input_shape}"
429
514
  )
430
515
  else:
431
516
  if input_shape is not None:
@@ -433,20 +518,16 @@ def _obtain_input_shape(
433
518
  raise ValueError("`input_shape` must be a tuple of three integers.")
434
519
  if input_shape[-1] != 3 and weights == "imagenet":
435
520
  raise ValueError(
436
- "The input must have 3 channels; got "
437
- "`input_shape=" + str(input_shape) + "`"
521
+ "The input must have 3 channels; Received "
522
+ f"`input_shape={input_shape}`"
438
523
  )
439
524
  if (input_shape[0] is not None and input_shape[0] < min_size) or (
440
525
  input_shape[1] is not None and input_shape[1] < min_size
441
526
  ):
442
527
  raise ValueError(
443
528
  "Input size must be at least "
444
- + str(min_size)
445
- + "x"
446
- + str(min_size)
447
- + "; got `input_shape="
448
- + str(input_shape)
449
- + "`"
529
+ f"{min_size}x{min_size}; Received: "
530
+ f"input_shape={input_shape}"
450
531
  )
451
532
  else:
452
533
  if require_flatten:
@@ -461,6 +542,6 @@ def _obtain_input_shape(
461
542
  raise ValueError(
462
543
  "If `include_top` is True, "
463
544
  "you should specify a static `input_shape`. "
464
- "Got `input_shape=" + str(input_shape) + "`"
545
+ f"Received: input_shape={input_shape}"
465
546
  )
466
547
  return input_shape
@@ -1,7 +1,8 @@
1
+ import keras
2
+
1
3
  from segmodels_keras._compat import KERAS_GTE_3
2
4
 
3
5
  if KERAS_GTE_3:
4
- import keras
5
6
  from keras import ops
6
7
  else:
7
8
  from keras import backend as ops
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: segmodels_keras
3
- Version: 0.1.0.dev0
3
+ Version: 0.1.0.dev2
4
4
  Summary: Image segmentation models with pre-trained backbones with Keras.
5
- Home-page: https://github.com/theroggy/segmodels_keras
5
+ Home-page: https://github.com/orthoseg/segmodels_keras
6
6
  Author: Pieter Roggemans
7
7
  Author-email: pieter.roggemans@gmail.com
8
8
  License: MIT
@@ -15,6 +15,7 @@ Requires-Python: >=3.0.0
15
15
  Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
17
  Requires-Dist: keras
18
+ Requires-Dist: packaging
18
19
  Provides-Extra: tests
19
20
  Requires-Dist: numpy; extra == "tests"
20
21
  Requires-Dist: pytest; extra == "tests"
@@ -4,8 +4,8 @@ README.rst
4
4
  pyproject.toml
5
5
  setup.py
6
6
  segmodels_keras/__init__.py
7
- segmodels_keras/__version__.py
8
7
  segmodels_keras/_compat.py
8
+ segmodels_keras/_version.py
9
9
  segmodels_keras/losses.py
10
10
  segmodels_keras/metrics.py
11
11
  segmodels_keras/utils.py
@@ -10,7 +10,7 @@ from setuptools import find_packages, setup
10
10
  # Package meta-data.
11
11
  NAME = "segmodels_keras"
12
12
  DESCRIPTION = "Image segmentation models with pre-trained backbones with Keras."
13
- URL = "https://github.com/theroggy/segmodels_keras"
13
+ URL = "https://github.com/orthoseg/segmodels_keras"
14
14
  EMAIL = "pieter.roggemans@gmail.com"
15
15
  AUTHOR = "Pieter Roggemans"
16
16
  REQUIRES_PYTHON = ">=3.0.0"
@@ -24,7 +24,7 @@ VERSION = None
24
24
  here = os.path.abspath(os.path.dirname(__file__))
25
25
 
26
26
  # What packages are required for this module to be executed?
27
- REQUIRED = ["keras"]
27
+ REQUIRED = ["keras", "packaging"]
28
28
 
29
29
  # What packages are optional?
30
30
  EXTRAS = {
@@ -39,10 +39,10 @@ try:
39
39
  except FileNotFoundError:
40
40
  long_description = DESCRIPTION
41
41
 
42
- # Load the package's __version__.py module as a dictionary.
42
+ # Load the package's _version.py module as a dictionary.
43
43
  about = {}
44
44
  if not VERSION:
45
- with open(os.path.join(here, NAME, "__version__.py")) as f:
45
+ with open(os.path.join(here, NAME, "_version.py")) as f:
46
46
  exec(f.read(), about)
47
47
  else:
48
48
  about["__version__"] = VERSION
@@ -1,260 +0,0 @@
1
- segmodels_keras
2
- =========================
3
-
4
- This is a fork of the
5
- [segmentation_models](https://github.com/qubvel/segmentation_models) library by
6
- Pavel Iakubovskii, which is not maintained anymore.
7
-
8
- This fork is updated to support latest versions of Keras and TensorFlow, and also
9
- contains some bug fixes and improvements.
10
-
11
- It is not meant as a full replacement of the original library, but rather as a
12
- solution for a library I developed and depended on segmentation_models:
13
- [orthoseg](https://github.com/orthoseg/orthoseg).
14
-
15
- Hence, backwards compatibility,... is not guaranteed or even an explicit goal.
16
-
17
-
18
- **The main features** of this library are:
19
-
20
- - High level API (just two lines of code to create model for segmentation)
21
- - **4** models architectures for binary and multi-class image segmentation
22
- (including legendary **Unet**)
23
- - **25** available backbones for each architecture
24
- - All backbones have **pre-trained** weights for faster and better
25
- convergence
26
- - Helpful segmentation losses (Jaccard, Dice, Focal) and metrics (IoU, F-score)
27
-
28
-
29
- Table of Contents
30
- ~~~~~~~~~~~~~~~~~
31
- - `Quick start`_
32
- - `Simple training pipeline`_
33
- - `Examples`_
34
- - `Models and Backbones`_
35
- - `Installation`_
36
- - `Documentation`_
37
- - `Change log`_
38
- - `Citing`_
39
- - `License`_
40
-
41
- Quick start
42
- ~~~~~~~~~~~
43
- Library is build to work together with Keras and TensorFlow Keras frameworks
44
-
45
- .. code:: python
46
-
47
- import segmentation_models as sm
48
- # Segmentation Models: using `keras` framework.
49
-
50
- By default it tries to import ``keras``, if it is not installed, it will try to start with ``tensorflow.keras`` framework.
51
- There are several ways to choose framework:
52
-
53
- - Provide environment variable ``SM_FRAMEWORK=keras`` / ``SM_FRAMEWORK=tf.keras`` before import ``segmentation_models``
54
- - Change framework ``sm.set_framework('keras')`` / ``sm.set_framework('tf.keras')``
55
-
56
- You can also specify what kind of ``image_data_format`` to use, segmentation-models works with both: ``channels_last`` and ``channels_first``.
57
- This can be useful for further model conversion to Nvidia TensorRT format or optimizing model for cpu/gpu computations.
58
-
59
- .. code:: python
60
-
61
- import keras
62
- # or from tensorflow import keras
63
-
64
- keras.backend.set_image_data_format('channels_last')
65
- # or keras.backend.set_image_data_format('channels_first')
66
-
67
- Created segmentation model is just an instance of Keras Model, which can be build as easy as:
68
-
69
- .. code:: python
70
-
71
- model = sm.Unet()
72
-
73
- Depending on the task, you can change the network architecture by choosing backbones with fewer or more parameters and use pretrainded weights to initialize it:
74
-
75
- .. code:: python
76
-
77
- model = sm.Unet('resnet34', encoder_weights='imagenet')
78
-
79
- Change number of output classes in the model (choose your case):
80
-
81
- .. code:: python
82
-
83
- # binary segmentation (this parameters are default when you call Unet('resnet34')
84
- model = sm.Unet('resnet34', classes=1, activation='sigmoid')
85
-
86
- .. code:: python
87
-
88
- # multiclass segmentation with non overlapping class masks (your classes + background)
89
- model = sm.Unet('resnet34', classes=3, activation='softmax')
90
-
91
- .. code:: python
92
-
93
- # multiclass segmentation with independent overlapping/non-overlapping class masks
94
- model = sm.Unet('resnet34', classes=3, activation='sigmoid')
95
-
96
-
97
- Change input shape of the model:
98
-
99
- .. code:: python
100
-
101
- # if you set input channels not equal to 3, you have to set encoder_weights=None
102
- # how to handle such case with encoder_weights='imagenet' described in docs
103
- model = Unet('resnet34', input_shape=(None, None, 6), encoder_weights=None)
104
-
105
- Simple training pipeline
106
- ~~~~~~~~~~~~~~~~~~~~~~~~
107
-
108
- .. code:: python
109
-
110
- import segmentation_models as sm
111
-
112
- BACKBONE = 'resnet34'
113
- preprocess_input = sm.get_preprocessing(BACKBONE)
114
-
115
- # load your data
116
- x_train, y_train, x_val, y_val = load_data(...)
117
-
118
- # preprocess input
119
- x_train = preprocess_input(x_train)
120
- x_val = preprocess_input(x_val)
121
-
122
- # define model
123
- model = sm.Unet(BACKBONE, encoder_weights='imagenet')
124
- model.compile(
125
- 'Adam',
126
- loss=sm.losses.bce_jaccard_loss,
127
- metrics=[sm.metrics.iou_score],
128
- )
129
-
130
- # fit model
131
- # if you use data generator use model.fit_generator(...) instead of model.fit(...)
132
- # more about `fit_generator` here: https://keras.io/models/sequential/#fit_generator
133
- model.fit(
134
- x=x_train,
135
- y=y_train,
136
- batch_size=16,
137
- epochs=100,
138
- validation_data=(x_val, y_val),
139
- )
140
-
141
- Same manipulations can be done with ``Linknet``, ``PSPNet`` and ``FPN``. For more detailed information about models API and use cases `Read the Docs <https://segmentation-models.readthedocs.io/en/latest/>`__.
142
-
143
- Examples
144
- ~~~~~~~~
145
- Models training examples:
146
- - [Jupyter Notebook] Binary segmentation (`cars`) on CamVid dataset `here <https://github.com/qubvel/segmentation_models/blob/master/examples/binary%20segmentation%20(camvid).ipynb>`__.
147
- - [Jupyter Notebook] Multi-class segmentation (`cars`, `pedestrians`) on CamVid dataset `here <https://github.com/qubvel/segmentation_models/blob/master/examples/multiclass%20segmentation%20(camvid).ipynb>`__.
148
-
149
- Models and Backbones
150
- ~~~~~~~~~~~~~~~~~~~~
151
- **Models**
152
-
153
- - `Unet <https://arxiv.org/abs/1505.04597>`__
154
- - `FPN <http://presentations.cocodataset.org/COCO17-Stuff-FAIR.pdf>`__
155
- - `Linknet <https://arxiv.org/abs/1707.03718>`__
156
- - `PSPNet <https://arxiv.org/abs/1612.01105>`__
157
-
158
- ============= ==============
159
- Unet Linknet
160
- ============= ==============
161
- |unet_image| |linknet_image|
162
- ============= ==============
163
-
164
- ============= ==============
165
- PSPNet FPN
166
- ============= ==============
167
- |psp_image| |fpn_image|
168
- ============= ==============
169
-
170
- .. _Unet: https://github.com/qubvel/segmentation_models/blob/readme/LICENSE
171
- .. _Linknet: https://arxiv.org/abs/1707.03718
172
- .. _PSPNet: https://arxiv.org/abs/1612.01105
173
- .. _FPN: http://presentations.cocodataset.org/COCO17-Stuff-FAIR.pdf
174
-
175
- .. |unet_image| image:: https://github.com/qubvel/segmentation_models/blob/master/images/unet.png
176
- .. |linknet_image| image:: https://github.com/qubvel/segmentation_models/blob/master/images/linknet.png
177
- .. |psp_image| image:: https://github.com/qubvel/segmentation_models/blob/master/images/pspnet.png
178
- .. |fpn_image| image:: https://github.com/qubvel/segmentation_models/blob/master/images/fpn.png
179
-
180
- **Backbones**
181
-
182
- .. table::
183
-
184
- ============= =====
185
- Type Names
186
- ============= =====
187
- VGG ``'vgg16' 'vgg19'``
188
- ResNet ``'resnet18' 'resnet34' 'resnet50' 'resnet101' 'resnet152'``
189
- SE-ResNet ``'seresnet18' 'seresnet34' 'seresnet50' 'seresnet101' 'seresnet152'``
190
- ResNeXt ``'resnext50' 'resnext101'``
191
- SE-ResNeXt ``'seresnext50' 'seresnext101'``
192
- SENet154 ``'senet154'``
193
- DenseNet ``'densenet121' 'densenet169' 'densenet201'``
194
- Inception ``'inceptionv3' 'inceptionresnetv2'``
195
- MobileNet ``'mobilenet' 'mobilenetv2'``
196
- EfficientNet ``'efficientnetb0' 'efficientnetb1' 'efficientnetb2' 'efficientnetb3' 'efficientnetb4' 'efficientnetb5' efficientnetb6' efficientnetb7'``
197
- ============= =====
198
-
199
- .. epigraph::
200
- All backbones have weights trained on 2012 ILSVRC ImageNet dataset (``encoder_weights='imagenet'``).
201
-
202
-
203
- Installation
204
- ~~~~~~~~~~~~
205
-
206
- **Requirements**
207
-
208
- 1) python 3
209
- 2) keras >= 2.2.0 or tensorflow >= 1.13
210
- 3) keras-applications >= 1.0.7, <=1.0.8
211
- 4) image-classifiers == 1.0.*
212
- 5) efficientnet == 1.0.*
213
-
214
- **PyPI stable package**
215
-
216
- .. code:: bash
217
-
218
- $ pip install -U segmentation-models
219
-
220
- **PyPI latest package**
221
-
222
- .. code:: bash
223
-
224
- $ pip install -U --pre segmentation-models
225
-
226
- **Source latest version**
227
-
228
- .. code:: bash
229
-
230
- $ pip install git+https://github.com/qubvel/segmentation_models
231
-
232
- Documentation
233
- ~~~~~~~~~~~~~
234
- Latest **documentation** is avaliable on `Read the
235
- Docs <https://segmentation-models.readthedocs.io/en/latest/>`__
236
-
237
- Change Log
238
- ~~~~~~~~~~
239
- To see important changes between versions look at CHANGELOG.md_
240
-
241
- Citing
242
- ~~~~~~~~
243
-
244
- .. code::
245
-
246
- @misc{Yakubovskiy:2019,
247
- Author = {Pavel Iakubovskii},
248
- Title = {Segmentation Models},
249
- Year = {2019},
250
- Publisher = {GitHub},
251
- Journal = {GitHub repository},
252
- Howpublished = {\url{https://github.com/qubvel/segmentation_models}}
253
- }
254
-
255
- License
256
- ~~~~~~~
257
- Project is distributed under `MIT Licence`_.
258
-
259
- .. _CHANGELOG.md: https://github.com/qubvel/segmentation_models/blob/master/CHANGELOG.md
260
- .. _`MIT Licence`: https://github.com/qubvel/segmentation_models/blob/master/LICENSE
@@ -1,3 +0,0 @@
1
- VERSION = (0, 1, 0, "dev0")
2
-
3
- __version__ = ".".join(map(str, VERSION))
@@ -1,3 +0,0 @@
1
- import keras
2
-
3
- KERAS_GTE_3 = keras.__version__ >= "3.0.0"