keras-hub-nightly 0.15.0.dev20240911134614__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.
Files changed (52) hide show
  1. keras_hub/__init__.py +0 -6
  2. keras_hub/api/__init__.py +1 -0
  3. keras_hub/api/models/__init__.py +22 -17
  4. keras_hub/{src/models/llama3/llama3_preprocessor.py → api/utils/__init__.py} +7 -8
  5. keras_hub/src/api_export.py +15 -9
  6. keras_hub/src/models/albert/albert_text_classifier.py +6 -1
  7. keras_hub/src/models/bert/bert_text_classifier.py +6 -1
  8. keras_hub/src/models/deberta_v3/deberta_v3_text_classifier.py +6 -1
  9. keras_hub/src/models/densenet/densenet_backbone.py +1 -1
  10. keras_hub/src/models/distil_bert/distil_bert_text_classifier.py +6 -1
  11. keras_hub/src/models/f_net/f_net_text_classifier.py +6 -1
  12. keras_hub/src/models/gemma/gemma_decoder_block.py +1 -1
  13. keras_hub/src/models/gpt2/gpt2_preprocessor.py +7 -78
  14. keras_hub/src/models/pali_gemma/pali_gemma_tokenizer.py +1 -1
  15. keras_hub/src/models/preprocessor.py +1 -5
  16. keras_hub/src/models/resnet/resnet_backbone.py +3 -16
  17. keras_hub/src/models/resnet/resnet_image_classifier.py +26 -3
  18. keras_hub/src/models/resnet/resnet_presets.py +12 -12
  19. keras_hub/src/models/retinanet/__init__.py +13 -0
  20. keras_hub/src/models/retinanet/anchor_generator.py +175 -0
  21. keras_hub/src/models/retinanet/box_matcher.py +259 -0
  22. keras_hub/src/models/retinanet/non_max_supression.py +578 -0
  23. keras_hub/src/models/roberta/roberta_text_classifier.py +6 -1
  24. keras_hub/src/models/task.py +6 -6
  25. keras_hub/src/models/text_classifier.py +12 -1
  26. keras_hub/src/models/xlm_roberta/xlm_roberta_text_classifier.py +6 -1
  27. keras_hub/src/tests/test_case.py +21 -0
  28. keras_hub/src/tokenizers/byte_pair_tokenizer.py +1 -0
  29. keras_hub/src/tokenizers/sentence_piece_tokenizer.py +1 -0
  30. keras_hub/src/tokenizers/word_piece_tokenizer.py +1 -0
  31. keras_hub/src/utils/imagenet/__init__.py +13 -0
  32. keras_hub/src/utils/imagenet/imagenet_utils.py +1067 -0
  33. keras_hub/src/utils/preset_utils.py +24 -33
  34. keras_hub/src/utils/tensor_utils.py +14 -14
  35. keras_hub/src/utils/timm/convert_resnet.py +0 -1
  36. keras_hub/src/utils/timm/preset_loader.py +6 -7
  37. keras_hub/src/version_utils.py +1 -1
  38. keras_hub_nightly-0.16.0.dev2024092017.dist-info/METADATA +202 -0
  39. {keras_hub_nightly-0.15.0.dev20240911134614.dist-info → keras_hub_nightly-0.16.0.dev2024092017.dist-info}/RECORD +41 -45
  40. {keras_hub_nightly-0.15.0.dev20240911134614.dist-info → keras_hub_nightly-0.16.0.dev2024092017.dist-info}/WHEEL +1 -1
  41. keras_hub/src/models/bart/bart_preprocessor.py +0 -264
  42. keras_hub/src/models/bloom/bloom_preprocessor.py +0 -178
  43. keras_hub/src/models/electra/electra_preprocessor.py +0 -155
  44. keras_hub/src/models/falcon/falcon_preprocessor.py +0 -180
  45. keras_hub/src/models/gemma/gemma_preprocessor.py +0 -184
  46. keras_hub/src/models/gpt_neo_x/gpt_neo_x_preprocessor.py +0 -138
  47. keras_hub/src/models/llama/llama_preprocessor.py +0 -182
  48. keras_hub/src/models/mistral/mistral_preprocessor.py +0 -183
  49. keras_hub/src/models/opt/opt_preprocessor.py +0 -181
  50. keras_hub/src/models/phi3/phi3_preprocessor.py +0 -183
  51. keras_hub_nightly-0.15.0.dev20240911134614.dist-info/METADATA +0 -33
  52. {keras_hub_nightly-0.15.0.dev20240911134614.dist-info → keras_hub_nightly-0.16.0.dev2024092017.dist-info}/top_level.txt +0 -0
