Commit 1a3c83d6 authored by zhanggzh's avatar zhanggzh
Browse files

增加keras-cv模型及训练代码

parent 9846958a
#!/usr/bin/env bash
# Copyright 2022 The KerasCV Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
# Builds a wheel of KerasCV for Pip. Requires Bazel.
# Adapted from https://github.com/tensorflow/addons/blob/master/build_deps/build_pip_pkg.sh
set -e
set -x
PLATFORM="$(uname -s | tr 'A-Z' 'a-z')"
function is_windows() {
if [[ "${PLATFORM}" =~ (cygwin|mingw32|mingw64|msys)_nt* ]]; then
true
else
false
fi
}
if is_windows; then
PIP_FILE_PREFIX="bazel-bin/build_pip_pkg.exe.runfiles/__main__/"
else
PIP_FILE_PREFIX="bazel-bin/build_pip_pkg.runfiles/__main__/"
fi
function main() {
while [[ ! -z "${1}" ]]; do
if [[ ${1} == "make" ]]; then
echo "Using Makefile to build pip package."
PIP_FILE_PREFIX=""
else
DEST=${1}
fi
shift
done
if [[ -z ${DEST} ]]; then
echo "No destination dir provided"
exit 1
fi
# Create the directory, then do dirname on a non-existent file inside it to
# give us an absolute paths with tilde characters resolved to the destination
# directory.
mkdir -p ${DEST}
if [[ ${PLATFORM} == "darwin" ]]; then
DEST=$(pwd -P)/${DEST}
else
DEST=$(readlink -f "${DEST}")
fi
echo "=== destination directory: ${DEST}"
TMPDIR=$(mktemp -d -t tmp.XXXXXXXXXX)
echo $(date) : "=== Using tmpdir: ${TMPDIR}"
echo "=== Copy KerasCV Custom op files"
cp ${PIP_FILE_PREFIX}setup.py "${TMPDIR}"
cp ${PIP_FILE_PREFIX}MANIFEST.in "${TMPDIR}"
cp ${PIP_FILE_PREFIX}README.md "${TMPDIR}"
cp ${PIP_FILE_PREFIX}LICENSE "${TMPDIR}"
rsync -avm -L --exclude='*_test.py' ${PIP_FILE_PREFIX}keras_cv "${TMPDIR}"
pushd ${TMPDIR}
echo $(date) : "=== Building wheel"
python3 setup.py bdist_wheel > /dev/null
cp dist/*.whl "${DEST}"
popd
rm -rf ${TMPDIR}
echo $(date) : "=== Output wheel file is in: ${DEST}"
}
main "$@"
# Copyright 2022 The KerasCV Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
# Usage: python configure.py
"""Configures local environment to prepare for building KerasCV from source."""
import logging
import os
import pathlib
import platform
import tensorflow as tf
from packaging.version import Version
_TFA_BAZELRC = ".bazelrc"
# Writes variables to bazelrc file
def write(line):
with open(_TFA_BAZELRC, "a") as f:
f.write(line + "\n")
def write_action_env(var_name, var):
write('build --action_env {}="{}"'.format(var_name, var))
def is_macos():
return platform.system() == "Darwin"
def is_windows():
return platform.system() == "Windows"
def is_linux():
return platform.system() == "Linux"
def is_raspi_arm():
return os.uname()[4] == "armv7l" or os.uname()[4] == "aarch64"
def is_linux_ppc64le():
return is_linux() and platform.machine() == "ppc64le"
def is_linux_x86_64():
return is_linux() and platform.machine() == "x86_64"
def is_linux_arm():
return is_linux() and platform.machine() == "arm"
def is_linux_aarch64():
return is_linux() and platform.machine() == "aarch64"
def is_linux_s390x():
return is_linux() and platform.machine() == "s390x"
def get_tf_header_dir():
import tensorflow as tf
tf_header_dir = tf.sysconfig.get_compile_flags()[0][2:]
if is_windows():
tf_header_dir = tf_header_dir.replace("\\", "/")
return tf_header_dir
def get_cpp_version():
cpp_version = "c++14"
if Version(tf.__version__) >= Version("2.10"):
cpp_version = "c++17"
return cpp_version
def get_tf_shared_lib_dir():
import tensorflow as tf
# OS Specific parsing
if is_windows():
tf_shared_lib_dir = tf.sysconfig.get_compile_flags()[0][2:-7] + "python"
return tf_shared_lib_dir.replace("\\", "/")
elif is_raspi_arm():
return tf.sysconfig.get_compile_flags()[0][2:-7] + "python"
else:
return tf.sysconfig.get_link_flags()[0][2:]
# Converts the linkflag namespec to the full shared library name
def get_shared_lib_name():
import tensorflow as tf
namespec = tf.sysconfig.get_link_flags()
if is_macos():
# MacOS
return "lib" + namespec[1][2:] + ".dylib"
elif is_windows():
# Windows
return "_pywrap_tensorflow_internal.lib"
elif is_raspi_arm():
# The below command for linux would return an empty list
return "_pywrap_tensorflow_internal.so"
else:
# Linux
return namespec[1][3:]
def create_build_configuration():
print()
print("Configuring KerasCV to be built from source...")
if os.path.isfile(_TFA_BAZELRC):
os.remove(_TFA_BAZELRC)
logging.disable(logging.WARNING)
write_action_env("TF_HEADER_DIR", get_tf_header_dir())
write_action_env("TF_SHARED_LIBRARY_DIR", get_tf_shared_lib_dir())
write_action_env("TF_SHARED_LIBRARY_NAME", get_shared_lib_name())
write_action_env("TF_CXX11_ABI_FLAG", tf.sysconfig.CXX11_ABI_FLAG)
# This should be replaced with a call to tf.sysconfig if it's added
write_action_env("TF_CPLUSPLUS_VER", get_cpp_version())
write("build --spawn_strategy=standalone")
write("build --strategy=Genrule=standalone")
write("build --experimental_repo_remote_exec")
write("build -c opt")
write(
"build --cxxopt="
+ '"-D_GLIBCXX_USE_CXX11_ABI="'
+ str(tf.sysconfig.CXX11_ABI_FLAG)
)
if is_windows():
write("build --config=windows")
write("build:windows --enable_runfiles")
write("build:windows --copt=/experimental:preprocessor")
write("build:windows --host_copt=/experimental:preprocessor")
write("build:windows --copt=/arch=AVX")
write("build:windows --cxxopt=/std:" + get_cpp_version())
write("build:windows --host_cxxopt=/std:" + get_cpp_version())
if is_macos() or is_linux():
if not is_linux_ppc64le() and not is_linux_arm() and not is_linux_aarch64():
write("build --copt=-mavx")
write("build --cxxopt=-std=" + get_cpp_version())
write("build --host_cxxopt=-std=" + get_cpp_version())
print("> Building only CPU ops")
print()
print("Build configurations successfully written to", _TFA_BAZELRC, ":\n")
print(pathlib.Path(_TFA_BAZELRC).read_text())
if __name__ == "__main__":
create_build_configuration()
package(default_visibility = ["//visibility:public"])
cc_library(
name = "tf_header_lib",
hdrs = [":tf_header_include"],
includes = ["include"],
visibility = ["//visibility:public"],
)
cc_library(
name = "libtensorflow_framework",
srcs = ["%{TF_SHARED_LIBRARY_NAME}"],
visibility = ["//visibility:public"],
)
%{TF_HEADER_GENRULE}
%{TF_SHARED_LIBRARY_GENRULE}
# Addons Build Definitions inherited from TensorFlow Core
D_GLIBCXX_USE_CXX11_ABI = "%{tf_cx11_abi}"
CPLUSPLUS_VERSION = "%{tf_cplusplus_ver}"
"""Setup TensorFlow as external dependency"""
_TF_HEADER_DIR = "TF_HEADER_DIR"
_TF_SHARED_LIBRARY_DIR = "TF_SHARED_LIBRARY_DIR"
_TF_SHARED_LIBRARY_NAME = "TF_SHARED_LIBRARY_NAME"
_TF_CXX11_ABI_FLAG = "TF_CXX11_ABI_FLAG"
_TF_CPLUSPLUS_VER = "TF_CPLUSPLUS_VER"
def _tpl(repository_ctx, tpl, substitutions = {}, out = None):
if not out:
out = tpl
repository_ctx.template(
out,
Label("//build_deps/tf_dependency:%s.tpl" % tpl),
substitutions,
)
def _fail(msg):
"""Output failure message when auto configuration fails."""
red = "\033[0;31m"
no_color = "\033[0m"
fail("%sPython Configuration Error:%s %s\n" % (red, no_color, msg))
def _is_windows(repository_ctx):
"""Returns true if the host operating system is windows."""
os_name = repository_ctx.os.name.lower()
if os_name.find("windows") != -1:
return True
return False
def _execute(
repository_ctx,
cmdline,
error_msg = None,
error_details = None,
empty_stdout_fine = False):
"""Executes an arbitrary shell command.
Helper for executes an arbitrary shell command.
Args:
repository_ctx: the repository_ctx object.
cmdline: list of strings, the command to execute.
error_msg: string, a summary of the error if the command fails.
error_details: string, details about the error or steps to fix it.
empty_stdout_fine: bool, if True, an empty stdout result is fine, otherwise
it's an error.
Returns:
The result of repository_ctx.execute(cmdline).
"""
result = repository_ctx.execute(cmdline)
if result.stderr or not (empty_stdout_fine or result.stdout):
_fail("\n".join([
error_msg.strip() if error_msg else "Repository command failed",
result.stderr.strip(),
error_details if error_details else "",
]))
return result
def _read_dir(repository_ctx, src_dir):
"""Returns a string with all files in a directory.
Finds all files inside a directory, traversing subfolders and following
symlinks. The returned string contains the full path of all files
separated by line breaks.
Args:
repository_ctx: the repository_ctx object.
src_dir: directory to find files from.
Returns:
A string of all files inside the given dir.
"""
if _is_windows(repository_ctx):
src_dir = src_dir.replace("/", "\\")
find_result = _execute(
repository_ctx,
["cmd.exe", "/c", "dir", src_dir, "/b", "/s", "/a-d"],
empty_stdout_fine = True,
)
# src_files will be used in genrule.outs where the paths must
# use forward slashes.
result = find_result.stdout.replace("\\", "/")
else:
find_result = _execute(
repository_ctx,
["find", src_dir, "-follow", "-type", "f"],
empty_stdout_fine = True,
)
result = find_result.stdout
return result
def _genrule(genrule_name, command, outs):
"""Returns a string with a genrule.
Genrule executes the given command and produces the given outputs.
Args:
genrule_name: A unique name for genrule target.
command: The command to run.
outs: A list of files generated by this rule.
Returns:
A genrule target.
"""
return (
"genrule(\n" +
' name = "' +
genrule_name + '",\n' +
" outs = [\n" +
outs +
"\n ],\n" +
' cmd = """\n' +
command +
'\n """,\n' +
")\n"
)
def _norm_path(path):
"""Returns a path with '/' and remove the trailing slash."""
path = path.replace("\\", "/")
if path[-1] == "/":
path = path[:-1]
return path
def _symlink_genrule_for_dir(
repository_ctx,
src_dir,
dest_dir,
genrule_name,
src_files = [],
dest_files = [],
tf_pip_dir_rename_pair = []):
"""Returns a genrule to symlink(or copy if on Windows) a set of files.
If src_dir is passed, files will be read from the given directory; otherwise
we assume files are in src_files and dest_files.
Args:
repository_ctx: the repository_ctx object.
src_dir: source directory.
dest_dir: directory to create symlink in.
genrule_name: genrule name.
src_files: list of source files instead of src_dir.
dest_files: list of corresonding destination files.
tf_pip_dir_rename_pair: list of the pair of tf pip parent directory to
replace. For example, in TF pip package, the source code is under
"tensorflow_core", and we might want to replace it with
"tensorflow" to match the header includes.
Returns:
genrule target that creates the symlinks.
"""
# Check that tf_pip_dir_rename_pair has the right length
tf_pip_dir_rename_pair_len = len(tf_pip_dir_rename_pair)
if tf_pip_dir_rename_pair_len != 0 and tf_pip_dir_rename_pair_len != 2:
_fail("The size of argument tf_pip_dir_rename_pair should be either 0 or 2, but %d is given." % tf_pip_dir_rename_pair_len)
if src_dir != None:
src_dir = _norm_path(src_dir)
dest_dir = _norm_path(dest_dir)
files = "\n".join(sorted(_read_dir(repository_ctx, src_dir).splitlines()))
# Create a list with the src_dir stripped to use for outputs.
if tf_pip_dir_rename_pair_len:
dest_files = files.replace(src_dir, "").replace(tf_pip_dir_rename_pair[0], tf_pip_dir_rename_pair[1]).splitlines()
else:
dest_files = files.replace(src_dir, "").splitlines()
src_files = files.splitlines()
command = []
outs = []
for i in range(len(dest_files)):
if dest_files[i] != "":
# If we have only one file to link we do not want to use the dest_dir, as
# $(@D) will include the full path to the file.
dest = "$(@D)/" + dest_dir + dest_files[i] if len(dest_files) != 1 else "$(@D)/" + dest_files[i]
# Copy the headers to create a sandboxable setup.
cmd = "cp -f"
command.append(cmd + ' "%s" "%s"' % (src_files[i], dest))
outs.append(' "' + dest_dir + dest_files[i] + '",')
genrule = _genrule(
genrule_name,
";\n".join(command),
"\n".join(outs),
)
return genrule
def _tf_pip_impl(repository_ctx):
tf_header_dir = repository_ctx.os.environ[_TF_HEADER_DIR]
tf_header_rule = _symlink_genrule_for_dir(
repository_ctx,
tf_header_dir,
"include",
"tf_header_include",
tf_pip_dir_rename_pair = ["tensorflow_core", "tensorflow"],
)
tf_shared_library_dir = repository_ctx.os.environ[_TF_SHARED_LIBRARY_DIR]
tf_shared_library_name = repository_ctx.os.environ[_TF_SHARED_LIBRARY_NAME]
tf_shared_library_path = "%s/%s" % (tf_shared_library_dir, tf_shared_library_name)
tf_cx11_abi = "-D_GLIBCXX_USE_CXX11_ABI=%s" % (repository_ctx.os.environ[_TF_CXX11_ABI_FLAG])
tf_cplusplus_ver = "-std=%s" % repository_ctx.os.environ[_TF_CPLUSPLUS_VER]
tf_shared_library_rule = _symlink_genrule_for_dir(
repository_ctx,
None,
"",
tf_shared_library_name,
[tf_shared_library_path],
[tf_shared_library_name],
)
_tpl(repository_ctx, "BUILD", {
"%{TF_HEADER_GENRULE}": tf_header_rule,
"%{TF_SHARED_LIBRARY_GENRULE}": tf_shared_library_rule,
"%{TF_SHARED_LIBRARY_NAME}": tf_shared_library_name,
})
_tpl(
repository_ctx,
"build_defs.bzl",
{
"%{tf_cx11_abi}": tf_cx11_abi,
"%{tf_cplusplus_ver}": tf_cplusplus_ver,
},
)
tf_configure = repository_rule(
environ = [
_TF_HEADER_DIR,
_TF_SHARED_LIBRARY_DIR,
_TF_SHARED_LIBRARY_NAME,
_TF_CXX11_ABI_FLAG,
_TF_CPLUSPLUS_VER,
],
implementation = _tf_pip_impl,
)
# keras-cv-image:deps has all deps of KerasCV for testing.
FROM us-west1-docker.pkg.dev/keras-team-test/keras-cv-test/keras-cv-image:deps
COPY . /kerascv
WORKDIR /kerascv
# KerasCV Accelerators Testing
This `cloudbuild/` directory contains configurations for accelerators (GPU/TPU)
testing. Briefly, for each PR, it copies the PR's code to a base docker image
which contains KerasCV dependencies to make a new docker image, and deploys the
new image to Google Kubernetes Engine cluster, then run all tests in
`keras_cv/` via Google Cloud Build.
- `cloudbuild.yaml`: The cloud build configuration that specifies steps to run
by cloud build.
- `Dockerfile`: The configuration to build the docker image for deployment.
- `requirements.txt`: Dependencies of KerasCV.
- `unit_test_jobs.jsonnet`: Jsonnet config that tells GKE cluster to run all
unit tests in `keras_cv/`.
This test is powered by [ml-testing-accelerators](https://github.com/GoogleCloudPlatform/ml-testing-accelerators).
### Adding Test Dependencies
You must be authorized to run builds in the `keras-team-test` GCP project.
If you are not, please open a GitHub issue and ping a team member.
To authorize yourself with `keras-team-test`, run:
```bash
gcloud config set project keras-team-test
```
To add a dependency for GPU tests:
- Create a PR adding the dependency to `requirements.txt`
- Have a Keras team member update the Docker image for GPU tests by running the remaining steps
- Create a `Dockerfile` with the following contents:
```
FROM tensorflow/tensorflow:2.10.0-gpu
RUN \
apt-get -y update && \
apt-get -y install openjdk-8-jdk && \
echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | tee /etc/apt/sources.list.d/bazel.list && \
curl https://bazel.build/bazel-release.pub.gpg | apt-key add
RUN apt-get -y update
RUN apt-get -y install bazel
RUN apt-get -y install git
RUN git clone https://github.com/{path_to_keras_cv_fork}.git
RUN cd keras-cv && git checkout {branch_name}
RUN pip install -r keras-cv/cloudbuild/requirements.txt
```
- Run the following command from the directory with your `Dockerfile`:
```
gcloud builds submit --region=us-west1 --tag us-west1-docker.pkg.dev/keras-team-test/keras-cv-test/keras-cv-image:deps --timeout=10m
```
- Merge the PR adding the dependency
substitutions:
# GCS bucket name.
_GCS_BUCKET: 'gs://keras-cv-github-test'
# GKE cluster name.
_CLUSTER_NAME: 'keras-cv-test-cluster'
# Location of GKE cluster.
_CLUSTER_ZONE: 'us-west1-b'
# Image name.
_IMAGE_NAME: 'us-west1-docker.pkg.dev/keras-team-test/keras-cv-test/keras-cv-image'
steps:
- name: 'docker'
id: build-image
args: [
'build',
'.',
'-f', 'cloudbuild/Dockerfile',
'-t', '$_IMAGE_NAME:$BUILD_ID',
]
- name: 'docker'
id: push-image
waitFor:
- build-image
args: ['push', '$_IMAGE_NAME:$BUILD_ID']
- name: 'golang'
id: download-jsonnet
waitFor: ['-']
entrypoint: 'go'
args: [
'install',
'github.com/google/go-jsonnet/cmd/jsonnet@latest',
]
- name: 'google/cloud-sdk'
id: clone-templates
waitFor: ['-']
entrypoint: 'git'
args: [
'clone',
'https://github.com/GoogleCloudPlatform/ml-testing-accelerators.git',
]
- name: 'golang'
id: build-templates
waitFor:
- download-jsonnet
- clone-templates
entrypoint: 'jsonnet'
args: [
'cloudbuild/unit_test_jobs.jsonnet',
'--string',
'-J', 'ml-testing-accelerators',
'--ext-str', 'image=$_IMAGE_NAME',
'--ext-str', 'tag_name=$BUILD_ID',
'--ext-str', 'gcs_bucket=$_GCS_BUCKET',
'-o', 'output.yaml',
]
- name: 'google/cloud-sdk'
id: create-job
waitFor:
- push-image
- build-templates
entrypoint: bash
args:
- -c
- |
set -u
set -e
set -x
gcloud container clusters get-credentials $_CLUSTER_NAME --zone $_CLUSTER_ZONE --project keras-team-test
job_name=$(kubectl create -f output.yaml -o name)
sleep 5
pod_name=$(kubectl wait --for condition=ready --timeout=10m pod -l job-name=${job_name#job.batch/} -o name)
kubectl logs -f $pod_name --container=train
sleep 5
gcloud artifacts docker images delete $_IMAGE_NAME:$BUILD_ID
exit $(kubectl get $pod_name -o jsonpath={.status.containerStatuses[0].state.terminated.exitCode})
timeout: 1800s # 30 minutes
options:
volumes:
- name: go-modules
path: /go
absl-py
packaging
pandas
tensorflow
tensorflow-datasets
flake8
regex
isort
black
pytest
\ No newline at end of file
local base = import 'templates/base.libsonnet';
local gpus = import 'templates/gpus.libsonnet';
local image = std.extVar('image');
local tagName = std.extVar('tag_name');
local gcsBucket = std.extVar('gcs_bucket');
local unittest = base.BaseTest {
// Configure job name.
frameworkPrefix: "tf",
modelName: "keras-cv",
mode: "unit-tests",
timeout: 3600, # 1 hour, in seconds
// Set up runtime environment.
image: image,
imageTag: tagName,
accelerator: gpus.teslaT4,
outputBucket: gcsBucket,
entrypoint: [
'bash',
'-c',
|||
# Build custom ops from source
python build_deps/configure.py
bazel build keras_cv/custom_ops:all --verbose_failures
cp bazel-bin/keras_cv/custom_ops/*.so keras_cv/custom_ops/
TEST_CUSTOM_OPS=true
# Run whatever is in `command` here.
${@:0}
|||
],
command: [
'pytest',
'keras_cv',
],
};
std.manifestYamlDoc(unittest.oneshotJob, quote_keys=false)
# Copyright 2022 The KerasCV Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import demo_utils
import tensorflow as tf
from keras_cv import layers as cv_layers
def _default_anchor_generator(bounding_box_format):
strides = [50]
sizes = [100.0]
scales = [1.0]
aspect_ratios = [1.0]
return cv_layers.AnchorGenerator(
bounding_box_format=bounding_box_format,
anchor_sizes=sizes,
aspect_ratios=aspect_ratios,
scales=scales,
strides=strides,
clip_boxes=True,
)
generator = _default_anchor_generator(bounding_box_format="xywh")
def pair_with_anchor_boxes(inputs):
images = inputs["images"]
anchor_boxes = generator(images[0])
anchor_boxes = anchor_boxes[0]
anchor_boxes = tf.expand_dims(anchor_boxes, axis=0)
anchor_boxes = tf.tile(anchor_boxes, [tf.shape(images)[0], 1, 1])
inputs["bounding_boxes"] = anchor_boxes
return inputs
if __name__ == "__main__":
dataset = demo_utils.load_voc_dataset(bounding_box_format="xywh")
result = dataset.map(pair_with_anchor_boxes, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_data(result, bounding_box_format="xywh")
# Copyright 2022 The KerasCV Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Utility functions for preprocessing demos."""
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds
from keras_cv import bounding_box
def preprocess_voc(inputs, format, image_size):
"""mapping function to create batched image and bbox coordinates"""
inputs["image"] = tf.image.resize(inputs["image"], image_size)
inputs["objects"]["bbox"] = bounding_box.convert_format(
inputs["objects"]["bbox"],
images=inputs["image"],
source="rel_yxyx",
target=format,
)
return {"images": inputs["image"], "bounding_boxes": inputs["objects"]["bbox"]}
def load_voc_dataset(
bounding_box_format,
name="voc/2007",
batch_size=9,
image_size=(224, 224),
):
dataset = tfds.load(name, split=tfds.Split.TRAIN, shuffle_files=True)
dataset = dataset.map(
lambda x: preprocess_voc(x, format=bounding_box_format, image_size=image_size),
num_parallel_calls=tf.data.AUTOTUNE,
)
dataset = dataset.padded_batch(
batch_size, padding_values={"images": None, "bounding_boxes": -1.0}
)
return dataset
def visualize_data(data, bounding_box_format):
data = next(iter(data))
images = data["images"]
bounding_boxes = data["bounding_boxes"]
output_images = visualize_bounding_boxes(
images, bounding_boxes, bounding_box_format
).numpy()
gallery_show(output_images)
def visualize_bounding_boxes(image, bounding_boxes, bounding_box_format):
color = np.array([[255.0, 0.0, 0.0]])
bounding_boxes = bounding_box.convert_format(
bounding_boxes,
source=bounding_box_format,
target="rel_yxyx",
images=image,
)
return tf.image.draw_bounding_boxes(image, bounding_boxes, color, name=None)
def gallery_show(images):
images = images.astype(int)
for i in range(9):
image = images[i]
plt.subplot(3, 3, i + 1)
plt.imshow(image.astype("uint8"))
plt.axis("off")
plt.show()
# Copyright 2022 The KerasCV Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Utility functions for preprocessing demos."""
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds
from keras_cv import bounding_box
def preprocess_voc(inputs, format, image_size):
"""mapping function to create batched image and bbox coordinates"""
inputs["image"] = tf.image.resize(inputs["image"], image_size)
inputs["objects"]["bbox"] = bounding_box.convert_format(
inputs["objects"]["bbox"],
images=inputs["image"],
source="rel_yxyx",
target=format,
)
inputs["objects"]["bbox"] = bounding_box.add_class_id(inputs["objects"]["bbox"])
return {"images": inputs["image"], "bounding_boxes": inputs["objects"]["bbox"]}
def load_voc_dataset(
bounding_box_format,
name="voc/2007",
batch_size=9,
image_size=(224, 224),
):
dataset = tfds.load(name, split=tfds.Split.TRAIN, shuffle_files=True)
dataset = dataset.map(
lambda x: preprocess_voc(x, format=bounding_box_format, image_size=image_size),
num_parallel_calls=tf.data.AUTOTUNE,
)
dataset = dataset.padded_batch(
batch_size, padding_values={"images": None, "bounding_boxes": -1.0}
)
return dataset
def visualize_data(data, bounding_box_format):
data = next(iter(data))
images = data["images"]
bounding_boxes = data["bounding_boxes"]
output_images = visualize_bounding_boxes(
images, bounding_boxes, bounding_box_format
).numpy()
gallery_show(output_images)
def visualize_bounding_boxes(image, bounding_boxes, bounding_box_format):
color = np.array([[255.0, 0.0, 0.0]])
bounding_boxes = bounding_boxes[..., :4]
bounding_boxes = bounding_box.convert_format(
bounding_boxes,
source=bounding_box_format,
target="rel_yxyx",
images=image,
)
return tf.image.draw_bounding_boxes(image, bounding_boxes, color, name=None)
def gallery_show(images):
images = images.astype(int)
for i in range(9):
image = images[i]
plt.subplot(3, 3, i + 1)
plt.imshow(image.astype("uint8"))
plt.axis("off")
plt.show()
# Copyright 2022 The KerasCV Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
mosaic_demo.py shows how to use the Mosaic preprocessing layer for
object detection.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
IMG_SIZE = (256, 256)
BATCH_SIZE = 9
def main():
dataset = demo_utils.load_voc_dataset(bounding_box_format="rel_xyxy")
mosaic = preprocessing.Mosaic(bounding_box_format="rel_xyxy")
result = dataset.map(mosaic, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_data(result, bounding_box_format="rel_xyxy")
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
random_flip_demo.py shows how to use the RandomFlip preprocessing layer for
object detection.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
IMG_SIZE = (256, 256)
BATCH_SIZE = 9
def main():
dataset = demo_utils.load_voc_dataset(bounding_box_format="rel_xyxy")
random_rotation = preprocessing.RandomFlip(bounding_box_format="rel_xyxy")
result = dataset.map(random_rotation, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_data(result, bounding_box_format="rel_xyxy")
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
random_rotation_demo.py shows how to use the RandomRotation preprocessing layer
for object detection.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
IMG_SIZE = (256, 256)
BATCH_SIZE = 9
def main():
dataset = demo_utils.load_voc_dataset(bounding_box_format="rel_xyxy")
random_rotation = preprocessing.RandomRotation(
factor=0.5, bounding_box_format="rel_xyxy"
)
result = dataset.map(random_rotation, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_data(result, bounding_box_format="rel_xyxy")
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
random_shear_demo.py shows how to use the RandomShear preprocessing layer
for object detection.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
IMG_SIZE = (256, 256)
BATCH_SIZE = 9
def main():
dataset = demo_utils.load_voc_dataset(bounding_box_format="rel_xyxy")
random_shear = preprocessing.RandomShear(
x_factor=(0.1, 0.5),
y_factor=(0.1, 0.5),
bounding_box_format="rel_xyxy",
)
dataset = dataset.map(random_shear, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_data(dataset, bounding_box_format="rel_xyxy")
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
visualization_demo.py is used to visualize the dataset with bounding boxes.
"""
import demo_utils
def main():
inputs = demo_utils.load_voc_dataset(bounding_box_format="rel_xyxy")
demo_utils.visualize_data(inputs, bounding_box_format="rel_xyxy")
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""aug_mix_demo.py shows how to use the AugMix preprocessing layer.
Operates on the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv import layers
def main():
augmix = layers.AugMix(value_range=[0, 255])
ds = demo_utils.load_oxford_dataset()
ds = ds.map(augmix, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment