keras-hub-nightly 0.19.0.dev202503060350__py3-none-any.whl → 0.20.0.dev202503150350__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/api/layers/__init__.py +3 -0
- keras_hub/api/models/__init__.py +5 -4
- keras_hub/src/models/cspnet/__init__.py +5 -0
- keras_hub/src/models/cspnet/cspnet_backbone.py +1279 -0
- keras_hub/src/models/cspnet/cspnet_image_classifier.py +12 -0
- keras_hub/src/models/cspnet/cspnet_image_classifier_preprocessor.py +14 -0
- keras_hub/src/models/cspnet/cspnet_image_converter.py +8 -0
- keras_hub/src/models/cspnet/cspnet_presets.py +16 -0
- keras_hub/src/models/gemma/gemma_attention.py +23 -12
- keras_hub/src/models/mobilenet/mobilenet_backbone.py +18 -1
- keras_hub/src/models/mobilenet/mobilenet_image_classifier.py +4 -1
- keras_hub/src/models/mobilenet/mobilenet_presets.py +38 -2
- keras_hub/src/models/siglip/siglip_presets.py +206 -10
- keras_hub/src/models/siglip/siglip_text_encoder.py +7 -1
- keras_hub/src/utils/keras_utils.py +32 -0
- keras_hub/src/utils/preset_utils.py +1 -0
- keras_hub/src/utils/timm/convert_cspnet.py +165 -0
- keras_hub/src/utils/timm/convert_mobilenet.py +120 -44
- keras_hub/src/utils/timm/preset_loader.py +9 -0
- keras_hub/src/version_utils.py +1 -1
- {keras_hub_nightly-0.19.0.dev202503060350.dist-info → keras_hub_nightly-0.20.0.dev202503150350.dist-info}/METADATA +1 -1
- {keras_hub_nightly-0.19.0.dev202503060350.dist-info → keras_hub_nightly-0.20.0.dev202503150350.dist-info}/RECORD +24 -20
- {keras_hub_nightly-0.19.0.dev202503060350.dist-info → keras_hub_nightly-0.20.0.dev202503150350.dist-info}/WHEEL +1 -1
- keras_hub/src/models/csp_darknet/__init__.py +0 -0
- keras_hub/src/models/csp_darknet/csp_darknet_backbone.py +0 -427
- keras_hub/src/models/csp_darknet/csp_darknet_image_classifier.py +0 -10
- {keras_hub_nightly-0.19.0.dev202503060350.dist-info → keras_hub_nightly-0.20.0.dev202503150350.dist-info}/top_level.txt +0 -0
@@ -1,427 +0,0 @@
|
|
1
|
-
import keras
|
2
|
-
from keras import layers
|
3
|
-
|
4
|
-
from keras_hub.src.api_export import keras_hub_export
|
5
|
-
from keras_hub.src.models.feature_pyramid_backbone import FeaturePyramidBackbone
|
6
|
-
|
7
|
-
|
8
|
-
@keras_hub_export("keras_hub.models.CSPDarkNetBackbone")
|
9
|
-
class CSPDarkNetBackbone(FeaturePyramidBackbone):
|
10
|
-
"""This class represents Keras Backbone of CSPDarkNet model.
|
11
|
-
|
12
|
-
This class implements a CSPDarkNet backbone as described in
|
13
|
-
[CSPNet: A New Backbone that can Enhance Learning Capability of CNN](
|
14
|
-
https://arxiv.org/abs/1911.11929).
|
15
|
-
|
16
|
-
Args:
|
17
|
-
stackwise_num_filters: A list of ints, filter size for each dark
|
18
|
-
level in the model.
|
19
|
-
stackwise_depth: A list of ints, the depth for each dark level in the
|
20
|
-
model.
|
21
|
-
block_type: str. One of `"basic_block"` or `"depthwise_block"`.
|
22
|
-
Use `"depthwise_block"` for depthwise conv block
|
23
|
-
`"basic_block"` for basic conv block.
|
24
|
-
Defaults to "basic_block".
|
25
|
-
image_shape: tuple. The input shape without the batch size.
|
26
|
-
Defaults to `(None, None, 3)`.
|
27
|
-
|
28
|
-
Examples:
|
29
|
-
```python
|
30
|
-
input_data = np.ones(shape=(8, 224, 224, 3))
|
31
|
-
|
32
|
-
# Pretrained backbone
|
33
|
-
model = keras_hub.models.CSPDarkNetBackbone.from_preset(
|
34
|
-
"csp_darknet_tiny_imagenet"
|
35
|
-
)
|
36
|
-
model(input_data)
|
37
|
-
|
38
|
-
# Randomly initialized backbone with a custom config
|
39
|
-
model = keras_hub.models.CSPDarkNetBackbone(
|
40
|
-
stackwise_num_filters=[128, 256, 512, 1024],
|
41
|
-
stackwise_depth=[3, 9, 9, 3],
|
42
|
-
)
|
43
|
-
model(input_data)
|
44
|
-
```
|
45
|
-
"""
|
46
|
-
|
47
|
-
def __init__(
|
48
|
-
self,
|
49
|
-
stackwise_num_filters,
|
50
|
-
stackwise_depth,
|
51
|
-
block_type="basic_block",
|
52
|
-
image_shape=(None, None, 3),
|
53
|
-
**kwargs,
|
54
|
-
):
|
55
|
-
# === Functional Model ===
|
56
|
-
channel_axis = (
|
57
|
-
-1 if keras.config.image_data_format() == "channels_last" else 1
|
58
|
-
)
|
59
|
-
apply_ConvBlock = (
|
60
|
-
apply_darknet_conv_block_depthwise
|
61
|
-
if block_type == "depthwise_block"
|
62
|
-
else apply_darknet_conv_block
|
63
|
-
)
|
64
|
-
base_channels = stackwise_num_filters[0] // 2
|
65
|
-
|
66
|
-
image_input = layers.Input(shape=image_shape)
|
67
|
-
x = image_input # Intermediate result.
|
68
|
-
x = apply_focus(channel_axis, name="stem_focus")(x)
|
69
|
-
x = apply_darknet_conv_block(
|
70
|
-
base_channels,
|
71
|
-
channel_axis,
|
72
|
-
kernel_size=3,
|
73
|
-
strides=1,
|
74
|
-
name="stem_conv",
|
75
|
-
)(x)
|
76
|
-
|
77
|
-
pyramid_outputs = {}
|
78
|
-
for index, (channels, depth) in enumerate(
|
79
|
-
zip(stackwise_num_filters, stackwise_depth)
|
80
|
-
):
|
81
|
-
x = apply_ConvBlock(
|
82
|
-
channels,
|
83
|
-
channel_axis,
|
84
|
-
kernel_size=3,
|
85
|
-
strides=2,
|
86
|
-
name=f"dark{index + 2}_conv",
|
87
|
-
)(x)
|
88
|
-
|
89
|
-
if index == len(stackwise_depth) - 1:
|
90
|
-
x = apply_spatial_pyramid_pooling_bottleneck(
|
91
|
-
channels,
|
92
|
-
channel_axis,
|
93
|
-
hidden_filters=channels // 2,
|
94
|
-
name=f"dark{index + 2}_spp",
|
95
|
-
)(x)
|
96
|
-
|
97
|
-
x = apply_cross_stage_partial(
|
98
|
-
channels,
|
99
|
-
channel_axis,
|
100
|
-
num_bottlenecks=depth,
|
101
|
-
block_type="basic_block",
|
102
|
-
residual=(index != len(stackwise_depth) - 1),
|
103
|
-
name=f"dark{index + 2}_csp",
|
104
|
-
)(x)
|
105
|
-
pyramid_outputs[f"P{index + 2}"] = x
|
106
|
-
|
107
|
-
super().__init__(inputs=image_input, outputs=x, **kwargs)
|
108
|
-
|
109
|
-
# === Config ===
|
110
|
-
self.stackwise_num_filters = stackwise_num_filters
|
111
|
-
self.stackwise_depth = stackwise_depth
|
112
|
-
self.block_type = block_type
|
113
|
-
self.image_shape = image_shape
|
114
|
-
self.pyramid_outputs = pyramid_outputs
|
115
|
-
|
116
|
-
def get_config(self):
|
117
|
-
config = super().get_config()
|
118
|
-
config.update(
|
119
|
-
{
|
120
|
-
"stackwise_num_filters": self.stackwise_num_filters,
|
121
|
-
"stackwise_depth": self.stackwise_depth,
|
122
|
-
"block_type": self.block_type,
|
123
|
-
"image_shape": self.image_shape,
|
124
|
-
}
|
125
|
-
)
|
126
|
-
return config
|
127
|
-
|
128
|
-
|
129
|
-
def apply_focus(channel_axis, name=None):
|
130
|
-
"""A block used in CSPDarknet to focus information into channels of the
|
131
|
-
image.
|
132
|
-
|
133
|
-
If the dimensions of a batch input is (batch_size, width, height, channels),
|
134
|
-
this layer converts the image into size (batch_size, width/2, height/2,
|
135
|
-
4*channels). See [the original discussion on YoloV5 Focus Layer](https://github.com/ultralytics/yolov5/discussions/3181).
|
136
|
-
|
137
|
-
Args:
|
138
|
-
name: the name for the lambda layer used in the block.
|
139
|
-
|
140
|
-
Returns:
|
141
|
-
a function that takes an input Tensor representing a Focus layer.
|
142
|
-
"""
|
143
|
-
|
144
|
-
def apply(x):
|
145
|
-
return layers.Concatenate(axis=channel_axis, name=name)(
|
146
|
-
[
|
147
|
-
x[..., ::2, ::2, :],
|
148
|
-
x[..., 1::2, ::2, :],
|
149
|
-
x[..., ::2, 1::2, :],
|
150
|
-
x[..., 1::2, 1::2, :],
|
151
|
-
],
|
152
|
-
)
|
153
|
-
|
154
|
-
return apply
|
155
|
-
|
156
|
-
|
157
|
-
def apply_darknet_conv_block(
|
158
|
-
filters,
|
159
|
-
channel_axis,
|
160
|
-
kernel_size,
|
161
|
-
strides,
|
162
|
-
use_bias=False,
|
163
|
-
activation="silu",
|
164
|
-
name=None,
|
165
|
-
):
|
166
|
-
"""
|
167
|
-
The basic conv block used in Darknet. Applies Conv2D followed by a
|
168
|
-
BatchNorm.
|
169
|
-
|
170
|
-
Args:
|
171
|
-
filters: Integer, the dimensionality of the output space (i.e. the
|
172
|
-
number of output filters in the convolution).
|
173
|
-
kernel_size: An integer or tuple/list of 2 integers, specifying the
|
174
|
-
height and width of the 2D convolution window. Can be a single
|
175
|
-
integer to specify the same value both dimensions.
|
176
|
-
strides: An integer or tuple/list of 2 integers, specifying the strides
|
177
|
-
of the convolution along the height and width. Can be a single
|
178
|
-
integer to the same value both dimensions.
|
179
|
-
use_bias: Boolean, whether the layer uses a bias vector.
|
180
|
-
activation: the activation applied after the BatchNorm layer. One of
|
181
|
-
"silu", "relu" or "leaky_relu", defaults to "silu".
|
182
|
-
name: the prefix for the layer names used in the block.
|
183
|
-
"""
|
184
|
-
if name is None:
|
185
|
-
name = f"conv_block{keras.backend.get_uid('conv_block')}"
|
186
|
-
|
187
|
-
def apply(inputs):
|
188
|
-
x = layers.Conv2D(
|
189
|
-
filters,
|
190
|
-
kernel_size,
|
191
|
-
strides,
|
192
|
-
padding="same",
|
193
|
-
data_format=keras.config.image_data_format(),
|
194
|
-
use_bias=use_bias,
|
195
|
-
name=name + "_conv",
|
196
|
-
)(inputs)
|
197
|
-
|
198
|
-
x = layers.BatchNormalization(axis=channel_axis, name=name + "_bn")(x)
|
199
|
-
|
200
|
-
if activation == "silu":
|
201
|
-
x = layers.Lambda(lambda x: keras.activations.silu(x))(x)
|
202
|
-
elif activation == "relu":
|
203
|
-
x = layers.ReLU()(x)
|
204
|
-
elif activation == "leaky_relu":
|
205
|
-
x = layers.LeakyReLU(0.1)(x)
|
206
|
-
|
207
|
-
return x
|
208
|
-
|
209
|
-
return apply
|
210
|
-
|
211
|
-
|
212
|
-
def apply_darknet_conv_block_depthwise(
|
213
|
-
filters, channel_axis, kernel_size, strides, activation="silu", name=None
|
214
|
-
):
|
215
|
-
"""
|
216
|
-
The depthwise conv block used in CSPDarknet.
|
217
|
-
|
218
|
-
Args:
|
219
|
-
filters: Integer, the dimensionality of the output space (i.e. the
|
220
|
-
number of output filters in the final convolution).
|
221
|
-
kernel_size: An integer or tuple/list of 2 integers, specifying the
|
222
|
-
height and width of the 2D convolution window. Can be a single
|
223
|
-
integer to specify the same value both dimensions.
|
224
|
-
strides: An integer or tuple/list of 2 integers, specifying the strides
|
225
|
-
of the convolution along the height and width. Can be a single
|
226
|
-
integer to the same value both dimensions.
|
227
|
-
activation: the activation applied after the final layer. One of "silu",
|
228
|
-
"relu" or "leaky_relu", defaults to "silu".
|
229
|
-
name: the prefix for the layer names used in the block.
|
230
|
-
|
231
|
-
"""
|
232
|
-
if name is None:
|
233
|
-
name = f"conv_block{keras.backend.get_uid('conv_block')}"
|
234
|
-
|
235
|
-
def apply(inputs):
|
236
|
-
x = layers.DepthwiseConv2D(
|
237
|
-
kernel_size,
|
238
|
-
strides,
|
239
|
-
padding="same",
|
240
|
-
data_format=keras.config.image_data_format(),
|
241
|
-
use_bias=False,
|
242
|
-
)(inputs)
|
243
|
-
x = layers.BatchNormalization(axis=channel_axis)(x)
|
244
|
-
|
245
|
-
if activation == "silu":
|
246
|
-
x = layers.Lambda(lambda x: keras.activations.swish(x))(x)
|
247
|
-
elif activation == "relu":
|
248
|
-
x = layers.ReLU()(x)
|
249
|
-
elif activation == "leaky_relu":
|
250
|
-
x = layers.LeakyReLU(0.1)(x)
|
251
|
-
|
252
|
-
x = apply_darknet_conv_block(
|
253
|
-
filters,
|
254
|
-
channel_axis,
|
255
|
-
kernel_size=1,
|
256
|
-
strides=1,
|
257
|
-
activation=activation,
|
258
|
-
)(x)
|
259
|
-
|
260
|
-
return x
|
261
|
-
|
262
|
-
return apply
|
263
|
-
|
264
|
-
|
265
|
-
def apply_spatial_pyramid_pooling_bottleneck(
|
266
|
-
filters,
|
267
|
-
channel_axis,
|
268
|
-
hidden_filters=None,
|
269
|
-
kernel_sizes=(5, 9, 13),
|
270
|
-
activation="silu",
|
271
|
-
name=None,
|
272
|
-
):
|
273
|
-
"""
|
274
|
-
Spatial pyramid pooling layer used in YOLOv3-SPP
|
275
|
-
|
276
|
-
Args:
|
277
|
-
filters: Integer, the dimensionality of the output spaces (i.e. the
|
278
|
-
number of output filters in used the blocks).
|
279
|
-
hidden_filters: Integer, the dimensionality of the intermediate
|
280
|
-
bottleneck space (i.e. the number of output filters in the
|
281
|
-
bottleneck convolution). If None, it will be equal to filters.
|
282
|
-
Defaults to None.
|
283
|
-
kernel_sizes: A list or tuple representing all the pool sizes used for
|
284
|
-
the pooling layers, defaults to (5, 9, 13).
|
285
|
-
activation: Activation for the conv layers, defaults to "silu".
|
286
|
-
name: the prefix for the layer names used in the block.
|
287
|
-
|
288
|
-
Returns:
|
289
|
-
a function that takes an input Tensor representing an
|
290
|
-
SpatialPyramidPoolingBottleneck.
|
291
|
-
"""
|
292
|
-
if name is None:
|
293
|
-
name = f"spp{keras.backend.get_uid('spp')}"
|
294
|
-
|
295
|
-
if hidden_filters is None:
|
296
|
-
hidden_filters = filters
|
297
|
-
|
298
|
-
def apply(x):
|
299
|
-
x = apply_darknet_conv_block(
|
300
|
-
hidden_filters,
|
301
|
-
channel_axis,
|
302
|
-
kernel_size=1,
|
303
|
-
strides=1,
|
304
|
-
activation=activation,
|
305
|
-
name=f"{name}_conv1",
|
306
|
-
)(x)
|
307
|
-
x = [x]
|
308
|
-
|
309
|
-
for kernel_size in kernel_sizes:
|
310
|
-
x.append(
|
311
|
-
layers.MaxPooling2D(
|
312
|
-
kernel_size,
|
313
|
-
strides=1,
|
314
|
-
padding="same",
|
315
|
-
data_format=keras.config.image_data_format(),
|
316
|
-
name=f"{name}_maxpool_{kernel_size}",
|
317
|
-
)(x[0])
|
318
|
-
)
|
319
|
-
|
320
|
-
x = layers.Concatenate(axis=channel_axis, name=f"{name}_concat")(x)
|
321
|
-
x = apply_darknet_conv_block(
|
322
|
-
filters,
|
323
|
-
channel_axis,
|
324
|
-
kernel_size=1,
|
325
|
-
strides=1,
|
326
|
-
activation=activation,
|
327
|
-
name=f"{name}_conv2",
|
328
|
-
)(x)
|
329
|
-
|
330
|
-
return x
|
331
|
-
|
332
|
-
return apply
|
333
|
-
|
334
|
-
|
335
|
-
def apply_cross_stage_partial(
|
336
|
-
filters,
|
337
|
-
channel_axis,
|
338
|
-
num_bottlenecks,
|
339
|
-
residual=True,
|
340
|
-
block_type="basic_block",
|
341
|
-
activation="silu",
|
342
|
-
name=None,
|
343
|
-
):
|
344
|
-
"""A block used in Cross Stage Partial Darknet.
|
345
|
-
|
346
|
-
Args:
|
347
|
-
filters: Integer, the dimensionality of the output space (i.e. the
|
348
|
-
number of output filters in the final convolution).
|
349
|
-
num_bottlenecks: an integer representing the number of blocks added in
|
350
|
-
the layer bottleneck.
|
351
|
-
residual: a boolean representing whether the value tensor before the
|
352
|
-
bottleneck should be added to the output of the bottleneck as a
|
353
|
-
residual, defaults to True.
|
354
|
-
block_type: str. One of `"basic_block"` or `"depthwise_block"`.
|
355
|
-
Use `"depthwise_block"` for depthwise conv block
|
356
|
-
`"basic_block"` for basic conv block.
|
357
|
-
Defaults to "basic_block".
|
358
|
-
activation: the activation applied after the final layer. One of "silu",
|
359
|
-
"relu" or "leaky_relu", defaults to "silu".
|
360
|
-
"""
|
361
|
-
|
362
|
-
if name is None:
|
363
|
-
uid = keras.backend.get_uid("cross_stage_partial")
|
364
|
-
name = f"cross_stage_partial_{uid}"
|
365
|
-
|
366
|
-
def apply(inputs):
|
367
|
-
hidden_channels = filters // 2
|
368
|
-
ConvBlock = (
|
369
|
-
apply_darknet_conv_block_depthwise
|
370
|
-
if block_type == "basic_block"
|
371
|
-
else apply_darknet_conv_block
|
372
|
-
)
|
373
|
-
|
374
|
-
x1 = apply_darknet_conv_block(
|
375
|
-
hidden_channels,
|
376
|
-
channel_axis,
|
377
|
-
kernel_size=1,
|
378
|
-
strides=1,
|
379
|
-
activation=activation,
|
380
|
-
name=f"{name}_conv1",
|
381
|
-
)(inputs)
|
382
|
-
|
383
|
-
x2 = apply_darknet_conv_block(
|
384
|
-
hidden_channels,
|
385
|
-
channel_axis,
|
386
|
-
kernel_size=1,
|
387
|
-
strides=1,
|
388
|
-
activation=activation,
|
389
|
-
name=f"{name}_conv2",
|
390
|
-
)(inputs)
|
391
|
-
|
392
|
-
for i in range(num_bottlenecks):
|
393
|
-
residual_x = x1
|
394
|
-
x1 = apply_darknet_conv_block(
|
395
|
-
hidden_channels,
|
396
|
-
channel_axis,
|
397
|
-
kernel_size=1,
|
398
|
-
strides=1,
|
399
|
-
activation=activation,
|
400
|
-
name=f"{name}_bottleneck_{i}_conv1",
|
401
|
-
)(x1)
|
402
|
-
x1 = ConvBlock(
|
403
|
-
hidden_channels,
|
404
|
-
channel_axis,
|
405
|
-
kernel_size=3,
|
406
|
-
strides=1,
|
407
|
-
activation=activation,
|
408
|
-
name=f"{name}_bottleneck_{i}_conv2",
|
409
|
-
)(x1)
|
410
|
-
if residual:
|
411
|
-
x1 = layers.Add(name=f"{name}_bottleneck_{i}_add")(
|
412
|
-
[residual_x, x1]
|
413
|
-
)
|
414
|
-
|
415
|
-
x = layers.Concatenate(name=f"{name}_concat")([x1, x2])
|
416
|
-
x = apply_darknet_conv_block(
|
417
|
-
filters,
|
418
|
-
channel_axis,
|
419
|
-
kernel_size=1,
|
420
|
-
strides=1,
|
421
|
-
activation=activation,
|
422
|
-
name=f"{name}_conv3",
|
423
|
-
)(x)
|
424
|
-
|
425
|
-
return x
|
426
|
-
|
427
|
-
return apply
|
@@ -1,10 +0,0 @@
|
|
1
|
-
from keras_hub.src.api_export import keras_hub_export
|
2
|
-
from keras_hub.src.models.csp_darknet.csp_darknet_backbone import (
|
3
|
-
CSPDarkNetBackbone,
|
4
|
-
)
|
5
|
-
from keras_hub.src.models.image_classifier import ImageClassifier
|
6
|
-
|
7
|
-
|
8
|
-
@keras_hub_export("keras_hub.models.CSPDarkNetImageClassifier")
|
9
|
-
class CSPDarkNetImageClassifier(ImageClassifier):
|
10
|
-
backbone_cls = CSPDarkNetBackbone
|