diff --git a/docs/index.rst b/docs/index.rst index ced959493a8..9e0b7b11bac 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -30,6 +30,7 @@ torchgeo tutorials/getting_started tutorials/custom_raster_dataset + tutorials/custom_segmentation_trainer tutorials/transforms tutorials/indices tutorials/trainers diff --git a/docs/tutorials/custom_raster_dataset.ipynb b/docs/tutorials/custom_raster_dataset.ipynb index 0e2785bb7ff..ea04196195f 100644 --- a/docs/tutorials/custom_raster_dataset.ipynb +++ b/docs/tutorials/custom_raster_dataset.ipynb @@ -250,8 +250,8 @@ "source": [ "root = os.path.join(tempfile.gettempdir(), 'sentinel')\n", "item_urls = [\n", - " 'https://planetarycomputer.microsoft.com/api/stac/v1/collections/sentinel-2-l2a/items/S2B_MSIL2A_20220902T090559_R050_T40XDH_20220902T181115',\n", - " 'https://planetarycomputer.microsoft.com/api/stac/v1/collections/sentinel-2-l2a/items/S2B_MSIL2A_20220718T084609_R107_T40XEJ_20220718T175008',\n", + " 'https://planetarycomputer.microsoft.com/api/stac/v1/collections/sentinel-2-l2a/items/S2B_MSIL2A_20220902T090559_R050_T40XDH_20220902T181115'\n", + " #'https://planetarycomputer.microsoft.com/api/stac/v1/collections/sentinel-2-l2a/items/S2B_MSIL2A_20220718T084609_R107_T40XEJ_20220718T175008',\n", "]\n", "\n", "for item_url in item_urls:\n", @@ -540,10 +540,6 @@ } ], "metadata": { - "colab": { - "collapsed_sections": [], - "provenance": [] - }, "execution": { "timeout": 1200 }, diff --git a/docs/tutorials/custom_segmentation_trainer.ipynb b/docs/tutorials/custom_segmentation_trainer.ipynb new file mode 100644 index 00000000000..f944ebbeef8 --- /dev/null +++ b/docs/tutorials/custom_segmentation_trainer.ipynb @@ -0,0 +1,514 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "flake8: noqa: E501\n", + "\n", + "Copyright (c) Microsoft Corporation. All rights reserved.\n", + "Licensed under the MIT License." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Custom Trainers\n", + "\n", + "In this tutorial, we demonstrate how to extend a TorchGeo [\"trainer class\"](https://torchgeo.readthedocs.io/en/latest/api/trainers.html). In TorchGeo there exist several trainer classes that are pre-made PyTorch Lightning Modules designed to allow for the easy training of models on semantic segmentation, classification, change detection, etc. tasks using TorchGeo's [prebuilt DataModules](https://torchgeo.readthedocs.io/en/latest/api/datamodules.html). While the trainers aim to provide sensible defaults and customization options for common tasks, they will not be able to cover all situations (e.g. researchers will likely want to implement and use their own architectures, loss functions, optimizers, etc. in the training routine). If you run into such a situation, then you can simply extend the trainer class you are interested in, and write custom logic to override the default functionality.\n", + "\n", + "This tutorial shows how to do exactly this to customize a learning rate schedule, logging, and model checkpointing for a semantic segmentation task using the [LandCover.ai](https://landcover.ai.linuxpolska.com/) dataset.\n", + "\n", + "It's recommended to run this notebook on Google Colab if you don't have your own GPU. Click the \"Open in Colab\" button above to get started." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup\n", + "\n", + "As always, we install TorchGeo." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%pip install torchgeo" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Imports\n", + "\n", + "Next, we import TorchGeo and any other libraries we need." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Get rid of the pesky warnings raised by kornia\n", + "# UserWarning: Default grid_sample and affine_grid behavior has changed to align_corners=False since 1.3.0. Please specify align_corners=True if the old behavior is desired. See the documentation of grid_sample for details.\n", + "import warnings\n", + "from collections.abc import Sequence\n", + "from typing import Any\n", + "\n", + "warnings.filterwarnings('ignore', category=UserWarning, module='torch.nn.functional')\n", + "warnings.filterwarnings('ignore', category=FutureWarning)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "import lightning\n", + "import lightning.pytorch as pl\n", + "import torch\n", + "from lightning.pytorch.callbacks import ModelCheckpoint\n", + "from lightning.pytorch.callbacks.callback import Callback\n", + "from torch.optim import AdamW\n", + "from torch.optim.lr_scheduler import CosineAnnealingLR\n", + "from torchmetrics import MetricCollection\n", + "from torchmetrics.classification import (\n", + " Accuracy,\n", + " FBetaScore,\n", + " JaccardIndex,\n", + " Precision,\n", + " Recall,\n", + ")\n", + "\n", + "from torchgeo.datamodules import LandCoverAI100DataModule\n", + "from torchgeo.trainers import SemanticSegmentationTask" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "lines_to_next_cell": 2 + }, + "source": [ + "## Custom SemanticSegmentationTask\n", + "\n", + "Now, we create a `CustomSemanticSegmentationTask` class that inhierits from `SemanticSegmentationTask` and that overrides a few methods:\n", + "- `__init__`: We add two new parameters `tmax` and `eta_min` to control the learning rate scheduler\n", + "- `configure_optimizers`: We use the `CosineAnnealingLR` learning rate scheduler instead of the default `ReduceLROnPlateau`\n", + "- `configure_metrics`: We add a \"MeanIoU\" metric (what we will use to evaluate the model's performance) and a variety of other classification metrics\n", + "- `configure_callbacks`: We demonstrate how to stack `ModelCheckpoint` callbacks to save the best checkpoint as well as periodic checkpoints\n", + "- `on_train_epoch_start`: We log the learning rate at the start of each epoch so we can easily see how it decays over a training run\n", + "\n", + "Overall these demonstrate how to customize the training routine to investigate specific research questions (e.g. of the scheduler on test performance)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class CustomSemanticSegmentationTask(SemanticSegmentationTask):\n", + " # any keywords we add here between *args and **kwargs will be found in self.hparams\n", + " def __init__(\n", + " self, *args: Any, tmax: int = 50, eta_min: float = 1e-6, **kwargs: Any\n", + " ) -> None:\n", + " super().__init__(*args, **kwargs) # pass args and kwargs to the parent class\n", + "\n", + " def configure_optimizers(\n", + " self,\n", + " ) -> 'lightning.pytorch.utilities.types.OptimizerLRSchedulerConfig':\n", + " \"\"\"Initialize the optimizer and learning rate scheduler.\n", + "\n", + " Returns:\n", + " Optimizer and learning rate scheduler.\n", + " \"\"\"\n", + " tmax: int = self.hparams['tmax']\n", + " eta_min: float = self.hparams['eta_min']\n", + "\n", + " optimizer = AdamW(self.parameters(), lr=self.hparams['lr'])\n", + " scheduler = CosineAnnealingLR(optimizer, T_max=tmax, eta_min=eta_min)\n", + " return {\n", + " 'optimizer': optimizer,\n", + " 'lr_scheduler': {'scheduler': scheduler, 'monitor': self.monitor},\n", + " }\n", + "\n", + " def configure_metrics(self) -> None:\n", + " \"\"\"Initialize the performance metrics.\"\"\"\n", + " num_classes: int = self.hparams['num_classes']\n", + "\n", + " self.train_metrics = MetricCollection(\n", + " {\n", + " 'OverallAccuracy': Accuracy(\n", + " task='multiclass', num_classes=num_classes, average='micro'\n", + " ),\n", + " 'OverallPrecision': Precision(\n", + " task='multiclass', num_classes=num_classes, average='micro'\n", + " ),\n", + " 'OverallRecall': Recall(\n", + " task='multiclass', num_classes=num_classes, average='micro'\n", + " ),\n", + " 'OverallF1Score': FBetaScore(\n", + " task='multiclass',\n", + " num_classes=num_classes,\n", + " beta=1.0,\n", + " average='micro',\n", + " ),\n", + " 'MeanIoU': JaccardIndex(\n", + " num_classes=num_classes, task='multiclass', average='macro'\n", + " ),\n", + " },\n", + " prefix='train_',\n", + " )\n", + " self.val_metrics = self.train_metrics.clone(prefix='val_')\n", + " self.test_metrics = self.train_metrics.clone(prefix='test_')\n", + "\n", + " def configure_callbacks(self) -> Sequence[Callback] | Callback:\n", + " \"\"\"Initialize callbacks for saving the best and latest models.\n", + "\n", + " Returns:\n", + " List of callbacks to apply.\n", + " \"\"\"\n", + " return [\n", + " ModelCheckpoint(every_n_epochs=50, save_top_k=-1, save_last=True),\n", + " ModelCheckpoint(monitor=self.monitor, mode=self.mode, save_top_k=5),\n", + " ]\n", + "\n", + " def on_train_epoch_start(self) -> None:\n", + " \"\"\"Log the learning rate at the start of each training epoch.\"\"\"\n", + " optimizers = self.optimizers()\n", + " if isinstance(optimizers, list):\n", + " lr = optimizers[0].param_groups[0]['lr']\n", + " else:\n", + " lr = optimizers.param_groups[0]['lr']\n", + " self.logger.experiment.add_scalar('lr', lr, self.current_epoch) # type: ignore" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Train model\n", + "\n", + "The remainder of the turial is straightforward and follows the typical [PyTorch Lightning](https://lightning.ai/) training routine. We instantiate a `DataModule` for the LandCover.AI 100 dataset (a small version of the LandCover.AI dataset for notebook testing), instantiate a `CustomSemanticSegmentationTask` with a U-Net and ResNet-50 backbone, then train the model using a Lightning trainer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dm = LandCoverAI100DataModule(root='data', batch_size=10, num_workers=2, download=True)\n", + "\n", + "# You can use the following for actual training runs\n", + "# from torchgeo.datamodules import LandCoverAIDataModule\n", + "# dm = LandCoverAIDataModule(root='data', batch_size=64, num_workers=8, download=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "task = CustomSemanticSegmentationTask(\n", + " model='unet',\n", + " backbone='resnet50',\n", + " weights=True,\n", + " in_channels=3,\n", + " num_classes=6,\n", + " loss='ce',\n", + " lr=1e-3,\n", + " tmax=50,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"backbone\": resnet50\n", + "\"class_weights\": None\n", + "\"eta_min\": 1e-06\n", + "\"freeze_backbone\": False\n", + "\"freeze_decoder\": False\n", + "\"ignore_index\": None\n", + "\"in_channels\": 3\n", + "\"loss\": ce\n", + "\"lr\": 0.001\n", + "\"model\": unet\n", + "\"num_classes\": 6\n", + "\"num_filters\": 3\n", + "\"patience\": 10\n", + "\"tmax\": 50" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# validate that the task's hyperparameters are as expected\n", + "task.hparams" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Trainer will use only 1 of 4 GPUs because it is running inside an interactive / notebook environment. You may try to set `Trainer(devices=4)` but please note that multi-GPU inside interactive / notebook environments is considered experimental and unstable. Your mileage may vary.\n", + "GPU available: True (cuda), used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "HPU available: False, using: 0 HPUs\n", + "`Trainer(limit_train_batches=1)` was configured so 1 batch per epoch will be used.\n", + "`Trainer(limit_val_batches=1)` was configured so 1 batch will be used.\n" + ] + } + ], + "source": [ + "# The following Trainer config is useful just for testing the code in this notebook.\n", + "trainer = pl.Trainer(\n", + " limit_train_batches=1,\n", + " limit_val_batches=1,\n", + " num_sanity_val_steps=0,\n", + " max_epochs=1,\n", + " accelerator='gpu' if torch.cuda.is_available() else 'cpu',\n", + ")\n", + "# You can use the following for actual training runs.\n", + "# trainer = pl.Trainer(min_epochs=150, max_epochs=250, log_every_n_steps=50)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "The following callbacks returned in `LightningModule.configure_callbacks` will override existing callbacks passed to Trainer: ModelCheckpoint\n", + "You are using a CUDA device ('NVIDIA A100 80GB PCIe') that has Tensor Cores. To properly utilize them, you should set `torch.set_float32_matmul_precision('medium' | 'high')` which will trade-off precision for performance. For more details, read https://pytorch.org/docs/stable/generated/torch.set_float32_matmul_precision.html#torch.set_float32_matmul_precision\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downloading https://cdn-lfs-us-1.huggingface.co/repos/76/99/7699a6c85994316c8a0bbf95d41627e5f1b3ea8501f66f73c0e2f53eb0afec45/bfe5bcf501a54cfd8ebf985346da50be5e8b751d3491812cd0c226b5a3abff41?response-content-disposition=inline%3B+filename*%3DUTF-8%27%27landcoverai100.zip%3B+filename%3D%22landcoverai100.zip%22%3B&response-content-type=application%2Fzip&Expires=1726948262&Policy=eyJTdGF0ZW1lbnQiOlt7IkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTcyNjk0ODI2Mn19LCJSZXNvdXJjZSI6Imh0dHBzOi8vY2RuLWxmcy11cy0xLmh1Z2dpbmdmYWNlLmNvL3JlcG9zLzc2Lzk5Lzc2OTlhNmM4NTk5NDMxNmM4YTBiYmY5NWQ0MTYyN2U1ZjFiM2VhODUwMWY2NmY3M2MwZTJmNTNlYjBhZmVjNDUvYmZlNWJjZjUwMWE1NGNmZDhlYmY5ODUzNDZkYTUwYmU1ZThiNzUxZDM0OTE4MTJjZDBjMjI2YjVhM2FiZmY0MT9yZXNwb25zZS1jb250ZW50LWRpc3Bvc2l0aW9uPSomcmVzcG9uc2UtY29udGVudC10eXBlPSoifV19&Signature=Gcz-ypfchbehbW2jBiQ%7ElsHtponr7Cpnoakn%7EcoIJ3O4JEiRgQBmW8GzoF7g9GVzRYHoSloeBlPSjkhB8FTdA5GDmKx16TJddhcFbzEhxAOzpYS9FBHVMf9yh0Ofbhy9w64GonBLDo6Lm97O%7EuGqTc4azZ-KzRTNTEvA%7Ej4%7Epb5aALM6vifb%7EfdIbfBtJC%7ECfB7U4Idu5gdqbnGIbUbnmpcd-g7UUgw3T1HbroqjappCt9HouM6nhAeoop2yBq7sgjxgDSdUA3rBACm8Hqi3rFth6Q4IFe%7Emoxt1mjV%7E0M2I2AHiSHK2k%7EZ%7ENaZgBUSk4S3R8mkWBrIv9JG19azAWg__&Key-Pair-Id=K24J24Z295AEI9 to data/landcoverai100.zip\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 9278198/9278198 [00:00<00:00, 21183125.27it/s]\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]\n", + "\n", + " | Name | Type | Params | Mode \n", + "-----------------------------------------------------------\n", + "0 | model | Unet | 32.5 M | train\n", + "1 | criterion | CrossEntropyLoss | 0 | train\n", + "2 | train_metrics | MetricCollection | 0 | train\n", + "3 | val_metrics | MetricCollection | 0 | train\n", + "4 | test_metrics | MetricCollection | 0 | train\n", + "-----------------------------------------------------------\n", + "32.5 M Trainable params\n", + "0 Non-trainable params\n", + "32.5 M Total params\n", + "130.087 Total estimated model params size (MB)\n", + "242 Modules in train mode\n", + "0 Modules in eval mode\n", + "/opt/conda/envs/torchgeo/lib/python3.12/site-packages/lightning/pytorch/loops/fit_loop.py:298: The number of training batches (1) is smaller than the logging interval Trainer(log_every_n_steps=50). Set a lower value for log_every_n_steps if you want to see logs for the training epoch.\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "47c8ef6ff2f147a287fcd137058b2509", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Training: | | 0/? [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "db9116f3e41245c6897b885aa322dcbc", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: | | 0/? [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "`Trainer.fit` stopped: `max_epochs=1` reached.\n" + ] + } + ], + "source": [ + "trainer.fit(task, dm)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test model\n", + "\n", + "Finally, we test the model (optionally loading from a previously saved checkpoint)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# You can load directly from a saved checkpoint with `.load_from_checkpoint(...)`\n", + "# Note that you can also just call `trainer.test(task, dm)` if you've already trained\n", + "# the model in the current notebook session.\n", + "\n", + "task = CustomSemanticSegmentationTask.load_from_checkpoint(\n", + " os.path.join('lightning_logs', 'version_0', 'checkpoints', 'epoch=0-step=1.ckpt')\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "The following callbacks returned in `LightningModule.configure_callbacks` will override existing callbacks passed to Trainer: ModelCheckpoint\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ab3b452d9a8f410fb5b2dfa6c660cbcf", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Testing: | | 0/? [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n", + "┃ Test metric ┃ DataLoader 0 ┃\n", + "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n", + "│ test_MeanIoU │ 0.0038406727835536003 │\n", + "│ test_OverallAccuracy │ 0.0015612284187227488 │\n", + "│ test_OverallF1Score │ 0.0015612284187227488 │\n", + "│ test_OverallPrecision │ 0.0015612284187227488 │\n", + "│ test_OverallRecall │ 0.0015612284187227488 │\n", + "│ test_loss │ 17.85824203491211 │\n", + "└───────────────────────────┴───────────────────────────┘\n", + "\n" + ], + "text/plain": [ + "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n", + "┃\u001b[1m \u001b[0m\u001b[1m Test metric \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m DataLoader 0 \u001b[0m\u001b[1m \u001b[0m┃\n", + "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n", + "│\u001b[36m \u001b[0m\u001b[36m test_MeanIoU \u001b[0m\u001b[36m \u001b[0m│\u001b[35m \u001b[0m\u001b[35m 0.0038406727835536003 \u001b[0m\u001b[35m \u001b[0m│\n", + "│\u001b[36m \u001b[0m\u001b[36m test_OverallAccuracy \u001b[0m\u001b[36m \u001b[0m│\u001b[35m \u001b[0m\u001b[35m 0.0015612284187227488 \u001b[0m\u001b[35m \u001b[0m│\n", + "│\u001b[36m \u001b[0m\u001b[36m test_OverallF1Score \u001b[0m\u001b[36m \u001b[0m│\u001b[35m \u001b[0m\u001b[35m 0.0015612284187227488 \u001b[0m\u001b[35m \u001b[0m│\n", + "│\u001b[36m \u001b[0m\u001b[36m test_OverallPrecision \u001b[0m\u001b[36m \u001b[0m│\u001b[35m \u001b[0m\u001b[35m 0.0015612284187227488 \u001b[0m\u001b[35m \u001b[0m│\n", + "│\u001b[36m \u001b[0m\u001b[36m test_OverallRecall \u001b[0m\u001b[36m \u001b[0m│\u001b[35m \u001b[0m\u001b[35m 0.0015612284187227488 \u001b[0m\u001b[35m \u001b[0m│\n", + "│\u001b[36m \u001b[0m\u001b[36m test_loss \u001b[0m\u001b[36m \u001b[0m│\u001b[35m \u001b[0m\u001b[35m 17.85824203491211 \u001b[0m\u001b[35m \u001b[0m│\n", + "└───────────────────────────┴───────────────────────────┘\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "[{'test_loss': 17.85824203491211,\n", + " 'test_MeanIoU': 0.0038406727835536003,\n", + " 'test_OverallAccuracy': 0.0015612284187227488,\n", + " 'test_OverallF1Score': 0.0015612284187227488,\n", + " 'test_OverallPrecision': 0.0015612284187227488,\n", + " 'test_OverallRecall': 0.0015612284187227488}]" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "trainer.test(task, dm)" + ] + } + ], + "metadata": { + "jupytext": { + "formats": "ipynb,py" + }, + "kernelspec": { + "display_name": "torchgeo", + "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.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/tutorials/getting_started.ipynb b/docs/tutorials/getting_started.ipynb index 1b1982711b3..b5edc63d64f 100644 --- a/docs/tutorials/getting_started.ipynb +++ b/docs/tutorials/getting_started.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "35303546", + "id": "0", "metadata": {}, "source": [ "Copyright (c) Microsoft Corporation. All rights reserved.\n", @@ -12,7 +12,7 @@ }, { "cell_type": "markdown", - "id": "9478ed9a", + "id": "1", "metadata": { "id": "NdrXRgjU7Zih" }, @@ -26,7 +26,7 @@ }, { "cell_type": "markdown", - "id": "34f10e9f", + "id": "2", "metadata": { "id": "lCqHTGRYBZcz" }, @@ -39,7 +39,7 @@ { "cell_type": "code", "execution_count": null, - "id": "019092f0", + "id": "3", "metadata": {}, "outputs": [], "source": [ @@ -48,7 +48,7 @@ }, { "cell_type": "markdown", - "id": "4db9f791", + "id": "4", "metadata": { "id": "dV0NLHfGBMWl" }, @@ -61,7 +61,7 @@ { "cell_type": "code", "execution_count": null, - "id": "3d92b0f1", + "id": "5", "metadata": { "id": "entire-albania" }, @@ -79,7 +79,7 @@ }, { "cell_type": "markdown", - "id": "7f26e4b8", + "id": "6", "metadata": { "id": "5rLknZxrBEMz" }, @@ -92,7 +92,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4a39af46", + "id": "7", "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -154,10 +154,10 @@ " 'https://naipeuwest.blob.core.windows.net/naip/v002/de/2018/de_060cm_2018/38075/'\n", ")\n", "tiles = [\n", - " 'm_3807511_ne_18_060_20181104.tif',\n", - " 'm_3807511_se_18_060_20181104.tif',\n", - " 'm_3807512_nw_18_060_20180815.tif',\n", - " 'm_3807512_sw_18_060_20180815.tif',\n", + " 'm_3807511_ne_18_060_20181104.tif'\n", + " #'m_3807511_se_18_060_20181104.tif',\n", + " #'m_3807512_nw_18_060_20180815.tif',\n", + " #'m_3807512_sw_18_060_20180815.tif',\n", "]\n", "for tile in tiles:\n", " download_url(naip_url + tile, naip_root)\n", @@ -167,7 +167,7 @@ }, { "cell_type": "markdown", - "id": "e25bad40", + "id": "8", "metadata": { "id": "HQVji2B22Qfu" }, @@ -178,7 +178,7 @@ { "cell_type": "code", "execution_count": null, - "id": "689bb2b0", + "id": "9", "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -195,7 +195,7 @@ }, { "cell_type": "markdown", - "id": "56f2d78b", + "id": "10", "metadata": { "id": "OWUhlfpD22IX" }, @@ -206,7 +206,7 @@ { "cell_type": "code", "execution_count": null, - "id": "daefbc4d", + "id": "11", "metadata": { "id": "WXxy8F8l2-aC" }, @@ -217,7 +217,7 @@ }, { "cell_type": "markdown", - "id": "ded44652", + "id": "12", "metadata": { "id": "yF_R54Yf3EUd" }, @@ -230,7 +230,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b8a0d99c", + "id": "13", "metadata": { "id": "RLczuU293itT" }, @@ -241,7 +241,7 @@ }, { "cell_type": "markdown", - "id": "5b8c1c52", + "id": "14", "metadata": { "id": "OWa-mmYd8S6K" }, @@ -254,7 +254,7 @@ { "cell_type": "code", "execution_count": null, - "id": "96faa142", + "id": "15", "metadata": { "id": "jfx-9ZmU8ZTc" }, @@ -265,7 +265,7 @@ }, { "cell_type": "markdown", - "id": "64ae63f7", + "id": "16", "metadata": { "id": "HZIfqqW58oZe" }, @@ -278,7 +278,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8a2b44f8", + "id": "17", "metadata": { "id": "7sGmNvBy8uIg" }, @@ -291,11 +291,6 @@ } ], "metadata": { - "colab": { - "collapsed_sections": [], - "name": "getting_started.ipynb", - "provenance": [] - }, "execution": { "timeout": 1200 }, @@ -314,7 +309,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.10.14" } }, "nbformat": 4, diff --git a/docs/tutorials/indices.ipynb b/docs/tutorials/indices.ipynb index 30576609ac8..ceb93a8223d 100644 --- a/docs/tutorials/indices.ipynb +++ b/docs/tutorials/indices.ipynb @@ -353,9 +353,6 @@ } ], "metadata": { - "colab": { - "provenance": [] - }, "execution": { "timeout": 1200 }, diff --git a/docs/tutorials/pretrained_weights.ipynb b/docs/tutorials/pretrained_weights.ipynb index 0c2c4a0fc48..e2b4c7612b0 100644 --- a/docs/tutorials/pretrained_weights.ipynb +++ b/docs/tutorials/pretrained_weights.ipynb @@ -473,9 +473,6 @@ ], "metadata": { "accelerator": "GPU", - "colab": { - "provenance": [] - }, "execution": { "timeout": 1200 }, diff --git a/docs/tutorials/trainers.ipynb b/docs/tutorials/trainers.ipynb index 5de3937a026..37d91a5714a 100644 --- a/docs/tutorials/trainers.ipynb +++ b/docs/tutorials/trainers.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "b13c2251", + "id": "0", "metadata": { "id": "b13c2251" }, @@ -14,7 +14,7 @@ }, { "cell_type": "markdown", - "id": "e563313d", + "id": "1", "metadata": { "id": "e563313d" }, @@ -28,7 +28,7 @@ }, { "cell_type": "markdown", - "id": "8c1f4156", + "id": "2", "metadata": { "id": "8c1f4156" }, @@ -41,7 +41,7 @@ { "cell_type": "code", "execution_count": null, - "id": "3f0d31a8", + "id": "3", "metadata": { "id": "3f0d31a8" }, @@ -52,7 +52,7 @@ }, { "cell_type": "markdown", - "id": "c90c94c7", + "id": "4", "metadata": { "id": "c90c94c7" }, @@ -65,7 +65,7 @@ { "cell_type": "code", "execution_count": null, - "id": "bd39f485", + "id": "5", "metadata": { "id": "bd39f485" }, @@ -89,7 +89,7 @@ }, { "cell_type": "markdown", - "id": "e6e1d9b6", + "id": "6", "metadata": { "id": "e6e1d9b6" }, @@ -103,7 +103,7 @@ }, { "cell_type": "markdown", - "id": "9f2daa0d", + "id": "7", "metadata": { "id": "9f2daa0d" }, @@ -114,7 +114,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8e100f8b", + "id": "8", "metadata": { "id": "8e100f8b", "nbmake": { @@ -137,7 +137,7 @@ { "cell_type": "code", "execution_count": null, - "id": "0f2a04c7", + "id": "9", "metadata": { "id": "0f2a04c7" }, @@ -151,7 +151,7 @@ }, { "cell_type": "markdown", - "id": "056b7b4c", + "id": "10", "metadata": { "id": "056b7b4c" }, @@ -162,7 +162,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ba5c5442", + "id": "11", "metadata": { "id": "ba5c5442" }, @@ -181,7 +181,7 @@ }, { "cell_type": "markdown", - "id": "d4b67f3e", + "id": "12", "metadata": { "id": "d4b67f3e" }, @@ -194,7 +194,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ffe26e5c", + "id": "13", "metadata": { "id": "ffe26e5c" }, @@ -211,7 +211,7 @@ }, { "cell_type": "markdown", - "id": "06afd8c7", + "id": "14", "metadata": { "id": "06afd8c7" }, @@ -222,7 +222,7 @@ { "cell_type": "code", "execution_count": null, - "id": "225a6d36", + "id": "15", "metadata": { "id": "225a6d36" }, @@ -241,7 +241,7 @@ }, { "cell_type": "markdown", - "id": "44d71e8f", + "id": "16", "metadata": { "id": "44d71e8f" }, @@ -252,7 +252,7 @@ { "cell_type": "code", "execution_count": null, - "id": "00e08790", + "id": "17", "metadata": { "id": "00e08790" }, @@ -263,7 +263,7 @@ }, { "cell_type": "markdown", - "id": "73700fb5", + "id": "18", "metadata": { "id": "73700fb5" }, @@ -274,7 +274,7 @@ { "cell_type": "code", "execution_count": null, - "id": "3e95ee0a", + "id": "19", "metadata": {}, "outputs": [], "source": [ @@ -283,7 +283,7 @@ }, { "cell_type": "markdown", - "id": "04cfc7a8", + "id": "20", "metadata": { "id": "04cfc7a8" }, @@ -294,7 +294,7 @@ { "cell_type": "code", "execution_count": null, - "id": "604a3b2f", + "id": "21", "metadata": { "id": "604a3b2f" }, @@ -306,9 +306,6 @@ ], "metadata": { "accelerator": "GPU", - "colab": { - "provenance": [] - }, "execution": { "timeout": 1200 }, diff --git a/docs/tutorials/transforms.ipynb b/docs/tutorials/transforms.ipynb index a7de9f32c69..4aeb12cbb2a 100644 --- a/docs/tutorials/transforms.ipynb +++ b/docs/tutorials/transforms.ipynb @@ -693,9 +693,6 @@ ], "metadata": { "accelerator": "GPU", - "colab": { - "provenance": [] - }, "execution": { "timeout": 1200 },