From b58c1e4ce55d4874eacf47e968e3608683dabf82 Mon Sep 17 00:00:00 2001 From: shayaharon Date: Mon, 29 Nov 2021 13:49:28 +0200 Subject: [PATCH] notebook added --- examples/quickstart.ipynb | 534 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 534 insertions(+) create mode 100644 examples/quickstart.ipynb diff --git a/examples/quickstart.ipynb b/examples/quickstart.ipynb new file mode 100644 index 0000000000..adb7915898 --- /dev/null +++ b/examples/quickstart.ipynb @@ -0,0 +1,534 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# SuperGradients Quick Tour Notebook" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Hi there and welcome to SuperGradients, a free open-source training library for PyTorch-based deep learning models.  Let's have a quick look at the SuperGradients library features. The library lets you train models from any Computer Vision tasks or import pre-trained SOTA models, such as object detection, calssification of images, and semantic segmentation for videos or images use cases.\n", + "\n", + "Whether you are a beginer or an expert it is likely that you already have your own training script, model, loss function implementation etc.\n", + "In this notebook we present the modifications needed in order to launch your training so you can benefit from the various tools the SuperGradients package has to offer.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# SuperGradients installation\n", + "# !pip install super-gradients\n", + "\n", + "# To install from source instead of the last release, comment the command above and uncomment the following one.\n", + "# !pip install git+https://github.com/Deci-AI/super_gradients.git" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "> **NOTE:** All code examples presented in the documentation are in PyTorch framework." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Getting started with training a model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Integrating Your Loss Function**\n", + "\n", + "The loss function class must be of torch.nn.module._LOSS type. For example, our LabelSmoothingCrossEntropyLoss implementation" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "You did not mention an AWS environment.You can set the environment variable ENVIRONMENT_NAME with one of the values: development,staging,production\n", + "[WARNING]No module named 'pycocotools'\n", + "callbacks -WARNING- Failed to import deci_lab_client\n" + ] + } + ], + "source": [ + "import torch.nn as nn\n", + "from super_gradients.training.losses.label_smoothing_cross_entropy_loss import cross_entropy\n", + "\n", + "class LabelSmoothingCrossEntropyLoss(nn.CrossEntropyLoss):\n", + " def __init__(self, weight=None, ignore_index=-100, reduction='mean', smooth_eps=None, smooth_dist=None,\n", + " from_logits=True):\n", + " super(LabelSmoothingCrossEntropyLoss, self).__init__(weight=weight,\n", + " ignore_index=ignore_index, reduction=reduction)\n", + " self.smooth_eps = smooth_eps\n", + " self.smooth_dist = smooth_dist\n", + " self.from_logits = from_logits\n", + "\n", + " def forward(self, input, target, smooth_dist=None):\n", + " if smooth_dist is None:\n", + " smooth_dist = self.smooth_dist\n", + " loss = cross_entropy(input, target, weight=self.weight, ignore_index=self.ignore_index,\n", + " reduction=self.reduction, smooth_eps=self.smooth_eps,\n", + " smooth_dist=smooth_dist, from_logits=self.from_logits)\n", + "\n", + " return loss" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Integrating Your Dataset**\n", + "\n", + "In order to integrate your own dataset with our training scheme, we introduce the *dataset_interface* concept, which wraps the *torch dataloaders* used for training.\n", + "The specified dataset interface class must inherit from deci_trainer.trainer.datasets.dataset_interfaces.dataset_interface, which is where data augmentation and data loader configurations are defined.\n", + "For instance, a dataset interface for Cifar10:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "import torchvision.datasets as datasets\n", + "import torchvision.transforms as transforms\n", + "from super_gradients.training import utils as core_utils\n", + "from super_gradients.training.datasets.dataset_interfaces import DatasetInterface\n", + "\n", + "\n", + "class UserDataset(DatasetInterface):\n", + "\n", + " def __init__(self, name=\"cifar10\", dataset_params={}):\n", + " super(UserDataset, self).__init__(dataset_params)\n", + " self.dataset_name = name\n", + " self.lib_dataset_params = {'mean': (0.4914, 0.4822, 0.4465), 'std': (0.2023, 0.1994, 0.2010)}\n", + "\n", + " crop_size = core_utils.get_param(self.dataset_params, 'crop_size', default_val=32)\n", + "\n", + " transform_train = transforms.Compose([\n", + " transforms.RandomCrop(crop_size, padding=4),\n", + " transforms.RandomHorizontalFlip(),\n", + " transforms.ToTensor(),\n", + " transforms.Normalize(self.lib_dataset_params['mean'], self.lib_dataset_params['std']),\n", + " ])\n", + "\n", + " transform_test = transforms.Compose([\n", + " transforms.ToTensor(),\n", + " transforms.Normalize(self.lib_dataset_params['mean'], self.lib_dataset_params['std']),\n", + " ])\n", + "\n", + " self.trainset = datasets.CIFAR10(root=self.dataset_params.dataset_dir, train=True, download=True,\n", + " transform=transform_train)\n", + "\n", + " self.valset = datasets.CIFAR10(root=self.dataset_params.dataset_dir, train=False, download=True,\n", + " transform=transform_test)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Required parameters can be passed using the python dataset_params argument. When implementing a dataset interface, the *trainset* and *valset* attributes are required and must be initiated with a torch.utils.data.Dataset type.\n", + " These fields will cause the DeciMode instance to use them accordingly, such as during training, validation, and so on." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Integrating Your Network Architecture**\n", + "\n", + "This is rather straightforward- the only requirement is that the model must be of torch.nn.Module type. In our case, a simple Lenet implementation (taken from https://github.com/icpm/pytorch-cifar10/blob/master/models/LeNet.py)." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "import torch.nn as nn\n", + "import torch.nn.functional as func\n", + "\n", + "\n", + "class LeNet(nn.Module):\n", + " def __init__(self):\n", + " super(LeNet, self).__init__()\n", + " self.conv1 = nn.Conv2d(3, 6, kernel_size=5)\n", + " self.conv2 = nn.Conv2d(6, 16, kernel_size=5)\n", + " self.fc1 = nn.Linear(16*5*5, 120)\n", + " self.fc2 = nn.Linear(120, 84)\n", + " self.fc3 = nn.Linear(84, 10)\n", + "\n", + " def forward(self, x):\n", + " x = func.relu(self.conv1(x))\n", + " x = func.max_pool2d(x, 2)\n", + " x = func.relu(self.conv2(x))\n", + " x = func.max_pool2d(x, 2)\n", + " x = x.view(x.size(0), -1)\n", + " x = func.relu(self.fc1(x))\n", + " x = func.relu(self.fc2(x))\n", + " x = self.fc3(x)\n", + " return x" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Putting It All Together**\n", + "\n", + "We instantiate an SgModel and a UserDatasetInterface, then call *connect_dataset_interface* which will initialize the dataloaders and pass additional dataset parameters to the SgModel instance." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Files already downloaded and verified\n", + "Files already downloaded and verified\n" + ] + } + ], + "source": [ + "from super_gradients.training import SgModel\n", + "\n", + "sg_model = SgModel(experiment_name='LeNet_cifar10_example')\n", + "# sg_model.build_model(architecture=network)\n", + "dataset_params = {\"batch_size\": 256}\n", + "dataset = UserDataset(dataset_params)\n", + "sg_model.connect_dataset_interface(dataset)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we pass a LeNet instance we defined above to the SgModel:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "network = LeNet()\n", + "sg_model.build_model(network)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we define metrics in order to valuate our model.\n", + "The metrics objects to be logged during training must be of torchmetrics.Metric type. For more information on how to use torchmetric.Metric objects and implement your own metrics. see https://torchmetrics.readthedocs.io/en/latest/pages/overview.html.\n", + "During training, the metric's update is called with the model's raw outputs and raw targets. Therefore, any processing of the two must be taken into account and applied in the update.\n", + "\n", + "For most of the familiar cases, an existing torchmetric.Metric implementation exists in super_gradients.training.metrics. Here we simply use the SuperGradients Top1 and Top5 accuracy metrics in order to define the metrics for evaluation on the train set and the validation set." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "from super_gradients.training.metrics import Accuracy, Top5\n", + "\n", + "train_metrics_list = [Accuracy(), Top5()]\n", + "valid_metrics_list = [Accuracy(), Top5()]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, we can define the training parameters, and simply call *train*:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\"events.out.tfevents.1637763896.h-MacBook-Pro-sl-Shay.local.47404.0\" will not be deleted\n", + "\"events.out.tfevents.1637763957.h-MacBook-Pro-sl-Shay.local.47404.1\" will not be deleted\n", + "sg_model -INFO- Started training for 250 epochs (0/249)\n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Train epoch 0: 0%| | 0/782 [00:00 **Training Parameter Notes:**\n", + "\\\n", + "loss_logging_items_names parameter – Refers to the single item returned by our loss function described above.\n", + "*metric_to_watch* – Is the model’s metric that determines the checkpoint to be saved. In our example, this parameter is set to Accuracy, and can be set to any of the following:\n", + "A metric name (str) of one of the metric objects from the *valid_metrics_list* or \"Loss\" (which refers to the validation loss).\n", + "*greater_metric_to_watch_is_better* flag – Determines when to save a model's checkpoint according to the value of the metric_to_watch." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "##TODO: How to load a pre-trained SOTA model and perform transfer learning\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} \ No newline at end of file