From 4fc55958b1360e893a5a4073c6f4b4589af9b2b6 Mon Sep 17 00:00:00 2001 From: shayaharon Date: Mon, 13 Nov 2023 11:03:18 +0200 Subject: [PATCH] final touches --- notebooks/quickstart_segmentation.ipynb | 1 - .../segmentation_connect_custom_dataset.ipynb | 1941 ++++++++--------- ...nsfer_learning_semantic_segmentation.ipynb | 1 - 3 files changed, 970 insertions(+), 973 deletions(-) diff --git a/notebooks/quickstart_segmentation.ipynb b/notebooks/quickstart_segmentation.ipynb index 63150b51c5..13798e9e3a 100644 --- a/notebooks/quickstart_segmentation.ipynb +++ b/notebooks/quickstart_segmentation.ipynb @@ -145,7 +145,6 @@ ], "source": [ "! pip install -qq super-gradients==3.4.1\n", - "\n", "! pip install -qq prettyformatter\n" ] }, diff --git a/notebooks/segmentation_connect_custom_dataset.ipynb b/notebooks/segmentation_connect_custom_dataset.ipynb index 2e3b465b5b..1e2d55dad4 100644 --- a/notebooks/segmentation_connect_custom_dataset.ipynb +++ b/notebooks/segmentation_connect_custom_dataset.ipynb @@ -1,980 +1,979 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "sh6t_y7KzqBH" - }, - "source": [ - "![SG - Horizontal.png](data:image/png;base64,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)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "5aISf1B-AGDQ" - }, - "source": [ - "# SuperGradients Semantic Segmentation How to Connect Custom Dataset\n", - "\n", - "In this tutorial we will explore how you can connect your custom Semantic Segmentation dataset to SG.\n", - "\n", - "Since SG trainer is fully compatible with PyTorch data loaders, we will demonstrate how to build one and use it.\n", - "\n", - "The notebook is divided into 5 sections:\n", - "1. Experiment setup\n", - "2. Dataset definition: create a proxy dataset and create a dataloader\n", - "3. Architecture definition: pre-trained PPLiteSeg on Cityscapes \n", - "4. Training setup\n", - "5. Training and Evaluation\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "-1nPOPmc1lGp" - }, - "source": [ - "#Install SG" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "VAssbjJw7Yt1" - }, - "source": [ - "The cell below will install **super_gradients** which will automatically get all its dependencies. Let's import all the installed libraries to make sure they installed succesfully." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "JKce1SM6voVH", - "outputId": "a6397510-a140-443f-f13c-eec1272cc1a8" - }, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Requirement already satisfied: torch in /usr/local/lib/python3.10/dist-packages (2.1.0+cu118)\n", - "Requirement already satisfied: torchvision in /usr/local/lib/python3.10/dist-packages (0.16.0+cu118)\n", - "Requirement already satisfied: torchaudio in /usr/local/lib/python3.10/dist-packages (2.1.0+cu118)\n", - "Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from torch) (3.13.1)\n", - "Requirement already satisfied: typing-extensions in /usr/local/lib/python3.10/dist-packages (from torch) (4.5.0)\n", - "Requirement already satisfied: sympy in /usr/local/lib/python3.10/dist-packages (from torch) (1.12)\n", - "Requirement already satisfied: networkx in /usr/local/lib/python3.10/dist-packages (from torch) (3.2.1)\n", - "Requirement already satisfied: jinja2 in /usr/local/lib/python3.10/dist-packages (from torch) (3.1.2)\n", - "Requirement already satisfied: fsspec in /usr/local/lib/python3.10/dist-packages (from torch) (2023.6.0)\n", - "Requirement already satisfied: triton==2.1.0 in /usr/local/lib/python3.10/dist-packages (from torch) (2.1.0)\n", - "Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from torchvision) (1.23.5)\n", - "Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from torchvision) (2.31.0)\n", - "Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in /usr/local/lib/python3.10/dist-packages (from torchvision) (9.4.0)\n", - "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2->torch) (2.1.3)\n", - "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->torchvision) (3.3.2)\n", - "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->torchvision) (3.4)\n", - "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->torchvision) (2.0.7)\n", - "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->torchvision) (2023.7.22)\n", - "Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.10/dist-packages (from sympy->torch) (1.3.0)\n", - " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " 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", - " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Building wheel for pycocotools (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n", - " Building wheel for termcolor (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Building wheel for treelib (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Building wheel for coverage (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Building wheel for xhtml2pdf (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Building wheel for antlr4-python3-runtime (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Building wheel for stringcase (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Building wheel for svglib (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", - "lida 0.0.10 requires fastapi, which is not installed.\n", - "lida 0.0.10 requires kaleido, which is not installed.\n", - "lida 0.0.10 requires python-multipart, which is not installed.\n", - "lida 0.0.10 requires uvicorn, which is not installed.\n", - "tensorflow 2.14.0 requires numpy>=1.23.5, but you have numpy 1.23.0 which is incompatible.\u001b[0m\u001b[31m\n", - "\u001b[0m" - ] - } - ], - "source": [ - "! pip install torch torchvision torchaudio\n", - "! pip install -qq super-gradients==3.4.1\n", - "! pip install -qq prettyformatter" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "njthhNJR1pJm" - }, - "source": [ - "# 1. Experiment setup" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "YPym4wvpOcOJ" - }, - "source": [ - "We will first initialize our **trainer** which will be in charge of everything, like training, evaluation, saving checkpoints, plotting etc.\n", - "\n", - "The **experiment name** argument is important as every checkpoints, logs and tensorboards to be saved in a directory with the same name. This directory will be created as a sub-directory of **ckpt_root_dir** as follow:\n", - "\n", - "```\n", - "ckpt_root_dir\n", - "|─── experiment_name_1\n", - "│ ckpt_best.pth # Model checkpoint on best epoch\n", - "│ ckpt_latest.pth # Model checkpoint on last epoch\n", - "│ average_model.pth # Model checkpoint averaged over epochs\n", - "│ events.out.tfevents.1659878383... # Tensorflow artifacts of a specific run\n", - "│ log_Aug07_11_52_48.txt # Trainer logs of a specific run\n", - "└─── experiment_name_2\n", - " ...\n", - "```\n", - "In this notebook multi-gpu training is set as `OFF`, for Distributed training multi_gpu can be set as\n", - " `MultiGPUMode.DISTRIBUTED_DATA_PARALLEL` or `MultiGPUMode.DATA_PARALLEL`.\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "A2PlnTWpimnH" - }, - "source": [ - "Let's define **ckpt_root_dir** inside the Colab, later we can use it to start TensorBoard and monitor the run." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "id": "_v1N3kXs3wo1" - }, - "outputs": [], - "source": [ - "from super_gradients.training import Trainer, MultiGPUMode\n", - "\n", - "\n", - "CHECKPOINT_DIR = '/home/notebook_ckpts/'\n", - "trainer = Trainer(experiment_name='transfer_learning_semantic_segementation_ppLite', ckpt_root_dir=CHECKPOINT_DIR)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "J9ZaMulSvwhr" - }, - "source": [ - "# 2. Dataset definition\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "_1TXuJKkKzFJ" - }, - "source": [ - "## 2.A Generate Proxy Dataset" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "Y7us7VHRig7M" - }, - "source": [ - "\n", - "A proxy dataset generation is available merely to demonstrate an end-to-end training pipeline in this notebook.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "id": "wbdVYnIyjgv-" - }, - "outputs": [], - "source": [ - "from PIL import Image\n", - "import os\n", - "import numpy as np\n", - "\n", - "\n", - "# creation of proxy dataset to demonstrate usage\n", - "def generate_proxy_dataset(write_path: str, num_samples: int, num_classes: int, img_size: int = 256):\n", - " # Create training files and text\n", - " os.makedirs(os.path.join(write_path, 'images', 'train'), exist_ok=True)\n", - " os.makedirs(os.path.join(write_path, 'images', 'val'), exist_ok=True)\n", - " os.makedirs(os.path.join(write_path, 'labels', 'train'), exist_ok=True)\n", - " os.makedirs(os.path.join(write_path, 'labels', 'val'), exist_ok=True)\n", - "\n", - " train_fp = open(os.path.join(write_path, 'train.txt'), 'w')\n", - " val_fp = open(os.path.join(write_path, 'val.txt'), 'w')\n", - "\n", - " # Create random samples\n", - " for n in range(num_samples):\n", - " img = np.random.rand(img_size, img_size, 3) * 255\n", - " img = Image.fromarray(img.astype('uint8')).convert('RGB')\n", - "\n", - " lbl = np.random.randint(0, num_classes, size=(img_size, img_size))\n", - " lbl = Image.fromarray(lbl.astype('uint8')).convert('L')\n", - "\n", - " im_string = '%000d.jpg' % n\n", - " lbl_string = '%000d.png' % n\n", - "\n", - " img_train_fn = os.path.join(write_path, 'images', 'train', im_string)\n", - " img_val_fn = img_train_fn.replace(\"train\", \"val\")\n", - " img.save(img_train_fn)\n", - " img.save(img_val_fn)\n", - "\n", - " lbl_train_fn = os.path.join(write_path, 'labels', 'train', lbl_string)\n", - " lbl_val_fn = lbl_train_fn.replace(\"train\", \"val\")\n", - " lbl.save(lbl_train_fn)\n", - " lbl.save(lbl_val_fn)\n", - "\n", - " train_fp.write(f\"{img_train_fn} {lbl_train_fn}\\n\")\n", - " val_fp.write(f\"{img_val_fn} {lbl_val_fn}\\n\")\n", - "\n", - " train_fp.close()\n", - " val_fp.close()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "id": "DXu4yfuZoiv0", - "colab": { - "base_uri": "https://localhost:8080/" - }, - "outputId": "dccaf4ba-159f-4a47-d13d-ba4b60eaac80" - }, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Train file `train.txt` content: \n", - "/content/example_data/images/train/0.jpg /content/example_data/labels/train/0.png\n", - "/content/example_data/images/train/1.jpg /content/example_data/labels/train/1.png\n", - "/content/example_data/images/train/2.jpg /content/example_data/labels/train/2.png\n", - "/content/example_data/images/train/3.jpg /content/example_data/labels/train/3.png\n", - "/content/example_data/images/train/4.jpg /content/example_data/labels/train/4.png\n", - "/content/example_data/images/train/5.jpg /content/example_data/labels/train/5.png\n", - "/content/example_data/images/train/6.jpg /content/example_data/labels/train/6.png\n", - "/content/example_data/images/train/7.jpg /content/example_data/labels/train/7.png\n", - "/content/example_data/images/train/8.jpg /content/example_data/labels/train/8.png\n", - "/content/example_data/images/train/9.jpg /content/example_data/labels/train/9.png\n" - ] - } - ], - "source": [ - "num_classes = 10\n", - "generate_proxy_dataset('/content/example_data', num_samples=10, num_classes=num_classes)\n", - "\n", - "print(\"Train file `train.txt` content: \")\n", - "! cat /content/example_data/train.txt" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "MDksFYrIqClt" - }, - "source": [ - "## 2.B Create Torch Dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "id": "AGziBKSIqaUu" - }, - "outputs": [], - "source": [ - "import torch\n", - "from torch.utils.data import Dataset\n", - "from torchvision import transforms, utils\n", - "\n", - "\n", - "class CustomDataset(Dataset):\n", - " \"\"\"\n", - " A PyTorch Dataset class to be used in a PyTorch DataLoader to create batches.\n", - " \"\"\"\n", - "\n", - " def __init__(self, data_folder, split):\n", - " \"\"\"\n", - " :param data_folder: folder where data files are stored\n", - " :param split: split, one of 'TRAIN' or 'TEST'\n", - " \"\"\"\n", - " self.data_folder = data_folder\n", - " self.split = split.lower()\n", - " assert self.split in {'train', 'val'}\n", - "\n", - " # Read data files\n", - " with open(os.path.join(data_folder, self.split + '.txt'), 'r') as f:\n", - " data_lines = f.readlines()\n", - " self.samples_fn = [line.strip().split(\" \") for line in data_lines]\n", - "\n", - " self.transforms = transforms.Compose([transforms.ToTensor()])\n", - "\n", - " def __getitem__(self, i):\n", - " # Read image and label\n", - " image = Image.open(self.samples_fn[i][0]).convert('RGB')\n", - " label = Image.open(self.samples_fn[i][1])\n", - "\n", - " image_tensor = self.transforms(image)\n", - " label_tensor = torch.from_numpy(np.array(label)).long()\n", - "\n", - " return image_tensor, label_tensor\n", - "\n", - "\n", - " def __len__(self):\n", - " return len(self.samples_fn)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "id": "2B0hlas_1Rh-" - }, - "outputs": [], - "source": [ - "train_dataset = CustomDataset(\"/content/example_data\", split=\"train\")\n", - "val_dataset = CustomDataset(\"/content/example_data\", split=\"val\")\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "eIG5tsiuor9E" - }, - "source": [ - "Let's have a look at the first sample:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "id": "ZsHqcq1jpN0F", - "colab": { - "base_uri": "https://localhost:8080/" - }, - "outputId": "e9c1182a-5359-45b6-c0f3-ad430a4fc67d" - }, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "torch.Size([3, 256, 256]) torch.Size([256, 256])\n", - "tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n" - ] - } - ], - "source": [ - "img, lbl = train_dataset[0]\n", - "print(img.shape, lbl.shape)\n", - "print(torch.unique(lbl))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "aWfFrYLzo9j8" - }, - "source": [ - "## 2.C Create Torch Dataloader" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "D3ThxDIopDDB" - }, - "source": [] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "id": "XrWjWfjXnw_r" - }, - "outputs": [], - "source": [ - "from torch.utils.data import Dataset, DataLoader\n", - "\n", - "train_dataloader = DataLoader(train_dataset, batch_size=4, shuffle=True, num_workers=2)\n", - "val_dataloader = DataLoader(val_dataset, batch_size=4, shuffle=False, num_workers=2)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "vB1sGPO8qwZJ" - }, - "source": [ - "Lets' have a look at the first batch:\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "id": "O-KuZQ3XBduM", - "colab": { - "base_uri": "https://localhost:8080/" - }, - "outputId": "489fc05e-f972-464d-c150-360e4f2dbd7e" - }, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "torch.Size([4, 3, 256, 256])" - ] - }, - "metadata": {}, - "execution_count": 10 - } - ], - "source": [ - "next(iter(train_dataloader))[0].shape" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "fFfvyMHU32QF" - }, - "source": [ - "\n", - "# 3. Architecture definition" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "EpqgjQjl4awr" - }, - "source": [ - "SG includes implementations of many different architectures for object detection tasks that can be found [here](https://github.com/Deci-AI/super-gradients#implemented-model-architectures)." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "GNM64JAa4sbF" - }, - "source": [ - "Create a PPLiteSeg nn.Module, with 1 class segmentation head classifier. For simplicity `use_aux_head` is set as `False`\n", - "and extra Auxiliary heads aren't used for training.\n", - "\n", - "Other segmentation modules can be used for this task such as, DDRNet, STDC and RegSeg.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "id": "YDK4btf04Gbu", - "colab": { - "base_uri": "https://localhost:8080/" - }, - "outputId": "cc7f1ab1-3a01-49c1-c9a2-6ca434dcc192" - }, - "outputs": [ - { - "output_type": "stream", - "name": "stderr", - "text": [ - "Downloading: \"https://sghub.deci.ai/models/pp_lite_t_seg75_cityscapes.pth\" to /root/.cache/torch/hub/checkpoints/pp_lite_t_seg75_cityscapes.pth\n", - "100%|██████████| 31.4M/31.4M [00:01<00:00, 32.4MB/s]\n", - "[2023-11-12 14:41:45] INFO - checkpoint_utils.py - Successfully loaded pretrained weights for architecture pp_lite_t_seg75\n" - ] - } - ], - "source": [ - "from super_gradients.training import models\n", - "from super_gradients.common.object_names import Models\n", - "\n", - "model = models.get(model_name=Models.PP_LITE_T_SEG75,\n", - " arch_params={\"use_aux_heads\": False},\n", - " num_classes=num_classes,\n", - " pretrained_weights=\"cityscapes\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "40UcYJ3u5JyF" - }, - "source": [ - "That being said, SG allows you to use one of SG implemented architectures or your custom architecture, as long as it inherits torch.nn.Module." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "LYPVR-XM4GsZ" - }, - "source": [ - "# 4. Training setup\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "6K_56lDV8azX" - }, - "source": [ - "\n", - "Here we define the training recipe. The full parameters can be found here [training parameters supported](https://deci-ai.github.io/super-gradients/user_guide.html#training-parameters).\n" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "id": "3eRe0hBz4G1n" - }, - "outputs": [], - "source": [ - "from super_gradients.training.metrics.segmentation_metrics import IoU\n", - "from super_gradients.training.utils.callbacks import BinarySegmentationVisualizationCallback, Phase\n", - "\n", - "\n", - "train_params = {\"max_epochs\": 10,\n", - " \"lr_mode\": \"cosine\",\n", - " \"initial_lr\": 0.005,\n", - " \"optimizer\": \"SGD\",\n", - " \"loss\": \"cross_entropy\",\n", - " \"average_best_models\": False,\n", - " \"metric_to_watch\": \"IoU\",\n", - " \"greater_metric_to_watch_is_better\": True,\n", - " \"train_metrics_list\": [IoU(num_classes=10)],\n", - " \"valid_metrics_list\": [IoU(num_classes=10)],\n", - " \"loss_logging_items_names\": [\"loss\"],\n", - " \"phase_callbacks\": [BinarySegmentationVisualizationCallback(phase=Phase.VALIDATION_BATCH_END,\n", - " freq=1,\n", - " last_img_idx_in_batch=4)],\n", - "\n", - " }" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "D3tVVUhy4OqP" - }, - "source": [ - "# 5. Training and evaluation\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "8tKUuxbe9NlQ" - }, - "source": [ - "The logs and the checkpoint for the latest epoch will be kept in your experiment folder.\n", - "\n", - "To start training we'll call train(...) and provide it with the objects we construted above: the model, the training parameters and the data loaders." - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "sh6t_y7KzqBH" + }, + "source": [ + "![SG - Horizontal.png](data:image/png;base64,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)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5aISf1B-AGDQ" + }, + "source": [ + "# SuperGradients Semantic Segmentation How to Connect Custom Dataset\n", + "\n", + "In this tutorial we will explore how you can connect your custom Semantic Segmentation dataset to SG.\n", + "\n", + "Since SG trainer is fully compatible with PyTorch data loaders, we will demonstrate how to build one and use it.\n", + "\n", + "The notebook is divided into 5 sections:\n", + "1. Experiment setup\n", + "2. Dataset definition: create a proxy dataset and create a dataloader\n", + "3. Architecture definition: pre-trained PPLiteSeg on Cityscapes \n", + "4. Training setup\n", + "5. Training and Evaluation\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-1nPOPmc1lGp" + }, + "source": [ + "#Install SG" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VAssbjJw7Yt1" + }, + "source": [ + "The cell below will install **super_gradients** which will automatically get all its dependencies. Let's import all the installed libraries to make sure they installed succesfully." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "JKce1SM6voVH", + "outputId": "a6397510-a140-443f-f13c-eec1272cc1a8" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Requirement already satisfied: torch in /usr/local/lib/python3.10/dist-packages (2.1.0+cu118)\n", + "Requirement already satisfied: torchvision in /usr/local/lib/python3.10/dist-packages (0.16.0+cu118)\n", + "Requirement already satisfied: torchaudio in /usr/local/lib/python3.10/dist-packages (2.1.0+cu118)\n", + "Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from torch) (3.13.1)\n", + "Requirement already satisfied: typing-extensions in /usr/local/lib/python3.10/dist-packages (from torch) (4.5.0)\n", + "Requirement already satisfied: sympy in /usr/local/lib/python3.10/dist-packages (from torch) (1.12)\n", + "Requirement already satisfied: networkx in /usr/local/lib/python3.10/dist-packages (from torch) (3.2.1)\n", + "Requirement already satisfied: jinja2 in /usr/local/lib/python3.10/dist-packages (from torch) (3.1.2)\n", + "Requirement already satisfied: fsspec in /usr/local/lib/python3.10/dist-packages (from torch) (2023.6.0)\n", + "Requirement already satisfied: triton==2.1.0 in /usr/local/lib/python3.10/dist-packages (from torch) (2.1.0)\n", + "Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from torchvision) (1.23.5)\n", + "Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from torchvision) (2.31.0)\n", + "Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in /usr/local/lib/python3.10/dist-packages (from torchvision) (9.4.0)\n", + "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2->torch) (2.1.3)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->torchvision) (3.3.2)\n", + "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->torchvision) (3.4)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->torchvision) (2.0.7)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->torchvision) (2023.7.22)\n", + "Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.10/dist-packages (from sympy->torch) (1.3.0)\n", + " Preparing metadata (setup.py) ... \u001B[?25l\u001B[?25hdone\n", + " 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", + " Preparing metadata (setup.py) ... \u001B[?25l\u001B[?25hdone\n", + " Preparing metadata (setup.py) ... \u001B[?25l\u001B[?25hdone\n", + " Preparing metadata (setup.py) ... \u001B[?25l\u001B[?25hdone\n", + " Preparing metadata (setup.py) ... \u001B[?25l\u001B[?25hdone\n", + " Preparing metadata (setup.py) ... \u001B[?25l\u001B[?25hdone\n", + " Preparing metadata (setup.py) ... \u001B[?25l\u001B[?25hdone\n", + " Building wheel for pycocotools (pyproject.toml) ... \u001B[?25l\u001B[?25hdone\n", + " Building wheel for termcolor (setup.py) ... \u001B[?25l\u001B[?25hdone\n", + " Building wheel for treelib (setup.py) ... \u001B[?25l\u001B[?25hdone\n", + " Building wheel for coverage (setup.py) ... \u001B[?25l\u001B[?25hdone\n", + " Building wheel for xhtml2pdf (setup.py) ... \u001B[?25l\u001B[?25hdone\n", + " Building wheel for antlr4-python3-runtime (setup.py) ... \u001B[?25l\u001B[?25hdone\n", + " Building wheel for stringcase (setup.py) ... \u001B[?25l\u001B[?25hdone\n", + " Building wheel for svglib (setup.py) ... \u001B[?25l\u001B[?25hdone\n", + "\u001B[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", + "lida 0.0.10 requires fastapi, which is not installed.\n", + "lida 0.0.10 requires kaleido, which is not installed.\n", + "lida 0.0.10 requires python-multipart, which is not installed.\n", + "lida 0.0.10 requires uvicorn, which is not installed.\n", + "tensorflow 2.14.0 requires numpy>=1.23.5, but you have numpy 1.23.0 which is incompatible.\u001B[0m\u001B[31m\n", + "\u001B[0m" + ] + } + ], + "source": [ + "! pip install -qq super-gradients==3.4.1\n", + "! pip install -qq prettyformatter" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "njthhNJR1pJm" + }, + "source": [ + "# 1. Experiment setup" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YPym4wvpOcOJ" + }, + "source": [ + "We will first initialize our **trainer** which will be in charge of everything, like training, evaluation, saving checkpoints, plotting etc.\n", + "\n", + "The **experiment name** argument is important as every checkpoints, logs and tensorboards to be saved in a directory with the same name. This directory will be created as a sub-directory of **ckpt_root_dir** as follow:\n", + "\n", + "```\n", + "ckpt_root_dir\n", + "|─── experiment_name_1\n", + "│ ckpt_best.pth # Model checkpoint on best epoch\n", + "│ ckpt_latest.pth # Model checkpoint on last epoch\n", + "│ average_model.pth # Model checkpoint averaged over epochs\n", + "│ events.out.tfevents.1659878383... # Tensorflow artifacts of a specific run\n", + "│ log_Aug07_11_52_48.txt # Trainer logs of a specific run\n", + "└─── experiment_name_2\n", + " ...\n", + "```\n", + "In this notebook multi-gpu training is set as `OFF`, for Distributed training multi_gpu can be set as\n", + " `MultiGPUMode.DISTRIBUTED_DATA_PARALLEL` or `MultiGPUMode.DATA_PARALLEL`.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A2PlnTWpimnH" + }, + "source": [ + "Let's define **ckpt_root_dir** inside the Colab, later we can use it to start TensorBoard and monitor the run." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "_v1N3kXs3wo1" + }, + "outputs": [], + "source": [ + "from super_gradients.training import Trainer, MultiGPUMode\n", + "\n", + "\n", + "CHECKPOINT_DIR = '/home/notebook_ckpts/'\n", + "trainer = Trainer(experiment_name='transfer_learning_semantic_segementation_ppLite', ckpt_root_dir=CHECKPOINT_DIR)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J9ZaMulSvwhr" + }, + "source": [ + "# 2. Dataset definition\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_1TXuJKkKzFJ" + }, + "source": [ + "## 2.A Generate Proxy Dataset" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Y7us7VHRig7M" + }, + "source": [ + "\n", + "A proxy dataset generation is available merely to demonstrate an end-to-end training pipeline in this notebook.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "id": "wbdVYnIyjgv-" + }, + "outputs": [], + "source": [ + "from PIL import Image\n", + "import os\n", + "import numpy as np\n", + "\n", + "\n", + "# creation of proxy dataset to demonstrate usage\n", + "def generate_proxy_dataset(write_path: str, num_samples: int, num_classes: int, img_size: int = 256):\n", + " # Create training files and text\n", + " os.makedirs(os.path.join(write_path, 'images', 'train'), exist_ok=True)\n", + " os.makedirs(os.path.join(write_path, 'images', 'val'), exist_ok=True)\n", + " os.makedirs(os.path.join(write_path, 'labels', 'train'), exist_ok=True)\n", + " os.makedirs(os.path.join(write_path, 'labels', 'val'), exist_ok=True)\n", + "\n", + " train_fp = open(os.path.join(write_path, 'train.txt'), 'w')\n", + " val_fp = open(os.path.join(write_path, 'val.txt'), 'w')\n", + "\n", + " # Create random samples\n", + " for n in range(num_samples):\n", + " img = np.random.rand(img_size, img_size, 3) * 255\n", + " img = Image.fromarray(img.astype('uint8')).convert('RGB')\n", + "\n", + " lbl = np.random.randint(0, num_classes, size=(img_size, img_size))\n", + " lbl = Image.fromarray(lbl.astype('uint8')).convert('L')\n", + "\n", + " im_string = '%000d.jpg' % n\n", + " lbl_string = '%000d.png' % n\n", + "\n", + " img_train_fn = os.path.join(write_path, 'images', 'train', im_string)\n", + " img_val_fn = img_train_fn.replace(\"train\", \"val\")\n", + " img.save(img_train_fn)\n", + " img.save(img_val_fn)\n", + "\n", + " lbl_train_fn = os.path.join(write_path, 'labels', 'train', lbl_string)\n", + " lbl_val_fn = lbl_train_fn.replace(\"train\", \"val\")\n", + " lbl.save(lbl_train_fn)\n", + " lbl.save(lbl_val_fn)\n", + "\n", + " train_fp.write(f\"{img_train_fn} {lbl_train_fn}\\n\")\n", + " val_fp.write(f\"{img_val_fn} {lbl_val_fn}\\n\")\n", + "\n", + " train_fp.close()\n", + " val_fp.close()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "id": "DXu4yfuZoiv0", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "dccaf4ba-159f-4a47-d13d-ba4b60eaac80" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Train file `train.txt` content: \n", + "/content/example_data/images/train/0.jpg /content/example_data/labels/train/0.png\n", + "/content/example_data/images/train/1.jpg /content/example_data/labels/train/1.png\n", + "/content/example_data/images/train/2.jpg /content/example_data/labels/train/2.png\n", + "/content/example_data/images/train/3.jpg /content/example_data/labels/train/3.png\n", + "/content/example_data/images/train/4.jpg /content/example_data/labels/train/4.png\n", + "/content/example_data/images/train/5.jpg /content/example_data/labels/train/5.png\n", + "/content/example_data/images/train/6.jpg /content/example_data/labels/train/6.png\n", + "/content/example_data/images/train/7.jpg /content/example_data/labels/train/7.png\n", + "/content/example_data/images/train/8.jpg /content/example_data/labels/train/8.png\n", + "/content/example_data/images/train/9.jpg /content/example_data/labels/train/9.png\n" + ] + } + ], + "source": [ + "num_classes = 10\n", + "generate_proxy_dataset('/content/example_data', num_samples=10, num_classes=num_classes)\n", + "\n", + "print(\"Train file `train.txt` content: \")\n", + "! cat /content/example_data/train.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MDksFYrIqClt" + }, + "source": [ + "## 2.B Create Torch Dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "id": "AGziBKSIqaUu" + }, + "outputs": [], + "source": [ + "import torch\n", + "from torch.utils.data import Dataset\n", + "from torchvision import transforms, utils\n", + "\n", + "\n", + "class CustomDataset(Dataset):\n", + " \"\"\"\n", + " A PyTorch Dataset class to be used in a PyTorch DataLoader to create batches.\n", + " \"\"\"\n", + "\n", + " def __init__(self, data_folder, split):\n", + " \"\"\"\n", + " :param data_folder: folder where data files are stored\n", + " :param split: split, one of 'TRAIN' or 'TEST'\n", + " \"\"\"\n", + " self.data_folder = data_folder\n", + " self.split = split.lower()\n", + " assert self.split in {'train', 'val'}\n", + "\n", + " # Read data files\n", + " with open(os.path.join(data_folder, self.split + '.txt'), 'r') as f:\n", + " data_lines = f.readlines()\n", + " self.samples_fn = [line.strip().split(\" \") for line in data_lines]\n", + "\n", + " self.transforms = transforms.Compose([transforms.ToTensor()])\n", + "\n", + " def __getitem__(self, i):\n", + " # Read image and label\n", + " image = Image.open(self.samples_fn[i][0]).convert('RGB')\n", + " label = Image.open(self.samples_fn[i][1])\n", + "\n", + " image_tensor = self.transforms(image)\n", + " label_tensor = torch.from_numpy(np.array(label)).long()\n", + "\n", + " return image_tensor, label_tensor\n", + "\n", + "\n", + " def __len__(self):\n", + " return len(self.samples_fn)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "id": "2B0hlas_1Rh-" + }, + "outputs": [], + "source": [ + "train_dataset = CustomDataset(\"/content/example_data\", split=\"train\")\n", + "val_dataset = CustomDataset(\"/content/example_data\", split=\"val\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eIG5tsiuor9E" + }, + "source": [ + "Let's have a look at the first sample:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "id": "ZsHqcq1jpN0F", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "e9c1182a-5359-45b6-c0f3-ad430a4fc67d" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "torch.Size([3, 256, 256]) torch.Size([256, 256])\n", + "tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n" + ] + } + ], + "source": [ + "img, lbl = train_dataset[0]\n", + "print(img.shape, lbl.shape)\n", + "print(torch.unique(lbl))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aWfFrYLzo9j8" + }, + "source": [ + "## 2.C Create Torch Dataloader" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "D3ThxDIopDDB" + }, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "id": "XrWjWfjXnw_r" + }, + "outputs": [], + "source": [ + "from torch.utils.data import Dataset, DataLoader\n", + "\n", + "train_dataloader = DataLoader(train_dataset, batch_size=4, shuffle=True, num_workers=2)\n", + "val_dataloader = DataLoader(val_dataset, batch_size=4, shuffle=False, num_workers=2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vB1sGPO8qwZJ" + }, + "source": [ + "Lets' have a look at the first batch:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "id": "O-KuZQ3XBduM", + "colab": { + "base_uri": "https://localhost:8080/" }, + "outputId": "489fc05e-f972-464d-c150-360e4f2dbd7e" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "id": "-Ojnc1bk9L3s", - "colab": { - "base_uri": "https://localhost:8080/" - }, - "outputId": "b36b8b9b-b554-444e-d440-02bf623c3efa" - }, - "outputs": [ - { - "output_type": "stream", - "name": "stderr", - "text": [ - "[2023-11-12 14:41:51] WARNING - sg_trainer.py - Train dataset size % batch_size != 0 and drop_last=False, this might result in smaller last batch.\n", - "[2023-11-12 14:41:58] INFO - sg_trainer.py - Starting a new run with `run_id=RUN_20231112_144158_892860`\n", - "[2023-11-12 14:41:58] INFO - sg_trainer.py - Checkpoints directory: /home/notebook_ckpts/transfer_learning_semantic_segementation_ppLite/RUN_20231112_144158_892860\n", - "/usr/local/lib/python3.10/dist-packages/super_gradients/common/registry/registry.py:72: DeprecationWarning: Object name `cross_entropy` is now deprecated. Please replace it with `CrossEntropyLoss`.\n", - " warnings.warn(f\"Object name `{name}` is now deprecated. Please replace it with `{deprecated_names[name]}`.\", DeprecationWarning)\n" - ] - }, - { - "output_type": "stream", - "name": "stdout", - "text": [ - "The console stream is now moved to /home/notebook_ckpts/transfer_learning_semantic_segementation_ppLite/RUN_20231112_144158_892860/console_Nov12_14_41_58.txt\n" - ] - }, - { - "output_type": "stream", - "name": "stderr", - "text": [ - "[2023-11-12 14:41:59] INFO - sg_trainer_utils.py - TRAINING PARAMETERS:\n", - " - Mode: Single GPU\n", - " - Number of GPUs: 1 (1 available on the machine)\n", - " - Full dataset size: 10 (len(train_set))\n", - " - Batch size per GPU: 4 (batch_size)\n", - " - Batch Accumulate: 1 (batch_accumulate)\n", - " - Total batch size: 4 (num_gpus * batch_size)\n", - " - Effective Batch size: 4 (num_gpus * batch_size * batch_accumulate)\n", - " - Iterations per epoch: 3 (len(train_loader))\n", - " - Gradient updates per epoch: 3 (len(train_loader) / batch_accumulate)\n", - "\n", - "[2023-11-12 14:41:59] INFO - sg_trainer.py - Started training for 10 epochs (0/9)\n", - "\n", - "Train epoch 0: 100%|██████████| 3/3 [00:08<00:00, 2.91s/it, CrossEntropyLoss=3.49, IoU=0.0319, gpu_mem=0.686]\n", - "Validating: 100%|██████████| 3/3 [00:00<00:00, 3.83it/s]\n", - "[2023-11-12 14:42:09] INFO - base_sg_logger.py - Checkpoint saved in /home/notebook_ckpts/transfer_learning_semantic_segementation_ppLite/RUN_20231112_144158_892860/ckpt_best.pth\n", - "[2023-11-12 14:42:09] INFO - sg_trainer.py - Best checkpoint overriden: validation IoU: 0.013753225095570087\n", - "Train epoch 1: 0%| | 0/3 [00:00