Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keras 3 tests #2143

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 15 additions & 16 deletions .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ permissions:
contents: read

jobs:
keras2:
name: Test the code with tf.keras
keras_2:
name: Test the code with Keras 2
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.9
uses: actions/setup-python@v1
uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Get pip cache dir
Expand All @@ -34,7 +34,7 @@ jobs:
${{ runner.os }}-pip-
- name: Install dependencies
run: |
pip install tensorflow>=2.13.0
pip install tensorflow~=2.14
pip install torch>=2.0.1+cpu
pip install "jax[cpu]"
pip install keras-core
Expand All @@ -44,17 +44,17 @@ jobs:
TEST_CUSTOM_OPS: false
run: |
pytest keras_cv/ --ignore keras_cv/models/legacy/ --durations 0
multibackend:
name: Test the code with Keras Core
keras_3:
name: Test the code with Keras 3
strategy:
fail-fast: false
matrix:
backend: [tensorflow, jax, torch]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.9
uses: actions/setup-python@v1
uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Get pip cache dir
Expand All @@ -71,12 +71,11 @@ jobs:
${{ runner.os }}-pip-
- name: Install dependencies
run: |
pip install tensorflow>=2.13.0
pip install -e ".[tests]" --progress-bar off --upgrade
pip install "jax[cpu]"
pip install torch>=2.0.1+cpu
pip install torchvision>=0.15.1
pip install keras-core
pip install -e ".[tests]" --progress-bar off --upgrade
pip install tf-nightly==2.16.0.dev20231103 # Pin a working nightly until rc0.
- name: Test with pytest
env:
TEST_CUSTOM_OPS: false # TODO(ianstenbit): test custom ops, or figure out what our story is here
Expand All @@ -99,9 +98,9 @@ jobs:
name: Check the code format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.9
uses: actions/setup-python@v1
uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Get pip cache dir
Expand All @@ -118,7 +117,7 @@ jobs:
${{ runner.os }}-pip-
- name: Install dependencies
run: |
pip install tensorflow>=2.13.0
pip install tensorflow~=2.14
pip install -e ".[tests]" --progress-bar off --upgrade
- name: Lint
run: bash shell/lint.sh
Expand All @@ -128,4 +127,4 @@ jobs:
source: '.'
extensions: 'h,c,cpp,hpp,cc'
clangFormatVersion: 14
style: google
style: google
2 changes: 1 addition & 1 deletion .github/workflows/devcontainer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
steps:

- name: Checkout (GitHub)
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Build and run dev container task
uses: devcontainers/[email protected]
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
pip install -r requirements.txt --progress-bar off
- name: Build wheel file
run: |
export BUILD_WITH_CUSTOM_OPS=false
python pip_build.py --nightly
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
Expand Down
133 changes: 33 additions & 100 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,105 +8,38 @@ permissions:
contents: read

