Visualize Object-Detection Datasets using Weights & Biases¶
This notebook demostrates how you can visualize and debug your data input pipeline for object detetction using Weights & Biases.
Original Notebook: https://keras.io/guides/keras_cv/object_detection_keras_cv/
Install Dependencies¶
In [ ]:
Copied!
!pip install --upgrade -q git+https://github.com/keras-team/keras-cv
!pip install --upgrade -q git+https://github.com/soumik12345/wandb-addons
!pip install --upgrade -q git+https://github.com/keras-team/keras-cv
!pip install --upgrade -q git+https://github.com/soumik12345/wandb-addons
In [ ]:
Copied!
import tensorflow as tf
from tensorflow import keras
import tensorflow_datasets as tfds
import keras_cv
import wandb
from wandb_addons.keras.detection import visualize_dataset
import tensorflow as tf
from tensorflow import keras
import tensorflow_datasets as tfds
import keras_cv
import wandb
from wandb_addons.keras.detection import visualize_dataset
Initialize a Weights & Biases run and Set up the Configs¶
In [ ]:
Copied!
wandb.init(project="keras-community-days", job_type="visualization")
config = wandb.config
config.batch_size = 4
config.base_lr = 0.005
config.model_name = "retinanet_resnet50_pascalvoc"
config.momentum = 0.9
config.global_clipnorm = 10.0
class_ids = [
"Aeroplane",
"Bicycle",
"Bird",
"Boat",
"Bottle",
"Bus",
"Car",
"Cat",
"Chair",
"Cow",
"Dining Table",
"Dog",
"Horse",
"Motorbike",
"Person",
"Potted Plant",
"Sheep",
"Sofa",
"Train",
"Tvmonitor",
"Total",
]
config.class_mapping = dict(zip(range(len(class_ids)), class_ids))
wandb.init(project="keras-community-days", job_type="visualization")
config = wandb.config
config.batch_size = 4
config.base_lr = 0.005
config.model_name = "retinanet_resnet50_pascalvoc"
config.momentum = 0.9
config.global_clipnorm = 10.0
class_ids = [
"Aeroplane",
"Bicycle",
"Bird",
"Boat",
"Bottle",
"Bus",
"Car",
"Cat",
"Chair",
"Cow",
"Dining Table",
"Dog",
"Horse",
"Motorbike",
"Person",
"Potted Plant",
"Sheep",
"Sofa",
"Train",
"Tvmonitor",
"Total",
]
config.class_mapping = dict(zip(range(len(class_ids)), class_ids))
Load Pascal VOC Dataset¶
In [ ]:
Copied!
def unpackage_raw_tfds_inputs(inputs, bounding_box_format):
image = inputs["image"]
boxes = keras_cv.bounding_box.convert_format(
inputs["objects"]["bbox"],
images=image,
source="rel_yxyx",
target=bounding_box_format,
)
bounding_boxes = {
"classes": tf.cast(inputs["objects"]["label"], dtype=tf.float32),
"boxes": tf.cast(boxes, dtype=tf.float32),
}
return {
"images": tf.cast(image, tf.float32),
"bounding_boxes": bounding_boxes
}
def load_pascal_voc(split, dataset, bounding_box_format):
ds = tfds.load(dataset, split=split, with_info=False, shuffle_files=True)
ds = ds.map(
lambda x: unpackage_raw_tfds_inputs(
x, bounding_box_format=bounding_box_format
),
num_parallel_calls=tf.data.AUTOTUNE,
)
return ds
train_ds = load_pascal_voc(
split="train", dataset="voc/2007", bounding_box_format="xywh"
)
eval_ds = load_pascal_voc(split="test", dataset="voc/2007", bounding_box_format="xywh")
train_ds = train_ds.shuffle(config.batch_size * 4)
def unpackage_raw_tfds_inputs(inputs, bounding_box_format):
image = inputs["image"]
boxes = keras_cv.bounding_box.convert_format(
inputs["objects"]["bbox"],
images=image,
source="rel_yxyx",
target=bounding_box_format,
)
bounding_boxes = {
"classes": tf.cast(inputs["objects"]["label"], dtype=tf.float32),
"boxes": tf.cast(boxes, dtype=tf.float32),
}
return {
"images": tf.cast(image, tf.float32),
"bounding_boxes": bounding_boxes
}
def load_pascal_voc(split, dataset, bounding_box_format):
ds = tfds.load(dataset, split=split, with_info=False, shuffle_files=True)
ds = ds.map(
lambda x: unpackage_raw_tfds_inputs(
x, bounding_box_format=bounding_box_format
),
num_parallel_calls=tf.data.AUTOTUNE,
)
return ds
train_ds = load_pascal_voc(
split="train", dataset="voc/2007", bounding_box_format="xywh"
)
eval_ds = load_pascal_voc(split="test", dataset="voc/2007", bounding_box_format="xywh")
train_ds = train_ds.shuffle(config.batch_size * 4)
Visualize the Raw Dataset with Bounding Box Annotations¶
In [ ]:
Copied!
train_ds = train_ds.ragged_batch(config.batch_size, drop_remainder=True)
eval_ds = eval_ds.ragged_batch(config.batch_size, drop_remainder=True)
visualize_dataset(
dataset=train_ds,
class_mapping=config.class_mapping,
title="Train-Dataset",
max_batches_to_visualize=10,
)
visualize_dataset(
dataset=eval_ds,
class_mapping=config.class_mapping,
title="Eval-Dataset",
max_batches_to_visualize=10,
)
train_ds = train_ds.ragged_batch(config.batch_size, drop_remainder=True)
eval_ds = eval_ds.ragged_batch(config.batch_size, drop_remainder=True)
visualize_dataset(
dataset=train_ds,
class_mapping=config.class_mapping,
title="Train-Dataset",
max_batches_to_visualize=10,
)
visualize_dataset(
dataset=eval_ds,
class_mapping=config.class_mapping,
title="Eval-Dataset",
max_batches_to_visualize=10,
)
Visualize the Training Dataset with Augmentations¶
In [ ]:
Copied!
augmenter = keras.Sequential(
layers=[
keras_cv.layers.RandomFlip(mode="horizontal", bounding_box_format="xywh"),
keras_cv.layers.JitteredResize(
target_size=(640, 640), scale_factor=(0.75, 1.3), bounding_box_format="xywh"
),
]
)
train_ds = train_ds.map(augmenter, num_parallel_calls=tf.data.AUTOTUNE)
visualize_dataset(
dataset=train_ds,
class_mapping=config.class_mapping,
title="Augmented-Train-Dataset",
max_batches_to_visualize=10,
)
augmenter = keras.Sequential(
layers=[
keras_cv.layers.RandomFlip(mode="horizontal", bounding_box_format="xywh"),
keras_cv.layers.JitteredResize(
target_size=(640, 640), scale_factor=(0.75, 1.3), bounding_box_format="xywh"
),
]
)
train_ds = train_ds.map(augmenter, num_parallel_calls=tf.data.AUTOTUNE)
visualize_dataset(
dataset=train_ds,
class_mapping=config.class_mapping,
title="Augmented-Train-Dataset",
max_batches_to_visualize=10,
)
Visualize the Resized Validation Dataset¶
In [ ]:
Copied!
inference_resizing = keras_cv.layers.Resizing(
640, 640, bounding_box_format="xywh", pad_to_aspect_ratio=True
)
eval_ds = eval_ds.map(inference_resizing, num_parallel_calls=tf.data.AUTOTUNE)
visualize_dataset(
dataset=eval_ds,
class_mapping=config.class_mapping,
title="Resized-Train-Dataset",
max_batches_to_visualize=10,
)
inference_resizing = keras_cv.layers.Resizing(
640, 640, bounding_box_format="xywh", pad_to_aspect_ratio=True
)
eval_ds = eval_ds.map(inference_resizing, num_parallel_calls=tf.data.AUTOTUNE)
visualize_dataset(
dataset=eval_ds,
class_mapping=config.class_mapping,
title="Resized-Train-Dataset",
max_batches_to_visualize=10,
)
Prepare Dataset for Evaluation¶
In [ ]:
Copied!
def dict_to_tuple(inputs):
return inputs["images"], keras_cv.bounding_box.to_dense(
inputs["bounding_boxes"], max_boxes=32
)
train_ds = train_ds.map(dict_to_tuple, num_parallel_calls=tf.data.AUTOTUNE)
eval_ds = eval_ds.map(dict_to_tuple, num_parallel_calls=tf.data.AUTOTUNE)
train_ds = train_ds.prefetch(tf.data.AUTOTUNE)
eval_ds = eval_ds.prefetch(tf.data.AUTOTUNE)
def dict_to_tuple(inputs):
return inputs["images"], keras_cv.bounding_box.to_dense(
inputs["bounding_boxes"], max_boxes=32
)
train_ds = train_ds.map(dict_to_tuple, num_parallel_calls=tf.data.AUTOTUNE)
eval_ds = eval_ds.map(dict_to_tuple, num_parallel_calls=tf.data.AUTOTUNE)
train_ds = train_ds.prefetch(tf.data.AUTOTUNE)
eval_ds = eval_ds.prefetch(tf.data.AUTOTUNE)
Define the Pre-trained Model¶
In [ ]:
Copied!
pretrained_model = keras_cv.models.RetinaNet.from_preset(
config.model_name, bounding_box_format="xywh"
)
optimizer = keras.optimizers.SGD(
learning_rate=config.base_lr,
momentum=config.momentum,
global_clipnorm=config.global_clipnorm
)
coco_metrics = keras_cv.metrics.BoxCOCOMetrics(
bounding_box_format="xywh", evaluate_freq=20
)
pretrained_model.compile(
classification_loss="focal",
box_loss="smoothl1",
optimizer=optimizer,
metrics=[coco_metrics],
)
pretrained_model = keras_cv.models.RetinaNet.from_preset(
config.model_name, bounding_box_format="xywh"
)
optimizer = keras.optimizers.SGD(
learning_rate=config.base_lr,
momentum=config.momentum,
global_clipnorm=config.global_clipnorm
)
coco_metrics = keras_cv.metrics.BoxCOCOMetrics(
bounding_box_format="xywh", evaluate_freq=20
)
pretrained_model.compile(
classification_loss="focal",
box_loss="smoothl1",
optimizer=optimizer,
metrics=[coco_metrics],
)
Evaluate the Pre-trained Model on the Evaluation Dataset¶
In [ ]:
Copied!
coco_metrics.reset_state()
result = pretrained_model.evaluate(eval_ds.take(40))
result = coco_metrics.result(force=True)
wandb.log({f"Evaluation/{k}": v.numpy() for k, v in result.items()})
coco_metrics.reset_state()
result = pretrained_model.evaluate(eval_ds.take(40))
result = coco_metrics.result(force=True)
wandb.log({f"Evaluation/{k}": v.numpy() for k, v in result.items()})
In [ ]:
Copied!
# Finish the experiment
wandb.finish()
# Finish the experiment
wandb.finish()