@@ -569,7 +569,16 @@ def load_serialized_object(config, **kwargs):
569
569
 
570
570
  def check_config_class(config):
571
571
  """Validate a preset is being loaded on the correct class."""
572
- return keras.saving.get_registered_object(config["registered_name"])
572
+ registered_name = config["registered_name"]
573
+ cls = keras.saving.get_registered_object(registered_name)
574
+ if cls is None:
575
+ raise ValueError(
576
+ f"Attempting to load class {registered_name} with "
577
+ "`from_preset()`, but there is no class registered with Keras "
578
+ f"for {registered_name}. Make sure to register any custom "
579
+ "classes with `register_keras_serializable()`."
580
+ )
581
+ return cls
573
582
 
574
583
 
575
584
  def jax_memory_cleanup(layer):
@@ -668,7 +677,7 @@ class PresetLoader:
668
677
  """Load an image converter layer from the preset."""
669
678
  raise NotImplementedError
670
679
 
671
- def load_task(self, cls, load_weights, load_task_extras, **kwargs):
680
+ def load_task(self, cls, load_weights, load_task_weights, **kwargs):
672
681
  """Load a task model from the preset.
673
682
 
674
683
  By default, we create a task from a backbone and preprocessor with
@@ -684,11 +693,10 @@ class PresetLoader:
684
693
  if "preprocessor" not in kwargs and cls.preprocessor_cls:
685
694
  kwargs["preprocessor"] = self.load_preprocessor(
686
695
  cls.preprocessor_cls,
687
- load_task_extras=load_task_extras,
688
696
  )
689
697
  return cls(**kwargs)
690
698
 
691
- def load_preprocessor(self, cls, load_task_extras, **kwargs):
699
+ def load_preprocessor(self, cls, **kwargs):
692
700
  """Load a prepocessor layer from the preset.
693
701
 
694
702
  By default, we create a preprocessor from a tokenizer with default
@@ -733,33 +741,25 @@ class KerasPresetLoader(PresetLoader):
733
741
  converter_config = load_json(self.preset, IMAGE_CONVERTER_CONFIG_FILE)
734
742
  return load_serialized_object(converter_config, **kwargs)
735
743
 
736
- def load_task(self, cls, load_weights, load_task_extras, **kwargs):
744
+ def load_task(self, cls, load_weights, load_task_weights, **kwargs):
737
745
  # If there is no `task.json` or it's for the wrong class delegate to the
738
746
  # super class loader.
739
- if not load_task_extras:
740
- return super().load_task(
741
- cls, load_weights, load_task_extras, **kwargs
742
- )
743
747
  if not check_file_exists(self.preset, TASK_CONFIG_FILE):