jobs:
deploy-with-custom-ops:
# This job is currently skipped until we cut a release with custom ops.
if: false
name: Build and deploy release wheels with custom ops
runs-on: ${{ matrix.os }}
strategy:
matrix:
# To switch on windows-2022/latest, please verify the bazel version:
# https://github.com/bazelbuild/bazel/issues/14232#issuecomment-1011247429
os: ['macos-12', 'windows-2019', 'ubuntu-18.04']
py-version: ['3.9', '3.10', '3.11']
tf-version: ['2.13.0']
use-macos-arm: [false]
include:
- os: 'macos-12'
tf-version: '2.13.0'
py-version: '3.9'
use-macos-arm: true
- os: 'macos-12'
tf-version: '2.13.0'
py-version: '3.10'
use-macos-arm: true
fail-fast: false
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.py-version }}
- name: Get pip cache dir
id: pip-cache
run: |
python -m pip install --upgrade pip setuptools wheel auditwheel twine
echo "::set-output name=dir::$(pip cache dir)"
- name: pip cache
uses: actions/cache@v2
with:
path: ${{ steps.pip-cache.outputs.dir }}
key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install tensorflow-cpu==${{ matrix.tf-version }}
python -m pip install -e ".[tests]" --progress-bar off --upgrade
- name: Configure Build Environment
run: |
python build_deps/configure.py
- name: Reinstall TensorFlow (MacOS ARM)
if: ${{ matrix.os == 'macos-12' && matrix.use-macos-arm}}
run: |
python -m pip uninstall -y tensorflow-cpu
python -m pip install --platform=macosx_12_0_arm64 --no-deps --target=$(python -c 'import site; print(site.getsitepackages()[0])') --upgrade tensorflow-macos==${{ matrix.tf-version }}
- name: Bazel Build
if: ${{ ! matrix.use-macos-arm }}
run: |
export BUILD_WITH_CUSTOM_OPS=true
bazel build build_pip_pkg
- name: Bazel Build (MacOS ARM)
if: ${{ matrix.use-macos-arm}}
run: |
bazel build --cpu=darwin_arm64 --copt -mmacosx-version-min=12.0 --linkopt -mmacosx-version-min=12.0 build_pip_pkg
- name: Build wheels
run: |
export BUILD_WITH_CUSTOM_OPS=true
bazel-bin/build_pip_pkg wheels
- name: Repair wheels (manylinux)
if: ${{ matrix.os == 'ubuntu-18.04' }}
run: |
python -m pip install --upgrade patchelf==0.14
bash build_deps/tf_auditwheel_patch.sh
python -m auditwheel repair --plat manylinux2014_x86_64 wheels/*.whl
rm wheels/*.whl
mv wheelhouse/* wheels/
- name: Upload wheels
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
twine upload wheels/*
deploy-without-custom-ops:
name: Build and deploy release wheels without custom ops
run-test-for-release:
uses: ./.github/workflows/actions.yml
release:
name: Build and publish to PyPI
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: 3.9
- name: Build wheels
run: |
pip install tensorflow==2.13.0
python -m pip install --upgrade setuptools wheel twine
python -m pip install --upgrade -r requirements.txt
export BUILD_WITH_CUSTOM_OPS=false
python pip_build.py
- name: Upload wheels
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
twine upload dist/*.whl
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Get pip cache dir
id: pip-cache
run: |
python -m pip install --upgrade pip setuptools
echo "::set-output name=dir::$(pip cache dir)"
- name: pip cache
uses: actions/cache@v2
with:
path: ${{ steps.pip-cache.outputs.dir }}
key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
pip install -r requirements.txt --progress-bar off
- name: Build a binary wheel and a source tarball
run: |
export BUILD_WITH_CUSTOM_OPS=false
python pip_build.py
- name: Publish distribution to PyPI
if: startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@master
with:
password: ${{ secrets.PYPI_API_TOKEN }}
2 changes: 2 additions & 0 deletions keras_cv/backend/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

if keras_3():
from keras.ops import * # noqa: F403, F401
# TODO: Remove once `is_tensor` is an public API
from keras.src.ops import is_tensor # noqa: F403, F401
from keras.preprocessing.image import smart_resize # noqa: F403, F401
else:
try:
Expand Down
55 changes: 55 additions & 0 deletions keras_cv/backend/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,63 @@
# limitations under the License.

from keras_cv.backend.config import keras_3
from keras_cv.backend import keras

if keras_3():
from keras.random import * # noqa: F403, F401
else:
from keras_core.random import * # noqa: F403, F401


class RandomGenerator:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SeedGenerator

"""Random generator that selects appropriate random ops.

Created for compatibility between Keras 2 and Keras 3.
"""

def __init__(self, seed=None, **kwargs):
self._seed = seed
self._is_keras_3 = keras_3()
if self._is_keras_3:
# Ignore args specifc to keras 2 RandomGenerator
kwargs.pop("force_generator", None)
kwargs.pop("rng_type", None)
self._seed_gen = keras.random.SeedGenerator(seed, **kwargs)
else:
self._v2_random_gen = keras.backend.RadomGenerator(seed, **kwargs)

def random_normal(self, shape, mean=0.0, stddev=1.0, dtype=None):
"""Produce random number based on the normal distribution.
"""
if self._is_keras_3:
return keras.random.normal(shape, mean=mean, stddev=stddev, dtype=dtype, seed=self._seed_gen)
else:
return self._v2_random_gen.random_normal(shape, mean=mean, stddev=stddev, dtype=dtype)

def random_uniform(
self, shape, minval=0.0, maxval=None, dtype=None
):
"""Produce random number based on the uniform distribution."""
if self._is_keras_3:
return keras.random.uniform(shape, minval=minval, maxval=maxval, dtype=dtype, seed=self._seed_gen)
else:
return self._v2_random_gen.random_uniform(shape, minval=minval, maxval=maxval, dtype=dtype)


def truncated_normal(
self, shape, mean=0.0, stddev=1.0, dtype=None
):
"""Produce random number based on the truncated normal distribution."""
if self._is_keras_3:
return keras.random.truncated_normal(shape, mean=mean, stddev=stddev, dtype=dtype, seed=self._seed_gen)
else:
return self._v2_random_gen.truncated_normal(shape, mean=mean, stddev=stddev, dtype=dtype)


def make_legacy_seed(self):
"""Create a new seed for the legacy stateful ops to use."""

if self._is_keras_3:
return self._seed_gen.next()
else:
return self._v2_random_gen.make_legacy_seed()
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from keras_cv.backend import keras
from keras_cv.backend import scope
from keras_cv.backend.config import multi_backend
from keras_cv.backend.random import RandomGenerator
from keras_cv.utils import preprocessing

# In order to support both unbatched and batched inputs, the horizontal
Expand Down Expand Up @@ -124,14 +125,14 @@ def augment_image(self, image, transformation):
```

Note that since the randomness is also a common functionality, this layer
also includes a keras_backend.RandomGenerator, which can be used to
also includes RandomGenerator, which can be used to
produce the random numbers. The random number generator is stored in the
`self._random_generator` attribute.
"""

def __init__(self, seed=None, **kwargs):
force_generator = kwargs.pop("force_generator", False)
self._random_generator = keras_backend.RandomGenerator(
self._random_generator = RandomGenerator(
seed=seed, force_generator=force_generator
)
super().__init__(**kwargs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from keras_cv.api_export import keras_cv_export
from keras_cv.backend import keras
from keras_cv.backend import scope
from keras_cv.backend.random import RandomGenerator
from keras_cv.backend.config import multi_backend
from keras_cv.utils import preprocessing

Expand Down Expand Up @@ -103,14 +104,14 @@ def __init__(self):
```

Note that since the randomness is also a common functionality, this layer
also includes a keras_backend.RandomGenerator, which can be used to
also includes RandomGenerator, which can be used to
produce the random numbers. The random number generator is stored in the
`self._random_generator` attribute.
"""

def __init__(self, seed=None, **kwargs):
force_generator = kwargs.pop("force_generator", False)
self._random_generator = keras_backend.RandomGenerator(
self._random_generator = RandomGenerator(
seed=seed, force_generator=force_generator
)
super().__init__(**kwargs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def augment_pointclouds(self, point_clouds, transformation):
```

Note that since the randomness is also a common functionality, this layer
also includes a keras.backend.RandomGenerator, which can be used to
also includes RandomGenerator, which can be used to
produce the random numbers. The random number generator is stored in the
`self._random_generator` attribute.
"""
Expand Down
15 changes: 15 additions & 0 deletions requirements-common.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Library deps.
absl-py
regex
pandas
keras-core>=0.1.6
tensorflow-datasets
pycocotools
# Tooling deps.
packaging
flake8
isort
black
pytest
build
namex
Loading
Loading