keras-hub-nightly 0.15.0.dev20240823171555__py3-none-any.whl → 0.16.0.dev2024092017__py3-none-any.whl
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.
- keras_hub/__init__.py +0 -6
- keras_hub/api/__init__.py +2 -0
- keras_hub/api/bounding_box/__init__.py +36 -0
- keras_hub/api/layers/__init__.py +14 -0
- keras_hub/api/models/__init__.py +97 -48
- keras_hub/api/tokenizers/__init__.py +30 -0
- keras_hub/api/utils/__init__.py +22 -0
- keras_hub/src/api_export.py +15 -9
- keras_hub/src/bounding_box/__init__.py +13 -0
- keras_hub/src/bounding_box/converters.py +529 -0
- keras_hub/src/bounding_box/formats.py +162 -0
- keras_hub/src/bounding_box/iou.py +263 -0
- keras_hub/src/bounding_box/to_dense.py +95 -0
- keras_hub/src/bounding_box/to_ragged.py +99 -0
- keras_hub/src/bounding_box/utils.py +194 -0
- keras_hub/src/bounding_box/validate_format.py +99 -0
- keras_hub/src/layers/preprocessing/audio_converter.py +121 -0
- keras_hub/src/layers/preprocessing/image_converter.py +130 -0
- keras_hub/src/layers/preprocessing/masked_lm_mask_generator.py +2 -0
- keras_hub/src/layers/preprocessing/multi_segment_packer.py +9 -8
- keras_hub/src/layers/preprocessing/preprocessing_layer.py +2 -29
- keras_hub/src/layers/preprocessing/random_deletion.py +33 -31
- keras_hub/src/layers/preprocessing/random_swap.py +33 -31
- keras_hub/src/layers/preprocessing/resizing_image_converter.py +101 -0
- keras_hub/src/layers/preprocessing/start_end_packer.py +3 -2
- keras_hub/src/models/albert/__init__.py +1 -2
- keras_hub/src/models/albert/albert_masked_lm_preprocessor.py +6 -86
- keras_hub/src/models/albert/{albert_classifier.py → albert_text_classifier.py} +34 -10
- keras_hub/src/models/albert/{albert_preprocessor.py → albert_text_classifier_preprocessor.py} +14 -70
- keras_hub/src/models/albert/albert_tokenizer.py +17 -36
- keras_hub/src/models/backbone.py +12 -34
- keras_hub/src/models/bart/__init__.py +1 -2
- keras_hub/src/models/bart/bart_seq_2_seq_lm_preprocessor.py +21 -148
- keras_hub/src/models/bart/bart_tokenizer.py +12 -39
- keras_hub/src/models/bert/__init__.py +1 -5
- keras_hub/src/models/bert/bert_masked_lm_preprocessor.py +6 -87
- keras_hub/src/models/bert/bert_presets.py +1 -4
- keras_hub/src/models/bert/{bert_classifier.py → bert_text_classifier.py} +19 -12
- keras_hub/src/models/bert/{bert_preprocessor.py → bert_text_classifier_preprocessor.py} +14 -70
- keras_hub/src/models/bert/bert_tokenizer.py +17 -35
- keras_hub/src/models/bloom/__init__.py +1 -2
- keras_hub/src/models/bloom/bloom_causal_lm_preprocessor.py +6 -91
- keras_hub/src/models/bloom/bloom_tokenizer.py +12 -41
- keras_hub/src/models/causal_lm.py +10 -29
- keras_hub/src/models/causal_lm_preprocessor.py +195 -0
- keras_hub/src/models/csp_darknet/csp_darknet_backbone.py +54 -15
- keras_hub/src/models/deberta_v3/__init__.py +1 -4
- keras_hub/src/models/deberta_v3/deberta_v3_masked_lm_preprocessor.py +14 -77
- keras_hub/src/models/deberta_v3/{deberta_v3_classifier.py → deberta_v3_text_classifier.py} +16 -11
- keras_hub/src/models/deberta_v3/{deberta_v3_preprocessor.py → deberta_v3_text_classifier_preprocessor.py} +23 -64
- keras_hub/src/models/deberta_v3/deberta_v3_tokenizer.py +30 -25
- keras_hub/src/models/densenet/densenet_backbone.py +46 -22
- keras_hub/src/models/distil_bert/__init__.py +1 -4
- keras_hub/src/models/distil_bert/distil_bert_masked_lm_preprocessor.py +14 -76
- keras_hub/src/models/distil_bert/{distil_bert_classifier.py → distil_bert_text_classifier.py} +17 -12
- keras_hub/src/models/distil_bert/{distil_bert_preprocessor.py → distil_bert_text_classifier_preprocessor.py} +23 -63
- keras_hub/src/models/distil_bert/distil_bert_tokenizer.py +19 -35
- keras_hub/src/models/efficientnet/__init__.py +13 -0
- keras_hub/src/models/efficientnet/efficientnet_backbone.py +569 -0
- keras_hub/src/models/efficientnet/fusedmbconv.py +229 -0
- keras_hub/src/models/efficientnet/mbconv.py +238 -0
- keras_hub/src/models/electra/__init__.py +1 -2
- keras_hub/src/models/electra/electra_tokenizer.py +17 -32
- keras_hub/src/models/f_net/__init__.py +1 -2
- keras_hub/src/models/f_net/f_net_masked_lm_preprocessor.py +12 -78
- keras_hub/src/models/f_net/{f_net_classifier.py → f_net_text_classifier.py} +17 -10
- keras_hub/src/models/f_net/{f_net_preprocessor.py → f_net_text_classifier_preprocessor.py} +19 -63
- keras_hub/src/models/f_net/f_net_tokenizer.py +17 -35
- keras_hub/src/models/falcon/__init__.py +1 -2
- keras_hub/src/models/falcon/falcon_causal_lm_preprocessor.py +6 -89
- keras_hub/src/models/falcon/falcon_tokenizer.py +12 -35
- keras_hub/src/models/gemma/__init__.py +1 -2
- keras_hub/src/models/gemma/gemma_causal_lm_preprocessor.py +6 -90
- keras_hub/src/models/gemma/gemma_decoder_block.py +1 -1
- keras_hub/src/models/gemma/gemma_tokenizer.py +12 -23
- keras_hub/src/models/gpt2/__init__.py +1 -2
- keras_hub/src/models/gpt2/gpt2_causal_lm_preprocessor.py +6 -89
- keras_hub/src/models/gpt2/gpt2_preprocessor.py +12 -90
- keras_hub/src/models/gpt2/gpt2_tokenizer.py +12 -34
- keras_hub/src/models/gpt_neo_x/gpt_neo_x_causal_lm_preprocessor.py +6 -91
- keras_hub/src/models/gpt_neo_x/gpt_neo_x_tokenizer.py +12 -34
- keras_hub/src/models/image_classifier.py +0 -5
- keras_hub/src/models/image_classifier_preprocessor.py +83 -0
- keras_hub/src/models/llama/__init__.py +1 -2
- keras_hub/src/models/llama/llama_causal_lm_preprocessor.py +6 -85
- keras_hub/src/models/llama/llama_tokenizer.py +12 -25
- keras_hub/src/models/llama3/__init__.py +1 -2
- keras_hub/src/models/llama3/llama3_causal_lm_preprocessor.py +6 -89
- keras_hub/src/models/llama3/llama3_tokenizer.py +12 -33
- keras_hub/src/models/masked_lm.py +0 -2
- keras_hub/src/models/masked_lm_preprocessor.py +156 -0
- keras_hub/src/models/mistral/__init__.py +1 -2
- keras_hub/src/models/mistral/mistral_causal_lm_preprocessor.py +6 -91
- keras_hub/src/models/mistral/mistral_tokenizer.py +12 -23
- keras_hub/src/models/mix_transformer/mix_transformer_backbone.py +2 -2
- keras_hub/src/models/mobilenet/__init__.py +13 -0
- keras_hub/src/models/mobilenet/mobilenet_backbone.py +530 -0
- keras_hub/src/models/mobilenet/mobilenet_image_classifier.py +114 -0
- keras_hub/src/models/opt/__init__.py +1 -2
- keras_hub/src/models/opt/opt_causal_lm_preprocessor.py +6 -93
- keras_hub/src/models/opt/opt_tokenizer.py +12 -41
- keras_hub/src/models/pali_gemma/__init__.py +1 -4
- keras_hub/src/models/pali_gemma/pali_gemma_causal_lm_preprocessor.py +28 -28
- keras_hub/src/models/pali_gemma/pali_gemma_image_converter.py +25 -0
- keras_hub/src/models/pali_gemma/pali_gemma_presets.py +5 -5
- keras_hub/src/models/pali_gemma/pali_gemma_tokenizer.py +11 -3
- keras_hub/src/models/phi3/__init__.py +1 -2
- keras_hub/src/models/phi3/phi3_causal_lm.py +3 -9
- keras_hub/src/models/phi3/phi3_causal_lm_preprocessor.py +6 -89
- keras_hub/src/models/phi3/phi3_tokenizer.py +12 -36
- keras_hub/src/models/preprocessor.py +72 -83
- keras_hub/src/models/resnet/__init__.py +6 -0
- keras_hub/src/models/resnet/resnet_backbone.py +390 -42
- keras_hub/src/models/resnet/resnet_image_classifier.py +33 -6
- keras_hub/src/models/resnet/resnet_image_classifier_preprocessor.py +28 -0
- keras_hub/src/models/{llama3/llama3_preprocessor.py → resnet/resnet_image_converter.py} +7 -5
- keras_hub/src/models/resnet/resnet_presets.py +95 -0
- keras_hub/src/models/retinanet/__init__.py +13 -0
- keras_hub/src/models/retinanet/anchor_generator.py +175 -0
- keras_hub/src/models/retinanet/box_matcher.py +259 -0
- keras_hub/src/models/retinanet/non_max_supression.py +578 -0
- keras_hub/src/models/roberta/__init__.py +1 -2
- keras_hub/src/models/roberta/roberta_masked_lm_preprocessor.py +22 -74
- keras_hub/src/models/roberta/{roberta_classifier.py → roberta_text_classifier.py} +16 -11
- keras_hub/src/models/roberta/{roberta_preprocessor.py → roberta_text_classifier_preprocessor.py} +21 -53
- keras_hub/src/models/roberta/roberta_tokenizer.py +13 -52
- keras_hub/src/models/seq_2_seq_lm_preprocessor.py +269 -0
- keras_hub/src/models/stable_diffusion_v3/__init__.py +13 -0
- keras_hub/src/models/stable_diffusion_v3/clip_encoder_block.py +103 -0
- keras_hub/src/models/stable_diffusion_v3/clip_preprocessor.py +93 -0
- keras_hub/src/models/stable_diffusion_v3/clip_text_encoder.py +149 -0
- keras_hub/src/models/stable_diffusion_v3/clip_tokenizer.py +167 -0
- keras_hub/src/models/stable_diffusion_v3/mmdit.py +427 -0
- keras_hub/src/models/stable_diffusion_v3/mmdit_block.py +317 -0
- keras_hub/src/models/stable_diffusion_v3/t5_xxl_preprocessor.py +74 -0
- keras_hub/src/models/stable_diffusion_v3/t5_xxl_text_encoder.py +155 -0
- keras_hub/src/models/stable_diffusion_v3/vae_attention.py +126 -0
- keras_hub/src/models/stable_diffusion_v3/vae_image_decoder.py +186 -0
- keras_hub/src/models/t5/__init__.py +1 -2
- keras_hub/src/models/t5/t5_tokenizer.py +13 -23
- keras_hub/src/models/task.py +71 -116
- keras_hub/src/models/{classifier.py → text_classifier.py} +19 -13
- keras_hub/src/models/text_classifier_preprocessor.py +138 -0
- keras_hub/src/models/whisper/__init__.py +1 -2
- keras_hub/src/models/whisper/{whisper_audio_feature_extractor.py → whisper_audio_converter.py} +20 -18
- keras_hub/src/models/whisper/whisper_backbone.py +0 -3
- keras_hub/src/models/whisper/whisper_presets.py +10 -10
- keras_hub/src/models/whisper/whisper_tokenizer.py +20 -16
- keras_hub/src/models/xlm_roberta/__init__.py +1 -4
- keras_hub/src/models/xlm_roberta/xlm_roberta_masked_lm_preprocessor.py +26 -72
- keras_hub/src/models/xlm_roberta/{xlm_roberta_classifier.py → xlm_roberta_text_classifier.py} +16 -11
- keras_hub/src/models/xlm_roberta/{xlm_roberta_preprocessor.py → xlm_roberta_text_classifier_preprocessor.py} +26 -53
- keras_hub/src/models/xlm_roberta/xlm_roberta_tokenizer.py +25 -10
- keras_hub/src/tests/test_case.py +46 -0
- keras_hub/src/tokenizers/byte_pair_tokenizer.py +30 -17
- keras_hub/src/tokenizers/byte_tokenizer.py +14 -15
- keras_hub/src/tokenizers/sentence_piece_tokenizer.py +20 -7
- keras_hub/src/tokenizers/tokenizer.py +67 -32
- keras_hub/src/tokenizers/unicode_codepoint_tokenizer.py +14 -15
- keras_hub/src/tokenizers/word_piece_tokenizer.py +34 -47
- keras_hub/src/utils/imagenet/__init__.py +13 -0
- keras_hub/src/utils/imagenet/imagenet_utils.py +1067 -0
- keras_hub/src/utils/keras_utils.py +0 -50
- keras_hub/src/utils/preset_utils.py +230 -68
- keras_hub/src/utils/tensor_utils.py +187 -69
- keras_hub/src/utils/timm/convert_resnet.py +19 -16
- keras_hub/src/utils/timm/preset_loader.py +66 -0
- keras_hub/src/utils/transformers/convert_albert.py +193 -0
- keras_hub/src/utils/transformers/convert_bart.py +373 -0
- keras_hub/src/utils/transformers/convert_bert.py +7 -17
- keras_hub/src/utils/transformers/convert_distilbert.py +10 -20
- keras_hub/src/utils/transformers/convert_gemma.py +5 -19
- keras_hub/src/utils/transformers/convert_gpt2.py +5 -18
- keras_hub/src/utils/transformers/convert_llama3.py +7 -18
- keras_hub/src/utils/transformers/convert_mistral.py +129 -0
- keras_hub/src/utils/transformers/convert_pali_gemma.py +7 -29
- keras_hub/src/utils/transformers/preset_loader.py +77 -0
- keras_hub/src/utils/transformers/safetensor_utils.py +2 -2
- keras_hub/src/version_utils.py +1 -1
- keras_hub_nightly-0.16.0.dev2024092017.dist-info/METADATA +202 -0
- keras_hub_nightly-0.16.0.dev2024092017.dist-info/RECORD +334 -0
- {keras_hub_nightly-0.15.0.dev20240823171555.dist-info → keras_hub_nightly-0.16.0.dev2024092017.dist-info}/WHEEL +1 -1
- keras_hub/src/models/bart/bart_preprocessor.py +0 -276
- keras_hub/src/models/bloom/bloom_preprocessor.py +0 -185
- keras_hub/src/models/electra/electra_preprocessor.py +0 -154
- keras_hub/src/models/falcon/falcon_preprocessor.py +0 -187
- keras_hub/src/models/gemma/gemma_preprocessor.py +0 -191
- keras_hub/src/models/gpt_neo_x/gpt_neo_x_preprocessor.py +0 -145
- keras_hub/src/models/llama/llama_preprocessor.py +0 -189
- keras_hub/src/models/mistral/mistral_preprocessor.py +0 -190
- keras_hub/src/models/opt/opt_preprocessor.py +0 -188
- keras_hub/src/models/phi3/phi3_preprocessor.py +0 -190
- keras_hub/src/models/whisper/whisper_preprocessor.py +0 -326
- keras_hub/src/utils/timm/convert.py +0 -37
- keras_hub/src/utils/transformers/convert.py +0 -101
- keras_hub_nightly-0.15.0.dev20240823171555.dist-info/METADATA +0 -34
- keras_hub_nightly-0.15.0.dev20240823171555.dist-info/RECORD +0 -297
- {keras_hub_nightly-0.15.0.dev20240823171555.dist-info → keras_hub_nightly-0.16.0.dev2024092017.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,569 @@
|
|
1
|
+
# Copyright 2024 The KerasHub Authors
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
import math
|
15
|
+
|
16
|
+
import keras
|
17
|
+
|
18
|
+
from keras_hub.src.api_export import keras_hub_export
|
19
|
+
from keras_hub.src.models.efficientnet.fusedmbconv import FusedMBConvBlock
|
20
|
+
from keras_hub.src.models.efficientnet.mbconv import MBConvBlock
|
21
|
+
from keras_hub.src.models.feature_pyramid_backbone import FeaturePyramidBackbone
|
22
|
+
|
23
|
+
|
24
|
+
@keras_hub_export("keras_hub.models.EfficientNetBackbone")
|
25
|
+
class EfficientNetBackbone(FeaturePyramidBackbone):
|
26
|
+
"""An EfficientNet backbone model.
|
27
|
+
|
28
|
+
This class encapsulates the architectures for both EfficientNetV1 and
|
29
|
+
EfficientNetV2. EfficientNetV2 uses Fused-MBConv Blocks and Neural
|
30
|
+
Architecture Search (NAS) to make models sizes much smaller while still
|
31
|
+
improving overall model quality.
|
32
|
+
|
33
|
+
References:
|
34
|
+
- [EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks]
|
35
|
+
(https://arxiv.org/abs/1905.11946) (ICML 2019)
|
36
|
+
- [Based on the original keras.applications EfficientNet]
|
37
|
+
(https://github.com/keras-team/keras/blob/master/keras/applications/efficientnet.py)
|
38
|
+
- [EfficientNetV2: Smaller Models and Faster Training]
|
39
|
+
(https://arxiv.org/abs/2104.00298) (ICML 2021)
|
40
|
+
|
41
|
+
Args:
|
42
|
+
width_coefficient: float, scaling coefficient for network width.
|
43
|
+
depth_coefficient: float, scaling coefficient for network depth.
|
44
|
+
dropout: float, dropout rate at skip connections. The default
|
45
|
+
value is set to 0.2.
|
46
|
+
depth_divisor: integer, a unit of network width. The default value is
|
47
|
+
set to 8.
|
48
|
+
activation: activation function to use between each convolutional layer.
|
49
|
+
input_shape: optional shape tuple, it should have exactly 3 input
|
50
|
+
channels.
|
51
|
+
stackwise_kernel_sizes: list of ints, the kernel sizes used for each
|
52
|
+
conv block.
|
53
|
+
stackwise_num_repeats: list of ints, number of times to repeat each
|
54
|
+
conv block.
|
55
|
+
stackwise_input_filters: list of ints, number of input filters for
|
56
|
+
each conv block.
|
57
|
+
stackwise_output_filters: list of ints, number of output filters for
|
58
|
+
each stack in the conv blocks model.
|
59
|
+
stackwise_expansion_ratios: list of floats, expand ratio passed to the
|
60
|
+
squeeze and excitation blocks.
|
61
|
+
stackwise_strides: list of ints, stackwise_strides for each conv block.
|
62
|
+
stackwise_squeeze_and_excite_ratios: list of ints, the squeeze and
|
63
|
+
excite ratios passed to the squeeze and excitation blocks.
|
64
|
+
stackwise_block_types: list of strings. Each value is either 'v1',
|
65
|
+
'unfused' or 'fused' depending on the desired blocks. 'v1' uses the
|
66
|
+
original efficientnet block. FusedMBConvBlock is similar to
|
67
|
+
MBConvBlock, but instead of using a depthwise convolution and a 1x1
|
68
|
+
output convolution blocks fused blocks use a single 3x3 convolution
|
69
|
+
block.
|
70
|
+
include_rescaling: bool, whether to rescale the inputs. If set to
|
71
|
+
True, inputs will be passed through a `Rescaling(1/255.0)` layer.
|
72
|
+
min_depth: integer, minimum number of filters. Can be None and ignored
|
73
|
+
if use_depth_divisor_as_min_depth is set to True.
|
74
|
+
include_initial_padding: bool, whether to include initial zero padding
|
75
|
+
(as per v1).
|
76
|
+
use_depth_divisor_as_min_depth: bool, whether to use depth_divisor as
|
77
|
+
the minimum depth instead of min_depth (as per v1).
|
78
|
+
cap_round_filter_decrease: bool, whether to cap the max decrease in the
|
79
|
+
number of filters the rounding process potentially produces
|
80
|
+
(as per v1).
|
81
|
+
stem_conv_padding: str, can be 'same' or 'valid'. Padding for the stem.
|
82
|
+
batch_norm_momentum: float, momentum for the moving average calcualtion
|
83
|
+
in the batch normalization layers.
|
84
|
+
|
85
|
+
Example:
|
86
|
+
```python
|
87
|
+
# You can customize the EfficientNet architecture:
|
88
|
+
model = EfficientNetBackbone(
|
89
|
+
stackwise_kernel_sizes=[3, 3, 3, 3, 3, 3],
|
90
|
+
stackwise_num_repeats=[2, 4, 4, 6, 9, 15],
|
91
|
+
stackwise_input_filters=[24, 24, 48, 64, 128, 160],
|
92
|
+
stackwise_output_filters=[24, 48, 64, 128, 160, 256],
|
93
|
+
stackwise_expansion_ratios=[1, 4, 4, 4, 6, 6],
|
94
|
+
stackwise_squeeze_and_excite_ratios=[0.0, 0.0, 0, 0.25, 0.25, 0.25],
|
95
|
+
stackwise_strides=[1, 2, 2, 2, 1, 2],
|
96
|
+
stackwise_block_types=[["fused"] * 3 + ["unfused"] * 3],
|
97
|
+
width_coefficient=1.0,
|
98
|
+
depth_coefficient=1.0,
|
99
|
+
include_rescaling=False,
|
100
|
+
)
|
101
|
+
images = np.ones((1, 256, 256, 3))
|
102
|
+
outputs = efficientnet.predict(images)
|
103
|
+
```
|
104
|
+
"""
|
105
|
+
|
106
|
+
def __init__(
|
107
|
+
self,
|
108
|
+
*,
|
109
|
+
width_coefficient,
|
110
|
+
depth_coefficient,
|
111
|
+
stackwise_kernel_sizes,
|
112
|
+
stackwise_num_repeats,
|
113
|
+
stackwise_input_filters,
|
114
|
+
stackwise_output_filters,
|
115
|
+
stackwise_expansion_ratios,
|
116
|
+
stackwise_squeeze_and_excite_ratios,
|
117
|
+
stackwise_strides,
|
118
|
+
stackwise_block_types,
|
119
|
+
include_rescaling=True,
|
120
|
+
dropout=0.2,
|
121
|
+
depth_divisor=8,
|
122
|
+
min_depth=8,
|
123
|
+
input_shape=(None, None, 3),
|
124
|
+
activation="swish",
|
125
|
+
include_initial_padding=False,
|
126
|
+
use_depth_divisor_as_min_depth=False,
|
127
|
+
cap_round_filter_decrease=False,
|
128
|
+
stem_conv_padding="same",
|
129
|
+
batch_norm_momentum=0.9,
|
130
|
+
**kwargs,
|
131
|
+
):
|
132
|
+
img_input = keras.layers.Input(shape=input_shape)
|
133
|
+
|
134
|
+
x = img_input
|
135
|
+
|
136
|
+
if include_rescaling:
|
137
|
+
# Use common rescaling strategy across keras
|
138
|
+
x = keras.layers.Rescaling(scale=1.0 / 255.0)(x)
|
139
|
+
|
140
|
+
if include_initial_padding:
|
141
|
+
x = keras.layers.ZeroPadding2D(
|
142
|
+
padding=self._correct_pad_downsample(x, 3),
|
143
|
+
name="stem_conv_pad",
|
144
|
+
)(x)
|
145
|
+
|
146
|
+
# Build stem
|
147
|
+
stem_filters = round_filters(
|
148
|
+
filters=stackwise_input_filters[0],
|
149
|
+
width_coefficient=width_coefficient,
|
150
|
+
min_depth=min_depth,
|
151
|
+
depth_divisor=depth_divisor,
|
152
|
+
use_depth_divisor_as_min_depth=use_depth_divisor_as_min_depth,
|
153
|
+
cap_round_filter_decrease=cap_round_filter_decrease,
|
154
|
+
)
|
155
|
+
|
156
|
+
x = keras.layers.Conv2D(
|
157
|
+
filters=stem_filters,
|
158
|
+
kernel_size=3,
|
159
|
+
strides=2,
|
160
|
+
padding=stem_conv_padding,
|
161
|
+
use_bias=False,
|
162
|
+
kernel_initializer=conv_kernel_initializer(),
|
163
|
+
name="stem_conv",
|
164
|
+
)(x)
|
165
|
+
|
166
|
+
x = keras.layers.BatchNormalization(
|
167
|
+
momentum=batch_norm_momentum,
|
168
|
+
name="stem_bn",
|
169
|
+
)(x)
|
170
|
+
x = keras.layers.Activation(activation, name="stem_activation")(x)
|
171
|
+
|
172
|
+
# Build blocks
|
173
|
+
block_id = 0
|
174
|
+
blocks = float(sum(stackwise_num_repeats))
|
175
|
+
|
176
|
+
self._pyramid_outputs = {}
|
177
|
+
curr_pyramid_level = 1
|
178
|
+
|
179
|
+
for i in range(len(stackwise_kernel_sizes)):
|
180
|
+
num_repeats = stackwise_num_repeats[i]
|
181
|
+
input_filters = stackwise_input_filters[i]
|
182
|
+
output_filters = stackwise_output_filters[i]
|
183
|
+
|
184
|
+
# Update block input and output filters based on depth multiplier.
|
185
|
+
input_filters = round_filters(
|
186
|
+
filters=input_filters,
|
187
|
+
width_coefficient=width_coefficient,
|
188
|
+
min_depth=min_depth,
|
189
|
+
depth_divisor=depth_divisor,
|
190
|
+
use_depth_divisor_as_min_depth=use_depth_divisor_as_min_depth,
|
191
|
+
cap_round_filter_decrease=cap_round_filter_decrease,
|
192
|
+
)
|
193
|
+
output_filters = round_filters(
|
194
|
+
filters=output_filters,
|
195
|
+
width_coefficient=width_coefficient,
|
196
|
+
min_depth=min_depth,
|
197
|
+
depth_divisor=depth_divisor,
|
198
|
+
use_depth_divisor_as_min_depth=use_depth_divisor_as_min_depth,
|
199
|
+
cap_round_filter_decrease=cap_round_filter_decrease,
|
200
|
+
)
|
201
|
+
|
202
|
+
repeats = round_repeats(
|
203
|
+
repeats=num_repeats,
|
204
|
+
depth_coefficient=depth_coefficient,
|
205
|
+
)
|
206
|
+
strides = stackwise_strides[i]
|
207
|
+
squeeze_and_excite_ratio = stackwise_squeeze_and_excite_ratios[i]
|
208
|
+
|
209
|
+
for j in range(repeats):
|
210
|
+
# The first block needs to take care of stride and filter size
|
211
|
+
# increase.
|
212
|
+
if j > 0:
|
213
|
+
strides = 1
|
214
|
+
input_filters = output_filters
|
215
|
+
|
216
|
+
if strides != 1:
|
217
|
+
self._pyramid_outputs[f"P{curr_pyramid_level}"] = x
|
218
|
+
curr_pyramid_level += 1
|
219
|
+
|
220
|
+
# 97 is the start of the lowercase alphabet.
|
221
|
+
letter_identifier = chr(j + 97)
|
222
|
+
stackwise_block_type = stackwise_block_types[i]
|
223
|
+
block_name = f"block{i + 1}{letter_identifier}_"
|
224
|
+
if stackwise_block_type == "v1":
|
225
|
+
x = self._apply_efficientnet_block(
|
226
|
+
inputs=x,
|
227
|
+
filters_in=input_filters,
|
228
|
+
filters_out=output_filters,
|
229
|
+
kernel_size=stackwise_kernel_sizes[i],
|
230
|
+
strides=strides,
|
231
|
+
expand_ratio=stackwise_expansion_ratios[i],
|
232
|
+
se_ratio=squeeze_and_excite_ratio,
|
233
|
+
activation=activation,
|
234
|
+
dropout=dropout * block_id / blocks,
|
235
|
+
name=block_name,
|
236
|
+
)
|
237
|
+
else:
|
238
|
+
block = get_conv_constructor(stackwise_block_type)(
|
239
|
+
input_filters=input_filters,
|
240
|
+
output_filters=output_filters,
|
241
|
+
expand_ratio=stackwise_expansion_ratios[i],
|
242
|
+
kernel_size=stackwise_kernel_sizes[i],
|
243
|
+
strides=strides,
|
244
|
+
se_ratio=squeeze_and_excite_ratio,
|
245
|
+
activation=activation,
|
246
|
+
dropout=dropout * block_id / blocks,
|
247
|
+
batch_norm_momentum=batch_norm_momentum,
|
248
|
+
name=block_name,
|
249
|
+
)
|
250
|
+
x = block(x)
|
251
|
+
block_id += 1
|
252
|
+
|
253
|
+
# Build top
|
254
|
+
top_filters = round_filters(
|
255
|
+
filters=1280,
|
256
|
+
width_coefficient=width_coefficient,
|
257
|
+
min_depth=min_depth,
|
258
|
+
depth_divisor=depth_divisor,
|
259
|
+
use_depth_divisor_as_min_depth=use_depth_divisor_as_min_depth,
|
260
|
+
cap_round_filter_decrease=cap_round_filter_decrease,
|
261
|
+
)
|
262
|
+
|
263
|
+
x = keras.layers.Conv2D(
|
264
|
+
filters=top_filters,
|
265
|
+
kernel_size=1,
|
266
|
+
padding="same",
|
267
|
+
strides=1,
|
268
|
+
kernel_initializer=conv_kernel_initializer(),
|
269
|
+
use_bias=False,
|
270
|
+
name="top_conv",
|
271
|
+
data_format="channels_last",
|
272
|
+
)(x)
|
273
|
+
x = keras.layers.BatchNormalization(
|
274
|
+
momentum=batch_norm_momentum,
|
275
|
+
name="top_bn",
|
276
|
+
)(x)
|
277
|
+
x = keras.layers.Activation(
|
278
|
+
activation=activation, name="top_activation"
|
279
|
+
)(x)
|
280
|
+
|
281
|
+
self._pyramid_outputs[f"P{curr_pyramid_level}"] = x
|
282
|
+
curr_pyramid_level += 1
|
283
|
+
|
284
|
+
# Create model.
|
285
|
+
super().__init__(inputs=img_input, outputs=x, **kwargs)
|
286
|
+
|
287
|
+
# === Config ===
|
288
|
+
self.include_rescaling = include_rescaling
|
289
|
+
self.width_coefficient = width_coefficient
|
290
|
+
self.depth_coefficient = depth_coefficient
|
291
|
+
self.dropout = dropout
|
292
|
+
self.depth_divisor = depth_divisor
|
293
|
+
self.min_depth = min_depth
|
294
|
+
self.activation = activation
|
295
|
+
self.stackwise_kernel_sizes = stackwise_kernel_sizes
|
296
|
+
self.stackwise_num_repeats = stackwise_num_repeats
|
297
|
+
self.stackwise_input_filters = stackwise_input_filters
|
298
|
+
self.stackwise_output_filters = stackwise_output_filters
|
299
|
+
self.stackwise_expansion_ratios = stackwise_expansion_ratios
|
300
|
+
self.stackwise_squeeze_and_excite_ratios = (
|
301
|
+
stackwise_squeeze_and_excite_ratios
|
302
|
+
)
|
303
|
+
self.stackwise_strides = stackwise_strides
|
304
|
+
self.stackwise_block_types = stackwise_block_types
|
305
|
+
|
306
|
+
self.include_initial_padding = include_initial_padding
|
307
|
+
self.use_depth_divisor_as_min_depth = use_depth_divisor_as_min_depth
|
308
|
+
self.cap_round_filter_decrease = cap_round_filter_decrease
|
309
|
+
self.stem_conv_padding = stem_conv_padding
|
310
|
+
self.batch_norm_momentum = batch_norm_momentum
|
311
|
+
|
312
|
+
def get_config(self):
|
313
|
+
config = super().get_config()
|
314
|
+
config.update(
|
315
|
+
{
|
316
|
+
"include_rescaling": self.include_rescaling,
|
317
|
+
"width_coefficient": self.width_coefficient,
|
318
|
+
"depth_coefficient": self.depth_coefficient,
|
319
|
+
"dropout": self.dropout,
|
320
|
+
"depth_divisor": self.depth_divisor,
|
321
|
+
"min_depth": self.min_depth,
|
322
|
+
"activation": self.activation,
|
323
|
+
"input_shape": self.input_shape[1:],
|
324
|
+
"stackwise_kernel_sizes": self.stackwise_kernel_sizes,
|
325
|
+
"stackwise_num_repeats": self.stackwise_num_repeats,
|
326
|
+
"stackwise_input_filters": self.stackwise_input_filters,
|
327
|
+
"stackwise_output_filters": self.stackwise_output_filters,
|
328
|
+
"stackwise_expansion_ratios": self.stackwise_expansion_ratios,
|
329
|
+
"stackwise_squeeze_and_excite_ratios": self.stackwise_squeeze_and_excite_ratios,
|
330
|
+
"stackwise_strides": self.stackwise_strides,
|
331
|
+
"stackwise_block_types": self.stackwise_block_types,
|
332
|
+
"include_initial_padding": self.include_initial_padding,
|
333
|
+
"use_depth_divisor_as_min_depth": self.use_depth_divisor_as_min_depth,
|
334
|
+
"cap_round_filter_decrease": self.cap_round_filter_decrease,
|
335
|
+
"stem_conv_padding": self.stem_conv_padding,
|
336
|
+
"batch_norm_momentum": self.batch_norm_momentum,
|
337
|
+
}
|
338
|
+
)
|
339
|
+
return config
|
340
|
+
|
341
|
+
def _correct_pad_downsample(self, inputs, kernel_size):
|
342
|
+
"""Returns a tuple for zero-padding for 2D convolution with downsampling.
|
343
|
+
|
344
|
+
Args:
|
345
|
+
inputs: Input tensor.
|
346
|
+
kernel_size: An integer or tuple/list of 2 integers.
|
347
|
+
|
348
|
+
Returns:
|
349
|
+
A tuple.
|
350
|
+
"""
|
351
|
+
img_dim = 1
|
352
|
+
input_size = inputs.shape[img_dim : (img_dim + 2)]
|
353
|
+
if isinstance(kernel_size, int):
|
354
|
+
kernel_size = (kernel_size, kernel_size)
|
355
|
+
if input_size[0] is None:
|
356
|
+
adjust = (1, 1)
|
357
|
+
else:
|
358
|
+
adjust = (1 - input_size[0] % 2, 1 - input_size[1] % 2)
|
359
|
+
correct = (kernel_size[0] // 2, kernel_size[1] // 2)
|
360
|
+
return (
|
361
|
+
(correct[0] - adjust[0], correct[0]),
|
362
|
+
(correct[1] - adjust[1], correct[1]),
|
363
|
+
)
|
364
|
+
|
365
|
+
def _apply_efficientnet_block(
|
366
|
+
self,
|
367
|
+
inputs,
|
368
|
+
filters_in=32,
|
369
|
+
filters_out=16,
|
370
|
+
kernel_size=3,
|
371
|
+
strides=1,
|
372
|
+
activation="swish",
|
373
|
+
expand_ratio=1,
|
374
|
+
se_ratio=0.0,
|
375
|
+
dropout=0.0,
|
376
|
+
name="",
|
377
|
+
):
|
378
|
+
"""An inverted residual block.
|
379
|
+
|
380
|
+
Args:
|
381
|
+
inputs: Tensor, The input tensor of the block
|
382
|
+
filters_in: integer, the number of input filters.
|
383
|
+
filters_out: integer, the number of output filters.
|
384
|
+
kernel_size: integer, the dimension of the convolution window.
|
385
|
+
strides: integer, the stride of the convolution.
|
386
|
+
activation: activation function to use between each convolutional layer.
|
387
|
+
expand_ratio: integer, scaling coefficient for the input filters.
|
388
|
+
se_ratio: float between 0 and 1, fraction to squeeze the input filters.
|
389
|
+
dropout: float between 0 and 1, fraction of the input units to drop.
|
390
|
+
name: string, block label.
|
391
|
+
|
392
|
+
Returns:
|
393
|
+
output tensor for the block.
|
394
|
+
"""
|
395
|
+
filters = filters_in * expand_ratio
|
396
|
+
if expand_ratio != 1:
|
397
|
+
x = keras.layers.Conv2D(
|
398
|
+
filters=filters,
|
399
|
+
kernel_size=1,
|
400
|
+
strides=1,
|
401
|
+
padding="same",
|
402
|
+
use_bias=False,
|
403
|
+
kernel_initializer=conv_kernel_initializer(),
|
404
|
+
name=name + "expand_conv",
|
405
|
+
)(inputs)
|
406
|
+
x = keras.layers.BatchNormalization(
|
407
|
+
axis=3,
|
408
|
+
name=name + "expand_bn",
|
409
|
+
)(x)
|
410
|
+
x = keras.layers.Activation(
|
411
|
+
activation, name=name + "expand_activation"
|
412
|
+
)(x)
|
413
|
+
else:
|
414
|
+
x = inputs
|
415
|
+
|
416
|
+
# Depthwise Convolution
|
417
|
+
if strides == 2:
|
418
|
+
x = keras.layers.ZeroPadding2D(
|
419
|
+
padding=self._correct_pad_downsample(x, kernel_size),
|
420
|
+
name=name + "dwconv_pad",
|
421
|
+
)(x)
|
422
|
+
conv_pad = "valid"
|
423
|
+
else:
|
424
|
+
conv_pad = "same"
|
425
|
+
|
426
|
+
x = keras.layers.DepthwiseConv2D(
|
427
|
+
kernel_size=kernel_size,
|
428
|
+
strides=strides,
|
429
|
+
padding=conv_pad,
|
430
|
+
use_bias=False,
|
431
|
+
depthwise_initializer=conv_kernel_initializer(),
|
432
|
+
name=name + "dwconv",
|
433
|
+
)(x)
|
434
|
+
x = keras.layers.BatchNormalization(
|
435
|
+
axis=3,
|
436
|
+
name=name + "dwconv_bn",
|
437
|
+
)(x)
|
438
|
+
x = keras.layers.Activation(
|
439
|
+
activation, name=name + "dwconv_activation"
|
440
|
+
)(x)
|
441
|
+
|
442
|
+
# Squeeze and Excitation phase
|
443
|
+
if 0 < se_ratio <= 1:
|
444
|
+
filters_se = max(1, int(filters_in * se_ratio))
|
445
|
+
se = keras.layers.GlobalAveragePooling2D(name=name + "se_squeeze")(
|
446
|
+
x
|
447
|
+
)
|
448
|
+
se_shape = (1, 1, filters)
|
449
|
+
se = keras.layers.Reshape(se_shape, name=name + "se_reshape")(se)
|
450
|
+
se = keras.layers.Conv2D(
|
451
|
+
filters_se,
|
452
|
+
1,
|
453
|
+
padding="same",
|
454
|
+
activation=activation,
|
455
|
+
kernel_initializer=conv_kernel_initializer(),
|
456
|
+
name=name + "se_reduce",
|
457
|
+
)(se)
|
458
|
+
se = keras.layers.Conv2D(
|
459
|
+
filters,
|
460
|
+
1,
|
461
|
+
padding="same",
|
462
|
+
activation="sigmoid",
|
463
|
+
kernel_initializer=conv_kernel_initializer(),
|
464
|
+
name=name + "se_expand",
|
465
|
+
)(se)
|
466
|
+
x = keras.layers.multiply([x, se], name=name + "se_excite")
|
467
|
+
|
468
|
+
# Output phase
|
469
|
+
x = keras.layers.Conv2D(
|
470
|
+
filters=filters_out,
|
471
|
+
kernel_size=1,
|
472
|
+
strides=1,
|
473
|
+
padding="same",
|
474
|
+
use_bias=False,
|
475
|
+
kernel_initializer=conv_kernel_initializer(),
|
476
|
+
name=name + "project",
|
477
|
+
)(x)
|
478
|
+
x = keras.layers.BatchNormalization(
|
479
|
+
axis=3,
|
480
|
+
name=name + "project_bn",
|
481
|
+
)(x)
|
482
|
+
x = keras.layers.Activation(
|
483
|
+
activation, name=name + "project_activation"
|
484
|
+
)(x)
|
485
|
+
|
486
|
+
if strides == 1 and filters_in == filters_out:
|
487
|
+
if dropout > 0:
|
488
|
+
x = keras.layers.Dropout(
|
489
|
+
dropout,
|
490
|
+
noise_shape=(None, 1, 1, 1),
|
491
|
+
name=name + "drop",
|
492
|
+
)(x)
|
493
|
+
x = keras.layers.Add(name=name + "add")([x, inputs])
|
494
|
+
|
495
|
+
return x
|
496
|
+
|
497
|
+
|
498
|
+
def conv_kernel_initializer(scale=2.0):
|
499
|
+
return keras.initializers.VarianceScaling(
|
500
|
+
scale=scale, mode="fan_out", distribution="truncated_normal"
|
501
|
+
)
|
502
|
+
|
503
|
+
|
504
|
+
def round_filters(
|
505
|
+
filters,
|
506
|
+
width_coefficient,
|
507
|
+
min_depth,
|
508
|
+
depth_divisor,
|
509
|
+
use_depth_divisor_as_min_depth,
|
510
|
+
cap_round_filter_decrease,
|
511
|
+
):
|
512
|
+
"""Round number of filters based on depth multiplier.
|
513
|
+
|
514
|
+
Args:
|
515
|
+
filters: int, number of filters for Conv layer
|
516
|
+
width_coefficient: float, denotes the scaling coefficient of network
|
517
|
+
width
|
518
|
+
depth_divisor: int, a unit of network width
|
519
|
+
use_depth_divisor_as_min_depth: bool, whether to use depth_divisor as
|
520
|
+
the minimum depth instead of min_depth (as per v1)
|
521
|
+
max_round_filter_decrease: bool, whether to cap the decrease in the
|
522
|
+
number of filters this process produces (as per v1)
|
523
|
+
|
524
|
+
Returns:
|
525
|
+
int, new rounded filters value for Conv layer
|
526
|
+
"""
|
527
|
+
filters *= width_coefficient
|
528
|
+
|
529
|
+
if use_depth_divisor_as_min_depth:
|
530
|
+
min_depth = depth_divisor
|
531
|
+
|
532
|
+
new_filters = max(
|
533
|
+
min_depth,
|
534
|
+
int(filters + depth_divisor / 2) // depth_divisor * depth_divisor,
|
535
|
+
)
|
536
|
+
|
537
|
+
if cap_round_filter_decrease:
|
538
|
+
# Make sure that round down does not go down by more than 10%.
|
539
|
+
if new_filters < 0.9 * filters:
|
540
|
+
new_filters += depth_divisor
|
541
|
+
|
542
|
+
return int(new_filters)
|
543
|
+
|
544
|
+
|
545
|
+
def round_repeats(repeats, depth_coefficient):
|
546
|
+
"""Round number of repeats based on depth multiplier.
|
547
|
+
|
548
|
+
Args:
|
549
|
+
repeats: int, number of repeats of efficientnet block
|
550
|
+
depth_coefficient: float, denotes the scaling coefficient of network
|
551
|
+
depth
|
552
|
+
|
553
|
+
Returns:
|
554
|
+
int, rounded repeats
|
555
|
+
"""
|
556
|
+
return int(math.ceil(depth_coefficient * repeats))
|
557
|
+
|
558
|
+
|
559
|
+
def get_conv_constructor(conv_type):
|
560
|
+
if conv_type == "unfused":
|
561
|
+
return MBConvBlock
|
562
|
+
elif conv_type == "fused":
|
563
|
+
return FusedMBConvBlock
|
564
|
+
else:
|
565
|
+
raise ValueError(
|
566
|
+
"Expected `conv_type` to be "
|
567
|
+
"one of 'unfused', 'fused', but got "
|
568
|
+
f"`conv_type={conv_type}`"
|
569
|
+
)
|