744
- raise ValueError(
745
- "Saved preset has no `task.json`, cannot load the task config "
746
- "from a file. Call `from_preset()` with "
747
- "`load_task_extras=False` to load the task from a backbone "
748
- "with library defaults."
748
+ return super().load_task(
749
+ cls, load_weights, load_task_weights, **kwargs
749
750
  )
750
751
  task_config = load_json(self.preset, TASK_CONFIG_FILE)
751
752
  if not issubclass(check_config_class(task_config), cls):
752
- raise ValueError(
753
- f"Saved `task.json`does not match calling cls {cls}. Call "
754
- "`from_preset()` with `load_task_extras=False` to load the "
755
- "task from a backbone with library defaults."
753
+ return super().load_task(
754
+ cls, load_weights, load_task_weights, **kwargs
756
755
  )
757
756
  # We found a `task.json` with a complete config for our class.
758
757
  task = load_serialized_object(task_config, **kwargs)
759
758
  if task.preprocessor and task.preprocessor.tokenizer:
760
759
  task.preprocessor.tokenizer.load_preset_assets(self.preset)
761
760
  if load_weights:
762
- if check_file_exists(self.preset, TASK_WEIGHTS_FILE):
761
+ has_task_weights = check_file_exists(self.preset, TASK_WEIGHTS_FILE)
762
+ if has_task_weights and load_task_weights:
763
763
  jax_memory_cleanup(task)
764
764
  task_weights = get_file(self.preset, TASK_WEIGHTS_FILE)
765
765
  task.load_task_weights(task_weights)
@@ -769,23 +769,14 @@ class KerasPresetLoader(PresetLoader):
769
769
  task.backbone.load_weights(backbone_weights)
770
770
  return task
771
771
 
772
- def load_preprocessor(self, cls, load_task_extras, **kwargs):
773
- if not load_task_extras:
774
- return super().load_preprocessor(cls, load_task_extras, **kwargs)
772
+ def load_preprocessor(self, cls, **kwargs):
773
+ # If there is no `preprocessing.json` or it's for the wrong class,
774
+ # delegate to the super class loader.
775
775
  if not check_file_exists(self.preset, PREPROCESSOR_CONFIG_FILE):
776
- raise ValueError(
777
- "Saved preset has no `preprocessor.json`, cannot load the task "
778
- "preprocessing config from a file. Call `from_preset()` with "
779
- "`load_task_extras=False` to load the preprocessor with "
780
- "library defaults."
781
- )
776
+ return super().load_preprocessor(cls, **kwargs)
782
777
  preprocessor_json = load_json(self.preset, PREPROCESSOR_CONFIG_FILE)
783
778
  if not issubclass(check_config_class(preprocessor_json), cls):
784
- raise ValueError(
785
- f"Saved `preprocessor.json`does not match calling cls {cls}. "
786
- "Call `from_preset()` with `load_task_extras=False` to "
787
- "load the the preprocessor with library defaults."
788
- )
779
+ return super().load_preprocessor(cls, **kwargs)
789
780
  # We found a `preprocessing.json` with a complete config for our class.
790
781
  preprocessor = load_serialized_object(preprocessor_json, **kwargs)
791
782
  preprocessor.tokenizer.load_preset_assets(self.preset)
@@ -30,20 +30,19 @@ except ImportError:
30
30
 
31
31
 
32
32
  NO_CONVERT_COUNTER = threading.local()
33
- NO_CONVERT_COUNTER.count = 0
34
33
 
35
34
 
36
35
  @contextlib.contextmanager
37
36
  def no_convert_scope():
38
37
  try:
39
- NO_CONVERT_COUNTER.count += 1
38
+ NO_CONVERT_COUNTER.count = getattr(NO_CONVERT_COUNTER, "count", 0) + 1
40
39
  yield
41
40
  finally:
42
- NO_CONVERT_COUNTER.count -= 1
41
+ NO_CONVERT_COUNTER.count = getattr(NO_CONVERT_COUNTER, "count", 0) - 1
43
42
 
44
43
 
45
44
  def in_no_convert_scope():
46
- return NO_CONVERT_COUNTER.count > 0
45
+ return getattr(NO_CONVERT_COUNTER, "count", 0) > 0
47
46
 
48
47
 
49
48
  def preprocessing_function(fn):
@@ -53,20 +52,21 @@ def preprocessing_function(fn):
53
52
 
54
53
  params = inspect.signature(fn).parameters
55
54
  accepts_labels = all(k in params for k in ("x", "y", "sample_weight"))
56
- with tf.device("cpu"):
57
- if not accepts_labels:
55
+ if not accepts_labels:
58
56
 
59
- @functools.wraps(fn)
60
- def wrapper(self, x, **kwargs):
57
+ @functools.wraps(fn)
58
+ def wrapper(self, x, **kwargs):
59
+ with tf.device("cpu"):
61
60
  x = convert_preprocessing_inputs(x)
62
61
  with no_convert_scope():
63
62
  x = fn(self, x, **kwargs)
64
63
  return convert_preprocessing_outputs(x)
65
64
 
66
- else:
65
+ else:
67
66
 
68
- @functools.wraps(fn)
69
- def wrapper(self, x, y=None, sample_weight=None, **kwargs):
67
+ @functools.wraps(fn)
68
+ def wrapper(self, x, y=None, sample_weight=None, **kwargs):
69
+ with tf.device("cpu"):
70
70
  x, y, sample_weight = convert_preprocessing_inputs(
71
71
  (x, y, sample_weight)
72
72
  )
@@ -74,7 +74,7 @@ def preprocessing_function(fn):
74
74
  x = fn(self, x, y=y, sample_weight=sample_weight, **kwargs)
75
75
  return convert_preprocessing_outputs(x)
76
76
 
77
- return wrapper
77
+ return wrapper
78
78
 
79
79
 
80
80
  def convert_preprocessing_inputs(x):
@@ -118,7 +118,7 @@ def convert_preprocessing_inputs(x):
118
118
  return {k: convert_preprocessing_inputs(x[k]) for k, v in x.items()}
119
119
  if isinstance(x, tuple):
120
120
  return tuple(convert_preprocessing_inputs(v) for v in x)
121
- if isinstance(x, str):
121
+ if isinstance(x, (str, bytes)):
122
122
  return tf.constant(x)
123
123
  if isinstance(x, list):
124
124
  try:
@@ -131,7 +131,7 @@ def convert_preprocessing_inputs(x):
131
131
  # If ragged conversion failed return to the numpy error.
132
132
  raise e
133
133
  # If we have a string input, use tf.tensor.
134
- if numpy_x.dtype.type is np.str_:
134
+ if numpy_x.dtype.type is np.str_ or numpy_x.dtype.type is np.bytes_:
135
135
  return tf.convert_to_tensor(x)
136
136
  # Numpy will default to int64, int32 works with more ops.
137
137
  if numpy_x.dtype == np.int64:
@@ -172,4 +172,3 @@ def convert_head(task, loader, timm_config):
172
172
  task.output_dense.bias,
173
173
  hf_weight_key=prefix + "bias",
174
174
  )
175
- return task
@@ -45,16 +45,15 @@ class TimmPresetLoader(PresetLoader):
45
45
  self.converter.convert_weights(backbone, loader, self.config)
46
46
  return backbone
47
47
 
48
- def load_task(self, cls, load_weights, load_task_extras, **kwargs):
49
- if not load_task_extras or not issubclass(cls, ImageClassifier):
48
+ def load_task(self, cls, load_weights, load_task_weights, **kwargs):
49
+ if not load_task_weights or not issubclass(cls, ImageClassifier):
50
50
  return super().load_task(
51
- cls, load_weights, load_task_extras, **kwargs
51
+ cls, load_weights, load_task_weights, **kwargs
52
52
  )
53
53
  # Support loading the classification head for classifier models.
54
- if "num_classes" not in kwargs:
55
- kwargs["num_classes"] = self.config["num_classes"]
56
- task = super().load_task(cls, load_weights, load_task_extras, **kwargs)
57
- if load_weights:
54
+ kwargs["num_classes"] = self.config["num_classes"]
55
+ task = super().load_task(cls, load_weights, load_task_weights, **kwargs)
56
+ if load_task_weights:
58
57
  with SafetensorLoader(self.preset, prefix="") as loader:
59
58
  self.converter.convert_head(task, loader, self.config)
60
59
  return task
@@ -15,7 +15,7 @@
15
15
  from keras_hub.src.api_export import keras_hub_export
16
16
 
17
17
  # Unique source of truth for the version number.
18
- __version__ = "0.15.0.dev20240911134614"
18
+ __version__ = "0.16.0.dev2024092017"
19
19
 
20
20
 
21
21
  @keras_hub_export("keras_hub.version")
@@ -0,0 +1,202 @@
1
+ Metadata-Version: 2.1
2
+ Name: keras_hub-nightly
3
+ Version: 0.16.0.dev2024092017
4
+ Summary: Industry-strength Natural Language Processing extensions for Keras.
5
+ Home-page: https://github.com/keras-team/keras-hub
6
+ Author: Keras team
7
+ Author-email: keras-hub@google.com
8
+ License: Apache License 2.0
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Operating System :: Unix
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Operating System :: MacOS
18
+ Classifier: Intended Audience :: Science/Research
19
+ Classifier: Topic :: Scientific/Engineering
20
+ Classifier: Topic :: Software Development
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ Requires-Dist: absl-py
24
+ Requires-Dist: numpy
25
+ Requires-Dist: packaging
26
+ Requires-Dist: regex
27
+ Requires-Dist: rich
28
+ Requires-Dist: kagglehub
29
+ Requires-Dist: tensorflow-text ; platform_system != "Darwin"
30
+ Provides-Extra: extras
31
+ Requires-Dist: rouge-score ; extra == 'extras'
32
+ Requires-Dist: sentencepiece ; extra == 'extras'
33
+
34
+ # KerasNLP: Multi-framework NLP Models
35
+ [![](https://github.com/keras-team/keras-hub/workflows/Tests/badge.svg?branch=master)](https://github.com/keras-team/keras-hub/actions?query=workflow%3ATests+branch%3Amaster)
36
+ ![Python](https://img.shields.io/badge/python-v3.9.0+-success.svg)
37
+ [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/keras-team/keras-hub/issues)
38
+
39
+ > [!IMPORTANT]
40
+ > 📢 KerasNLP is becoming KerasHub! 📢 Read
41
+ > [the announcement](https://github.com/keras-team/keras-hub/issues/1831).
42
+ >
43
+ > We have renamed the repo to KerasHub in preparation for the release, but have not yet
44
+ > released the new package. Follow the announcement for news.
45
+
46
+ KerasNLP is a natural language processing library that works natively
47
+ with TensorFlow, JAX, or PyTorch. KerasNLP provides a repository of pre-trained
48
+ models and a collection of lower-level building blocks for language modeling.
49
+ Built on Keras 3, models can be trained and serialized in any framework
50
+ and re-used in another without costly migrations.
51
+
52
+ This library is an extension of the core Keras API; all high-level modules are
53
+ Layers and Models that receive that same level of polish as core Keras.
54
+ If you are familiar with Keras, congratulations! You already understand most of
55
+ KerasNLP.
56
+
57
+ All models support JAX, TensorFlow, and PyTorch from a single model
58
+ definition and can be fine-tuned on GPUs and TPUs out of the box. Models can
59
+ be trained on individual accelerators with built-in PEFT techniques, or
60
+ fine-tuned at scale with model and data parallel training. See our
61
+ [Getting Started guide](https://keras.io/guides/keras_nlp/getting_started)
62
+ to start learning our API. Browse our models on
63
+ [Kaggle](https://www.kaggle.com/organizations/keras/models).
64
+ We welcome contributions.
65
+
66
+ ## Quick Links
67
+
68
+ ### For everyone
69
+
70
+ - [Home Page](https://keras.io/keras_nlp)
71
+ - [Developer Guides](https://keras.io/guides/keras_nlp)
72
+ - [API Reference](https://keras.io/api/keras_nlp)
73
+ - [Pre-trained Models](https://www.kaggle.com/organizations/keras/models)
74
+
75
+ ### For contributors
76
+
77
+ - [Contributing Guide](CONTRIBUTING.md)
78
+ - [Roadmap](ROADMAP.md)
79
+ - [Style Guide](STYLE_GUIDE.md)
80
+ - [API Design Guide](API_DESIGN_GUIDE.md)
81
+ - [Call for Contributions](https://github.com/keras-team/keras-hub/issues?q=is%3Aissue+is%3Aopen+label%3A%22contributions+welcome%22)
82
+
83
+ ## Quickstart
84
+
85
+ Fine-tune BERT on IMDb movie reviews:
86
+
87
+ ```python
88
+ import os
89
+ os.environ["KERAS_BACKEND"] = "jax" # Or "tensorflow" or "torch"!
90
+
91
+ import keras_nlp
92
+ import tensorflow_datasets as tfds
93
+
94
+ imdb_train, imdb_test = tfds.load(
95
+ "imdb_reviews",
96
+ split=["train", "test"],
97
+ as_supervised=True,
98
+ batch_size=16,
99
+ )
100
+ # Load a BERT model.
101
+ classifier = keras_nlp.models.Classifier.from_preset(
102
+ "bert_base_en",
103
+ num_classes=2,
104
+ activation="softmax",
105
+ )
106
+ # Fine-tune on IMDb movie reviews.
107
+ classifier.fit(imdb_train, validation_data=imdb_test)
108
+ # Predict two new examples.
109
+ classifier.predict(["What an amazing movie!", "A total waste of my time."])
110
+ ```
111
+
112
+ Try it out [in a colab](https://colab.research.google.com/gist/mattdangerw/e457e42d5ea827110c8d5cb4eb9d9a07/kerasnlp-quickstart.ipynb).
113
+ For more in depth guides and examples, visit
114
+ [keras.io/keras_nlp](https://keras.io/keras_nlp/).
115
+
116
+ ## Installation
117
+
118
+ To install the latest KerasNLP release with Keras 3, simply run:
119
+
120
+ ```
121
+ pip install --upgrade keras-nlp
122
+ ```
123
+
124
+ To install the latest nightly changes for both KerasNLP and Keras, you can use
125
+ our nightly package.
126
+
127
+ ```
128
+ pip install --upgrade keras-nlp-nightly
129
+ ```
130
+
131
+ Note that currently, installing KerasNLP will always pull in TensorFlow for use
132
+ of the `tf.data` API for preprocessing. Even when pre-processing with `tf.data`,
133
+ training can still happen on any backend.
134
+
135
+ Read [Getting started with Keras](https://keras.io/getting_started/) for more
136
+ information on installing Keras 3 and compatibility with different frameworks.
137
+
138
+ > [!IMPORTANT]
139
+ > We recommend using KerasNLP with TensorFlow 2.16 or later, as TF 2.16 packages
140
+ > Keras 3 by default.
141
+
142
+ ## Configuring your backend
143
+
144
+ If you have Keras 3 installed in your environment (see installation above),
145
+ you can use KerasNLP with any of JAX, TensorFlow and PyTorch. To do so, set the
146
+ `KERAS_BACKEND` environment variable. For example:
147
+
148
+ ```shell
149
+ export KERAS_BACKEND=jax
150
+ ```
151
+
152
+ Or in Colab, with:
153
+
154
+ ```python
155
+ import os
156
+ os.environ["KERAS_BACKEND"] = "jax"
157
+
158
+ import keras_nlp
159
+ ```
160
+
161
+ > [!IMPORTANT]
162
+ > Make sure to set the `KERAS_BACKEND` before import any Keras libraries, it
163
+ > will be used to set up Keras when it is first imported.
164
+
165
+ ## Compatibility
166
+
167
+ We follow [Semantic Versioning](https://semver.org/), and plan to
168
+ provide backwards compatibility guarantees both for code and saved models built
169
+ with our components. While we continue with pre-release `0.y.z` development, we
170
+ may break compatibility at any time and APIs should not be consider stable.
171
+
172
+ ## Disclaimer
173
+
174
+ KerasNLP provides access to pre-trained models via the `keras_nlp.models` API.
175
+ These pre-trained models are provided on an "as is" basis, without warranties
176
+ or conditions of any kind. The following underlying models are provided by third
177
+ parties, and subject to separate licenses:
178
+ BART, BLOOM, DeBERTa, DistilBERT, GPT-2, Llama, Mistral, OPT, RoBERTa, Whisper,
179
+ and XLM-RoBERTa.
180
+
181
+ ## Citing KerasNLP
182
+
183
+ If KerasNLP helps your research, we appreciate your citations.
184
+ Here is the BibTeX entry:
185
+
186
+ ```bibtex
187
+ @misc{kerasnlp2022,
188
+ title={KerasNLP},
189
+ author={Watson, Matthew, and Qian, Chen, and Bischof, Jonathan and Chollet,
190
+ Fran\c{c}ois and others},
191
+ year={2022},
192
+ howpublished={\url{https://github.com/keras-team/keras-hub}},
193
+ }
194
+ ```
195
+
196
+ ## Acknowledgements
197
+
198
+ Thank you to all of our wonderful contributors!
199
+
200
+ <a href="https://github.com/keras-team/keras-hub/graphs/contributors">
201
+ <img src="https://contrib.rocks/image?repo=keras-team/keras-hub" />
202
+ </a>