Skip to content

Commit ad19601

Browse files
sampathwebmattdangerwdivyashreepathihallitirthasheshpatel
authored
r0.7.2 Cherry Pick (#2215)
* Fix Keras 3 version check (#2191) * Fix Keras 3 version check * Fix Keras 3 version check * Fix Keras 3 version check * Raise error if Keras is not compatible with TF * Fix bug when upranking passthrough inputs to RandAugment (#2194) - RandAugment sometimes will choose a "no augmentation" option and passthrough inputs unaltered. - Preprocessing normalization routines were not making copies of inputs and sometimes mutating layer input directly (mutating the input dict to cast dtypes and uprank tensors). - RandAugment under the passthrough option would return these inputs directly. The net effect was sometimes attempting to uprank during a passthrough call, breaking tf.map_fn * fix stable diffusion rank error (#2208) * Simplify running KerasCV with Keras 3 (#2179) * remove keras_core dependency * update init * update readme * fix model None error (#2176) (#2177) * Update pycoco_callback.py * Update waymo_evaluation_callback.py * fix model None error (#2176) (#2178) * Update pycoco_callback.py * Update waymo_evaluation_callback.py * update readme and conftest * update readme * update citation list * fix mix transformer tests * fix lint error * fix all failing tests * Fix dtype support for SegmentAnythingModel (#2207) * Fix dtype support for SAM * Update keras_cv/models/segmentation/segment_anything/sam_test.py * Fix Keras 2 failures * Fix F401 lint error; remove unused import * Version bump to r0.7.2.dev0 --------- Co-authored-by: Matt Watson <[email protected]> Co-authored-by: Divyashree Sreepathihalli <[email protected]> Co-authored-by: Tirth Patel <[email protected]>
1 parent 52f0b26 commit ad19601

22 files changed

+194
-186
lines changed

Diff for: README.md

+34-27
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
[![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/keras-team/keras-cv/issues)
88

99
KerasCV is a library of modular computer vision components that work natively
10-
with TensorFlow, JAX, or PyTorch. Built on [Keras Core](https://keras.io/keras_core/announcement/),
11-
these models, layers, metrics, callbacks, etc., can be trained and serialized
12-
in any framework and re-used in another without costly migrations. See
13-
"Configuring your backend" below for more details on multi-framework KerasCV.
10+
with TensorFlow, JAX, or PyTorch. Built on Keras 3, these models, layers,
11+
metrics, callbacks, etc., can be trained and serialized in any framework and
12+
re-used in another without costly migrations. See "Configuring your backend"
13+
below for more details on multi-framework KerasCV.
1414

1515
<img style="width: 440px; max-width: 90%;" src="https://storage.googleapis.com/keras-cv/guides/keras-cv-augmentations.gif">
1616

@@ -34,29 +34,44 @@ these common tasks.
3434
- [API Design Guidelines](.github/API_DESIGN.md)
3535

3636
## Installation
37+
KerasCV supports both Keras 2 and Keras 3. We recommend Keras 3 for all new
38+
users, as it enables using KerasCV models and layers with JAX, TensorFlow and
39+
PyTorch.
3740

38-
To install the latest official release:
41+
### Keras 2 Installation
42+
43+
To install the latest KerasCV release with Keras 2, simply run:
3944

4045
```
41-
pip install keras-cv tensorflow --upgrade
46+
pip install --upgrade keras-cv tensorflow
4247
```
4348

44-
To install the latest unreleased changes to the library, we recommend using
45-
pip to install directly from the master branch on github:
49+
### Keras 3 Installation
50+
51+
There are currently two ways to install Keras 3 with KerasCV. To install the
52+
latest changes for KerasCV and Keras, you can use our nightly package.
53+
4654

4755
```
48-
pip install git+https://github.com/keras-team/keras-cv.git tensorflow --upgrade
56+
pip install --upgrade keras-cv-nightly tf-nightly
4957
```
5058

51-
## Configuring your backend
59+
To install the stable versions of KerasCV and Keras 3, you should install Keras
60+
3 **after** installing KerasCV. This is a temporary step while TensorFlow is
61+
pinned to Keras 2, and will no longer be necessary after TensorFlow 2.16.
5262

53-
**Keras 3** is an upcoming release of the Keras library which supports
54-
TensorFlow, Jax or Torch as backends. This is supported today in KerasNLP,
55-
but will not be enabled by default until the official release of Keras 3. If you
56-
`pip install keras-cv` and run a script or notebook without changes, you will
57-
be using TensorFlow and **Keras 2**.
63+
```
64+
pip install --upgrade keras-cv tensorflow
65+
pip install keras>=3
66+
```
67+
> [!IMPORTANT]
68+
> Keras 3 will not function with TensorFlow 2.14 or earlier.
69+
70+
## Configuring your backend
5871

59-
If you would like to enable a preview of the Keras 3 behavior, you can do
72+
If you have Keras 3 installed in your environment (see installation above),
73+
you can use KerasCV with any of JAX, TensorFlow and PyTorch. To do so, set the
74+
`KERAS_BACKEND` environment variable. For example:
6075
so by setting the `KERAS_BACKEND` environment variable. For example:
6176

6277
```shell
@@ -75,21 +90,13 @@ import keras_cv
7590
> [!IMPORTANT]
7691
> Make sure to set the `KERAS_BACKEND` before import any Keras libraries, it
7792
> will be used to set up Keras when it is first imported.
78-
Until the Keras 3 release, KerasCV will use a preview of Keras 3 on PyPI named
79-
[keras-core](https://pypi.org/project/keras-core/).
80-
81-
> [!IMPORTANT]
82-
> If you set `KERAS_BACKEND` variable, you should `import keras_core as keras`
83-
> instead of `import keras`. This is a temporary step until Keras 3 is out!
84-
To restore the default **Keras 2** behavior, `unset KERAS_BACKEND` before
85-
importing Keras and KerasCV.
8693
8794
Once that configuration step is done, you can just import KerasCV and start
8895
using it on top of your backend of choice:
8996

9097
```python
9198
import keras_cv
92-
from keras_cv.backend import keras
99+
import keras
93100

94101
filepath = keras.utils.get_file(origin="https://i.imgur.com/gCNcJJI.jpg")
95102
image = np.array(keras.utils.load_img(filepath))
@@ -108,7 +115,7 @@ predictions = model.predict(image_resized)
108115
import tensorflow as tf
109116
import keras_cv
110117
import tensorflow_datasets as tfds
111-
from keras_cv.backend import keras
118+
import keras
112119

113120
# Create a preprocessing pipeline with augmentations
114121
BATCH_SIZE = 16
@@ -260,7 +267,7 @@ Here is the BibTeX entry:
260267
```bibtex
261268
@misc{wood2022kerascv,
262269
title={KerasCV},
263-
author={Wood, Luke and Tan, Zhenyu and Stenbit, Ian and Bischof, Jonathan and Zhu, Scott and Chollet, Fran\c{c}ois and others},
270+
author={Wood, Luke and Tan, Zhenyu and Stenbit, Ian and Bischof, Jonathan and Zhu, Scott and Chollet, Fran\c{c}ois and Sreepathihalli, Divyashree and Sampath, Ramesh and others},
264271
year={2022},
265272
howpublished={\url{https://github.com/keras-team/keras-cv}},
266273
}

Diff for: keras_cv/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@
4242
from keras_cv.core import NormalFactorSampler
4343
from keras_cv.core import UniformFactorSampler
4444

45-
__version__ = "0.7.1"
45+
__version__ = "0.7.2.dev0"

Diff for: keras_cv/backend/__init__.py

+17-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,20 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
"""
15+
Keras backend module.
16+
17+
This module adds a temporary Keras API surface that is fully under KerasCV
18+
control. The goal is to allow us to write Keras 3-like code everywhere, while
19+
still supporting Keras 2. We do this by using the `keras_core` package with
20+
Keras 2 to backport Keras 3 numerics APIs (`keras.ops` and `keras.random`) into
21+
Keras 2. The sub-modules exposed are as follows:
22+
23+
- `config`: check which version of Keras is being run.
24+
- `keras`: The full `keras` API with compat shims for older Keras versions.
25+
- `ops`: `keras.ops` for Keras 3 or `keras_core.ops` for Keras 2.
26+
- `random`: `keras.random` for Keras 3 or `keras_core.ops` for Keras 2.
27+
"""
1428
from keras_cv.backend import config # noqa: E402
1529
from keras_cv.backend import keras # noqa: E402
1630
from keras_cv.backend import ops # noqa: E402
@@ -19,12 +33,12 @@
1933

2034

2135
def assert_tf_keras(src):
22-
if config.multi_backend():
36+
if config.keras_3():
2337
raise NotImplementedError(
24-
f"KerasCV component {src} does not yet support Keras Core, and can "
38+
f"KerasCV component {src} does not yet support Keras 3, and can "
2539
"only be used in `tf.keras`."
2640
)
2741

2842

2943
def supports_ragged():
30-
return not config.multi_backend()
44+
return not config.keras_3()

Diff for: keras_cv/backend/config.py

+22-62
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,33 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
import json
15-
import os
1614

17-
_MULTI_BACKEND = False
1815

19-
# Set Keras base dir path given KERAS_HOME env variable, if applicable.
20-
# Otherwise either ~/.keras or /tmp.
21-
if "KERAS_HOME" in os.environ:
22-
_keras_dir = os.environ.get("KERAS_HOME")
23-
else:
24-
_keras_base_dir = os.path.expanduser("~")
25-
if not os.access(_keras_base_dir, os.W_OK):
26-
_keras_base_dir = "/tmp"
27-
_keras_dir = os.path.join(_keras_base_dir, ".keras")
16+
from tensorflow import keras
17+
18+
# We follow the version of keras that tensorflow is configured to use.
19+
_USE_KERAS_3 = False
20+
21+
# Note that only recent versions of keras have a `version()` function.
22+
if hasattr(keras, "version") and keras.version().startswith("3."):
23+
_USE_KERAS_3 = True
2824

2925

3026
def detect_if_tensorflow_uses_keras_3():
3127
# We follow the version of keras that tensorflow is configured to use.
32-
from tensorflow import keras
33-
34-
# Note that only recent versions of keras have a `version()` function.
35-
if hasattr(keras, "version") and keras.version().startswith("3."):
36-
return True
28+
try:
29+
from tensorflow import keras
30+
31+
# Note that only recent versions of keras have a `version()` function.
32+
if hasattr(keras, "version") and keras.version().startswith("3."):
33+
return True
34+
except:
35+
raise ValueError(
36+
"Unable to import `keras` with `tensorflow`. Please check your "
37+
"Keras and Tensorflow version are compatible; Keras 3 requires "
38+
"TensorFlow 2.15 or later. See keras.io/getting_started for more "
39+
"information on installing Keras."
40+
)
3741

3842
# No `keras.version()` means we are on an old version of keras.
3943
return False
@@ -49,53 +53,9 @@ def keras_3():
4953
return _USE_KERAS_3
5054

5155

52-
# Attempt to read KerasCV config file.
53-
_config_path = os.path.expanduser(os.path.join(_keras_dir, "keras_cv.json"))
54-
if os.path.exists(_config_path):
55-
try:
56-
with open(_config_path) as f:
57-
_config = json.load(f)
58-
except ValueError:
59-
_config = {}
60-
_MULTI_BACKEND = _config.get("multi_backend", _MULTI_BACKEND)
61-
62-
# Save config file, if possible.
63-
if not os.path.exists(_keras_dir):
64-
try:
65-
os.makedirs(_keras_dir)
66-
except OSError:
67-
# Except permission denied and potential race conditions
68-
# in multi-threaded environments.
69-
pass
70-
71-
if not os.path.exists(_config_path):
72-
_config = {
73-
"multi_backend": _MULTI_BACKEND,
74-
}
75-
try:
76-
with open(_config_path, "w") as f:
77-
f.write(json.dumps(_config, indent=4))
78-
except IOError:
79-
# Except permission denied.
80-
pass
81-
82-
if "KERAS_BACKEND" in os.environ and os.environ["KERAS_BACKEND"]:
83-
_MULTI_BACKEND = True
84-
85-
86-
def multi_backend():
87-
return _MULTI_BACKEND
88-
89-
9056
def backend():
9157
"""Check the backend framework."""
92-
if not multi_backend():
93-
return "tensorflow"
9458
if not keras_3():
95-
import keras_core
96-
97-
return keras_core.config.backend()
98-
99-
from tensorflow import keras
59+
return "tensorflow"
10060

10161
return keras.config.backend()

Diff for: keras_cv/backend/keras.py

-5
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@
3030
import keras # noqa: F403, F401
3131
from keras import * # noqa: F403, F401
3232

33-
keras.backend.name_scope = keras.name_scope
34-
elif config.multi_backend():
35-
import keras_core as keras # noqa: F403, F401
36-
from keras_core import * # noqa: F403, F401
37-
3833
keras.backend.name_scope = keras.name_scope
3934
else:
4035
from tensorflow import keras # noqa: F403, F401

Diff for: keras_cv/backend/ops.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
from keras_cv.backend.config import keras_3
15-
from keras_cv.backend.config import multi_backend
14+
from keras_cv.backend import config
1615

17-
if keras_3():
16+
if config.keras_3():
1817
from keras.ops import * # noqa: F403, F401
1918
from keras.preprocessing.image import smart_resize # noqa: F403, F401
2019

@@ -32,5 +31,5 @@
3231
from keras_core.src.utils.image_utils import ( # noqa: F403, F401
3332
smart_resize,
3433
)
35-
if not multi_backend():
36-
from keras_cv.backend.tf_ops import * # noqa: F403, F401
34+
if config.backend() == "tensorflow":
35+
from keras_cv.backend.tf_ops import * # noqa: F403, F401

Diff for: keras_cv/backend/scope.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from keras_cv.backend import keras
1919
from keras_cv.backend import ops
2020
from keras_cv.backend import tf_ops
21-
from keras_cv.backend.config import multi_backend
21+
from keras_cv.backend.config import keras_3
2222

2323
_ORIGINAL_OPS = copy.copy(backend.ops.__dict__)
2424
_ORIGINAL_SUPPORTS_RAGGED = backend.supports_ragged
@@ -30,7 +30,7 @@
3030
def tf_data(function):
3131
@functools.wraps(function)
3232
def wrapper(*args, **kwargs):
33-
if multi_backend() and keras.src.utils.backend_utils.in_tf_graph():
33+
if keras_3() and keras.src.utils.backend_utils.in_tf_graph():
3434
with TFDataScope():
3535
return function(*args, **kwargs)
3636
else:

Diff for: keras_cv/conftest.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import tensorflow as tf
1818
from packaging import version
1919

20-
from keras_cv.backend.config import multi_backend
20+
from keras_cv.backend.config import keras_3
2121

2222

2323
def pytest_addoption(parser):
@@ -45,7 +45,7 @@ def pytest_configure(config):
4545
)
4646
config.addinivalue_line(
4747
"markers",
48-
"tf_keras_only: mark test as a tf.keras-only test",
48+
"tf_keras_only: mark test as a Keras 2-only test",
4949
)
5050
config.addinivalue_line(
5151
"markers",
@@ -69,12 +69,12 @@ def pytest_collection_modifyitems(config, items):
6969
skip_extra_large = pytest.mark.skipif(
7070
not run_extra_large_tests, reason="need --run_extra_large option to run"
7171
)
72-
skip_tf_keras_only = pytest.mark.skipif(
73-
multi_backend(),
74-
reason="This test is only supported on tf.keras",
72+
skip_keras_2_only = pytest.mark.skipif(
73+
keras_3(),
74+
reason="This test is only supported on Keras 2",
7575
)
7676
skip_tf_only = pytest.mark.skipif(
77-
multi_backend() and keras_core.backend.backend() != "tensorflow",
77+
keras_3() and keras_core.backend.backend() != "tensorflow",
7878
reason="This test is only supported on TensorFlow",
7979
)
8080
for item in items:
@@ -87,6 +87,6 @@ def pytest_collection_modifyitems(config, items):
8787
if "extra_large" in item.keywords:
8888
item.add_marker(skip_extra_large)
8989
if "tf_keras_only" in item.keywords:
90-
item.add_marker(skip_tf_keras_only)
90+
item.add_marker(skip_keras_2_only)
9191
if "tf_only" in item.keywords:
9292
item.add_marker(skip_tf_only)

Diff for: keras_cv/layers/object_detection/multi_class_non_max_suppression.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from keras_cv.api_export import keras_cv_export
1919
from keras_cv.backend import keras
2020
from keras_cv.backend import ops
21-
from keras_cv.backend.config import multi_backend
21+
from keras_cv.backend.config import keras_3
2222

2323

2424
@keras_cv_export("keras_cv.layers.MultiClassNonMaxSuppression")
@@ -73,7 +73,7 @@ def call(
7373
`bounding_box_format` specified in the constructor.
7474
class_prediction: Dense Tensor of shape [batch, boxes, num_classes].
7575
"""
76-
if multi_backend() and keras.backend.backend() != "tensorflow":
76+
if keras_3() and keras.backend.backend() != "tensorflow":
7777
raise NotImplementedError(
7878
"MultiClassNonMaxSuppression does not support non-TensorFlow "
7979
"backends. Consider using NonMaxSuppression instead."

0 commit comments

Comments
 (0)