Created
November 27, 2023 10:01
-
-
Save ritwikraha/861371ea9e2d855a01a19be172e5dd6e to your computer and use it in GitHub Desktop.
semantic_segmentation_deeplab_v3_plus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "view-in-github", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"<a href=\"https://colab.research.google.com/gist/ritwikraha/861371ea9e2d855a01a19be172e5dd6e/semantic_segmentation_deeplab_v3_plus.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "eD5lD7cHMTbh" | |
}, | |
"source": [ | |
"# Semantic Segmentation with KerasCV\n", | |
"\n", | |
"**Author:** [Divyashree Sreepathihalli](https://github.com/divyashreepathihalli), [Ian Stenbit](https://github.com/ianstenbit)<br>\n", | |
"**Date created:** 2023/08/22<br>\n", | |
"**Last modified:** 2023/08/24<br>\n", | |
"**Description:** Train and use DeepLabv3+ segmentation model with KerasCV." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "dQRuzRgAMTbj" | |
}, | |
"source": [ | |
"![](https://storage.googleapis.com/keras-nlp/getting_started_guide/prof_keras_intermediate.png)\n", | |
"\n", | |
"## Background\n", | |
"Semantic segmentation is a type of computer vision task that involves assigning a\n", | |
"class label such as person, bike, or background to each individual pixel of an\n", | |
"image, effectively dividing the image into regions that correspond to different\n", | |
"fobject classes or categories.\n", | |
"\n", | |
"![](https://miro.medium.com/v2/resize:fit:4800/format:webp/1*z6ch-2BliDGLIHpOPFY_Sw.png)\n", | |
"\n", | |
"\n", | |
"\n", | |
"KerasCV offers the DeepLabv3+ model developed by Google for semantic\n", | |
"segmentation. This guide demonstrates how to finetune and use DeepLabv3+ model for\n", | |
"image semantic segmentaion with KerasCV. Its architecture that combines atrous convolutions,\n", | |
"contextual information aggregation, and powerful backbones to achieve accurate and\n", | |
"detailed semantic segmentation. The DeepLabv3+ model has been shown to achieve\n", | |
"state-of-the-art results on a variety of image segmentation benchmarks.\n", | |
"\n", | |
"### References\n", | |
"[Encoder-Decoder with Atrous Separable Convolution for Semantic Image\n", | |
"Segmentation](https://arxiv.org/abs/1802.02611)<br>\n", | |
"[Rethinking Atrous Convolution for Semantic Image\n", | |
"Segmentation](https://arxiv.org/abs/1706.05587)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "GEj1dr36MTbj" | |
}, | |
"source": [ | |
"## Setup and Imports\n", | |
"\n", | |
"Let's install the dependencies and import the necessary modules.\n", | |
"\n", | |
"To run this tutorial, you will need to install the following packages:\n", | |
"\n", | |
"* `keras-cv`\n", | |
"* `keras-core`" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "dXRIcCCBMTbj", | |
"outputId": "5f273a4a-58ea-424a-f1b6-d399aa34723f" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
" Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n", | |
" Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n", | |
" Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n", | |
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m950.8/950.8 kB\u001b[0m \u001b[31m13.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", | |
"\u001b[?25h Building wheel for keras-cv (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n", | |
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m521.6/521.6 MB\u001b[0m \u001b[31m3.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", | |
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m4.8/4.8 MB\u001b[0m \u001b[31m106.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", | |
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m206.7/206.7 kB\u001b[0m \u001b[31m21.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", | |
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m5.5/5.5 MB\u001b[0m \u001b[31m107.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", | |
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m440.9/440.9 kB\u001b[0m \u001b[31m34.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", | |
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m996.8/996.8 kB\u001b[0m \u001b[31m65.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", | |
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.7/1.7 MB\u001b[0m \u001b[31m84.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", | |
"\u001b[?25h" | |
] | |
} | |
], | |
"source": [ | |
"!pip install -q git+https://github.com/keras-team/keras-cv.git@master\n", | |
"!pip uninstall -q keras -y\n", | |
"!pip uninstall -q tensorflow -y\n", | |
"!pip install -q tf-nightly # needed for some data processing in keras-cv\n", | |
"!pip install -q keras-nightly" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "qXT4HDXlMTbk" | |
}, | |
"source": [ | |
"After installing `keras-core` and `keras-cv`, set the backend for `keras-core`.\n", | |
"This guide can be run with any backend (Tensorflow, JAX, PyTorch).\n", | |
"\n", | |
"```\n", | |
"%env KERAS_BACKEND=tensorflow\n", | |
"```" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "w2JwNBlUMTbk", | |
"outputId": "69edd465-596b-4244-cbd9-46a4e273dab1" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"env: KERAS_BACKEND=tensorflow\n" | |
] | |
} | |
], | |
"source": [ | |
"%env KERAS_BACKEND=tensorflow\n", | |
"import keras\n", | |
"from keras import ops\n", | |
"\n", | |
"import keras_cv\n", | |
"import numpy as np\n", | |
"\n", | |
"from keras_cv.datasets.pascal_voc.segmentation import load as load_voc" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "swWE1dRSMTbk" | |
}, | |
"source": [ | |
"## Perform semantic segmentation with a pretrained DeepLabv3+ model\n", | |
"\n", | |
"The highest level API in the KerasCV semantic segmentation API is the `keras_cv.models`\n", | |
"API. This API includes fully pretrained semantic segmentation models, such as\n", | |
"`keras_cv.models.DeepLabV3Plus`.\n", | |
"\n", | |
"Let's get started by constructing a DeepLabv3+ pretrained on the pascalvoc dataset." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "8He8H_62MTbk", | |
"outputId": "d485f59a-b5a2-45ac-c7f8-4745711824c5" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Downloading data from https://storage.googleapis.com/keras-cv/models/deeplab_v3_plus/voc/deeplabv3plus_resenet50_pascal_voc.weights.h5\n", | |
"\u001b[1m313992688/313992688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 0us/step\n" | |
] | |
} | |
], | |
"source": [ | |
"model = keras_cv.models.DeepLabV3Plus.from_preset(\n", | |
" \"deeplab_v3_plus_resnet50_pascalvoc\",\n", | |
" num_classes=21,\n", | |
" input_shape=[512, 512, 3],\n", | |
")" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "f6xzoD7BMTbl" | |
}, | |
"source": [ | |
"Let us visualize the results of this pretrained model" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 207 | |
}, | |
"id": "OeIWUKHWMTbl", | |
"outputId": "336b702c-3a94-43cc-f164-e03106cd2535" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Downloading data from https://i.imgur.com/gCNcJJI.jpg\n", | |
"\u001b[1m1215963/1215963\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 0us/step\n" | |
] | |
}, | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": [ | |
"<Figure size 300x300 with 1 Axes>" | |
], | |
"image/png": "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\n" | |
}, | |
"metadata": {} | |
} | |
], | |
"source": [ | |
"filepath = keras.utils.get_file(origin=\"https://i.imgur.com/gCNcJJI.jpg\")\n", | |
"image = keras.utils.load_img(filepath)\n", | |
"\n", | |
"resize = keras_cv.layers.Resizing(height=512, width=512)\n", | |
"image = resize(image)\n", | |
"image = keras.ops.expand_dims(np.array(image), axis=0)\n", | |
"preds = ops.expand_dims(ops.argmax(model(image), axis=-1), axis=-1)\n", | |
"keras_cv.visualization.plot_segmentation_mask_gallery(\n", | |
" image,\n", | |
" value_range=(0, 255),\n", | |
" num_classes=1,\n", | |
" y_true=None,\n", | |
" y_pred=preds,\n", | |
" scale=3,\n", | |
" rows=1,\n", | |
" cols=1,\n", | |
")" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "QWxwFKfbMTbl" | |
}, | |
"source": [ | |
"## Train a custom semantic segmentation model\n", | |
"In this guide, we'll assemble a full training pipeline for a KerasCV DeepLabV3 semantic\n", | |
"segmentation model. This includes data loading, augmentation, training, metric\n", | |
"evaluation, and inference!" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "GaaEytkbMTbl" | |
}, | |
"source": [ | |
"## Download the data\n", | |
"\n", | |
"We download\n", | |
"[Pascal VOC dataset](https://www.eecs.berkeley.edu/Research/Projects/CS/vision/grouping/semantic_contours/benchmark.tgz)\n", | |
"with KerasCV datasets and split them into train dataset `train_ds` and `eval_ds`." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"id": "9a3bg8MCMTbl" | |
}, | |
"outputs": [], | |
"source": [ | |
"train_ds = load_voc(split=\"sbd_train\")\n", | |
"eval_ds = load_voc(split=\"sbd_eval\")" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "kUmoRx6qMTbl" | |
}, | |
"source": [ | |
"## Preprocess the data\n", | |
"\n", | |
"The `preprocess_tfds_inputs` utility function preprocesses the inputs to a dictionary of\n", | |
"`images` and `segmentation_masks`. The images and segmentation masks are resized to\n", | |
"512x512. The resulting dataset is then batched into groups of 4 image and segmentation\n", | |
"mask pairs.\n", | |
"\n", | |
"A batch of this preprocessed input training data can be visualized using the\n", | |
"`keras_cv.visualization.plot_segmentation_mask_gallery` function. This function takes a\n", | |
"batch of images and segmentation masks as input and displays them in a grid." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"id": "-qRYotAJMTbl" | |
}, | |
"outputs": [], | |
"source": [ | |
"\n", | |
"def preprocess_tfds_inputs(inputs):\n", | |
" def unpackage_tfds_inputs(tfds_inputs):\n", | |
" return {\n", | |
" \"images\": tfds_inputs[\"image\"],\n", | |
" \"segmentation_masks\": tfds_inputs[\"class_segmentation\"],\n", | |
" }\n", | |
" outputs = inputs.map(unpackage_tfds_inputs)\n", | |
" outputs = outputs.map(keras_cv.layers.Resizing(height=512, width=512))\n", | |
" outputs = outputs.batch(4, drop_remainder=True)\n", | |
" return outputs\n", | |
"\n", | |
"\n", | |
"train_ds = preprocess_tfds_inputs(train_ds)\n", | |
"batch = train_ds.take(1).get_single_element()\n", | |
"keras_cv.visualization.plot_segmentation_mask_gallery(\n", | |
" batch[\"images\"],\n", | |
" value_range=(0, 255),\n", | |
" num_classes=21, # The number of classes for the oxford iiit pet dataset. The VOC dataset also includes 1 class for the background.\n", | |
" y_true=batch[\"segmentation_masks\"],\n", | |
" scale=3,\n", | |
" rows=2,\n", | |
" cols=2,\n", | |
")" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "wRzsfez2MTbl" | |
}, | |
"source": [ | |
"The preprocessing is applied to the evaluation dataset `eval_ds`." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"id": "nzkGyrOoMTbl" | |
}, | |
"outputs": [], | |
"source": [ | |
"eval_ds = preprocess_tfds_inputs(eval_ds)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "DtbZrZXSMTbm" | |
}, | |
"source": [ | |
"## Data Augmentation\n", | |
"\n", | |
"KerasCV provides a variety of image augmentation options. In this example, we will use\n", | |
"the `RandomFlip` augmentation to augment the training dataset. The `RandomFlip`\n", | |
"augmentation randomly flips the images in the training dataset horizontally or\n", | |
"vertically. This can help to improve the model's robustness to changes in the orientation\n", | |
"of the objects in the images." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"id": "BGs6JqWbMTbm" | |
}, | |
"outputs": [], | |
"source": [ | |
"train_ds = train_ds.map(keras_cv.layers.RandomFlip())\n", | |
"batch = train_ds.take(1).get_single_element()\n", | |
"\n", | |
"keras_cv.visualization.plot_segmentation_mask_gallery(\n", | |
" batch[\"images\"],\n", | |
" value_range=(0, 255),\n", | |
" num_classes=21,\n", | |
" y_true=batch[\"segmentation_masks\"],\n", | |
" scale=3,\n", | |
" rows=2,\n", | |
" cols=2,\n", | |
")" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "ZaVgiXCcMTbm" | |
}, | |
"source": [ | |
"## Model Configuration\n", | |
"\n", | |
"Please feel free to modify the configurations for model training and note how the\n", | |
"training results changes. This is an great exercise to get a better understanding of the\n", | |
"training pipeline.\n", | |
"\n", | |
"The learning rate schedule is used by the optimizer to calculate the learning rate for\n", | |
"each epoch. The optimizer then uses the learning rate to update the weights of the model.\n", | |
"In this case, the learning rate schedule uses a cosine decay function. A cosine decay\n", | |
"function starts high and then decreases over time, eventually reaching zero. The\n", | |
"cardinality of the VOC dataset is 2124 with a batch size of 4. The dataset cardinality\n", | |
"is important for learning rate decay because it determines how many steps the model\n", | |
"will train for. The initial learning rate is proportional to 0.007 and the decay\n", | |
"steps are 2124. This means that the learning rate will start at `INITIAL_LR` and then\n", | |
"decrease to zero over 2124 steps.\n", | |
"![png](/img/guides/semantic_segmentation_deeplab_v3_plus/learning_rate_schedule.png)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"id": "jc5Q5H6EMTbm" | |
}, | |
"outputs": [], | |
"source": [ | |
"BATCH_SIZE = 4\n", | |
"INITIAL_LR = 0.007 * BATCH_SIZE / 16\n", | |
"EPOCHS = 1\n", | |
"NUM_CLASSES = 21\n", | |
"learning_rate = keras.optimizers.schedules.CosineDecay(\n", | |
" INITIAL_LR,\n", | |
" decay_steps=EPOCHS * 2124,\n", | |
")" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "bXHKq8AiMTbm" | |
}, | |
"source": [ | |
"We instantiate a DeepLabV3+ model with a ResNet50 backbone pretrained on ImageNet classification:\n", | |
"`resnet50_v2_imagenet` pre-trained weights will be used as the backbone feature\n", | |
"extractor for the DeepLabV3Plus model. The `num_classes` parameter specifies the number of\n", | |
"classes that the model will be trained to segment." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"id": "Nl1JQBNdMTbm" | |
}, | |
"outputs": [], | |
"source": [ | |
"model = keras_cv.models.DeepLabV3Plus.from_preset(\n", | |
" \"resnet50_v2_imagenet\", num_classes=NUM_CLASSES\n", | |
")\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "XNZgIxxEMTbm" | |
}, | |
"source": [ | |
"## Compile the model\n", | |
"\n", | |
"The model.compile() function sets up the training process for the model. It defines the\n", | |
"- optimization algorithm - Stochastic Gradient Descent (SGD)\n", | |
"- the loss function - categorical cross-entropy\n", | |
"- the evaluation metrics - Mean IoU and categorical accuracy\n", | |
"\n", | |
"Semantic segmentation evaluation metrics:\n", | |
"\n", | |
"Mean Intersection over Union (MeanIoU):\n", | |
"MeanIoU measures how well a semantic segmentation model accurately identifies\n", | |
"and delineates different objects or regions in an image. It calculates the\n", | |
"overlap between predicted and actual object boundaries, providing a score\n", | |
"between 0 and 1, where 1 represents a perfect match.\n", | |
"\n", | |
"Categorical Accuracy:\n", | |
"Categorical Accuracy measures the proportion of correctly classified pixels in\n", | |
"an image. It gives a simple percentage indicating how accurately the model\n", | |
"predicts the categories of pixels in the entire image.\n", | |
"\n", | |
"In essence, MeanIoU emphasizes the accuracy of identifying specific object\n", | |
"boundaries, while Categorical Accuracy gives a broad overview of overall\n", | |
"pixel-level correctness." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"id": "XM37SZuIMTbm" | |
}, | |
"outputs": [], | |
"source": [ | |
"model.compile(\n", | |
" optimizer=keras.optimizers.SGD(\n", | |
" learning_rate=learning_rate, weight_decay=0.0001, momentum=0.9, clipnorm=10.0\n", | |
" ),\n", | |
" loss=keras.losses.CategoricalCrossentropy(from_logits=False),\n", | |
" metrics=[\n", | |
" keras.metrics.MeanIoU(\n", | |
" num_classes=NUM_CLASSES, sparse_y_true=False, sparse_y_pred=False\n", | |
" ),\n", | |
" keras.metrics.CategoricalAccuracy(),\n", | |
" ],\n", | |
")\n", | |
"\n", | |
"model.summary()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "U1GrZYVFMTbm" | |
}, | |
"source": [ | |
"The utility function `dict_to_tuple` effectively transforms the dictionaries of training\n", | |
"and validation datasets into tuples of images and one-hot encoded segmentation masks,\n", | |
"which is used during training and evaluation of the DeepLabv3+ model." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"id": "ziwRs8YiMTbm" | |
}, | |
"outputs": [], | |
"source": [ | |
"\n", | |
"def dict_to_tuple(x):\n", | |
" return x[\"images\"], ops.one_hot(\n", | |
" ops.cast(ops.squeeze(x[\"segmentation_masks\"], axis=-1), \"int32\"), 21\n", | |
" )\n", | |
"\n", | |
"\n", | |
"train_ds = train_ds.map(dict_to_tuple)\n", | |
"eval_ds = eval_ds.map(dict_to_tuple)\n", | |
"\n", | |
"model.fit(train_ds, validation_data=eval_ds, epochs=EPOCHS)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "z3JNtXRAMTbm" | |
}, | |
"source": [ | |
"## Predictions with trained model\n", | |
"Now that the model training of DeepLabv3+ has completed, let's test it by making\n", | |
"predications\n", | |
"on a few sample images." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"id": "WmwjkuuEMTbm" | |
}, | |
"outputs": [], | |
"source": [ | |
"test_ds = load_voc(split=\"sbd_eval\")\n", | |
"test_ds = preprocess_tfds_inputs(test_ds)\n", | |
"\n", | |
"images, masks = next(iter(train_ds.take(1)))\n", | |
"preds = ops.expand_dims(ops.argmax(model(images), axis=-1), axis=-1)\n", | |
"masks = ops.expand_dims(ops.argmax(masks, axis=-1), axis=-1)\n", | |
"\n", | |
"keras_cv.visualization.plot_segmentation_mask_gallery(\n", | |
" images,\n", | |
" value_range=(0, 255),\n", | |
" num_classes=21,\n", | |
" y_true=masks,\n", | |
" y_pred=preds,\n", | |
" scale=3,\n", | |
" rows=1,\n", | |
" cols=4,\n", | |
")\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "9fljj-rMMTbm" | |
}, | |
"source": [ | |
"Here are some additional tips for using the KerasCV DeepLabv3+ model:\n", | |
"\n", | |
"- The model can be trained on a variety of datasets, including the COCO dataset, the\n", | |
"PASCAL VOC dataset, and the Cityscapes dataset.\n", | |
"- The model can be fine-tuned on a custom dataset to improve its performance on a\n", | |
"specific task.\n", | |
"- The model can be used to perform real-time inference on images.\n", | |
"- Also, try out KerasCV's SegFormer model `keras_cv.models.segmentation.SegFormer`. The\n", | |
"SegFormer model is a newer model that has been shown to achieve state-of-the-art results\n", | |
"on a variety of image segmentation benchmarks. It is based on the Swin Transformer\n", | |
"architecture, and it is more efficient and accurate than previous image segmentation\n", | |
"models." | |
] | |
} | |
], | |
"metadata": { | |
"accelerator": "GPU", | |
"colab": { | |
"name": "semantic_segmentation_deeplab_v3_plus", | |
"provenance": [], | |
"toc_visible": true, | |
"include_colab_link": true | |
}, | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.7.0" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment