Quickstart
Introduction
This tutorial walk you through the different steps of training one of the MMDetection models supported in IceVision. We use either the Fridge Objects dataset or the PennFudan dataset.
The IceVision Framework is an agnostic framework. As an illustration, we will train our model using both the fastai library, and pytorch-lightning libraries.
For more information about how the fridge dataset as well as its corresponding parser check out the IceData repository.
Installing IceVision and IceData
# !pip install icevision[all] icedata -q
!pip install git+git://github.com/airctic/icevision.git#egg=icevision[all] --upgrade -q
# !pip install icedata -q
!pip install git+git://github.com/airctic/icedata.git --upgrade -q
MMDetection Installation
# Install mmdetection
!rm -rf mmdetection
!git clone https://github.com/open-mmlab/mmdetection.git
!pip install -e mmdetection -q
!ls
mmdetection sample_data
Check Pytorch installation
import torch, torchvision
print(torch.__version__, torch.cuda.is_available())
torch_version, cuda_version = (torch.__version__).split("+")
torch_version, cuda_version
1.7.0+cu101 True
('1.7.0', 'cu101')
MMCV Full-Version Installation
mmcv_full_version = "1.2.5"
mmcv_full_url = f"https://download.openmmlab.com/mmcv/dist/{cuda_version}/torch{torch_version}/index.html" #e.g https://download.openmmlab.com/mmcv/dist/cu101/torch1.7.0/index.html
mmcv_full_url
!pip install mmcv-full=={mmcv_full_version} -f {mmcv_full_url} -U -q
# Restart Runtime
import os
def restart_runtime():
os.kill(os.getpid(), 9)
restart_runtime()
import mmcv
print("MMCV: ", mmcv.__version__)
# Check MMDetection installation
import mmdet
print("MMDetection: ", mmdet.__version__)
# Check mmcv installation
from mmcv.ops import get_compiling_cuda_version, get_compiler_version
print(get_compiling_cuda_version())
print(get_compiler_version())
'https://download.openmmlab.com/mmcv/dist/cu101/torch1.7.0/index.html'
MMCV: 1.2.5
MMDetection: 2.9.0
10.1
GCC 7.3
If mmdet is not recognized, Restart Runtime from the "Runtime Menu"
Imports
from icevision.all import *
MMDetection Models Information
models_info contain all the necessary configuration information to build an MMDetection model. That includes:
- 'model_name'
- 'model_type'
- 'cfg_filepath'
- 'weights_url'
all_models_info = [
{
'model_name': "cornernet",
'model_type': models.mmdet.cornernet,
'cfg_filepath': "mmdetection/configs/cornernet/cornernet_hourglass104_mstest_32x3_210e_coco.py",
'weights_url': "http://download.openmmlab.com/mmdetection/v2.0/cornernet/cornernet_hourglass104_mstest_32x3_210e_coco/cornernet_hourglass104_mstest_32x3_210e_coco_20200819_203110-1efaea91.pth",
},
{
'model_name': "centripetalnet",
'model_type': models.mmdet.centripetalnet,
'cfg_filepath': "mmdetection/configs/centripetalnet/centripetalnet_hourglass104_mstest_16x6_210e_coco.py",
'weights_url': "http://download.openmmlab.com/mmdetection/v2.0/centripetalnet/centripetalnet_hourglass104_mstest_16x6_210e_coco/centripetalnet_hourglass104_mstest_16x6_210e_coco_20200915_204804-3ccc61e5.pth",
},
{
'model_name': "retinanet",
'model_type': models.mmdet.retinanet,
'cfg_filepath': "mmdetection/configs/_base_/models/retinanet_r50_fpn.py",
'weights_url': "http://download.openmmlab.com/mmdetection/v2.0/retinanet/retinanet_r50_fpn_1x_coco/retinanet_r50_fpn_1x_coco_20200130-c2398f9e.pth",
},
{
'model_name': "fcos",
'model_type': models.mmdet.fcos,
'cfg_filepath': "mmdetection/configs/fcos/fcos_x101_64x4d_fpn_gn-head_mstrain_640-800_2x_coco.py",
'weights_url': "http://download.openmmlab.com/mmdetection/v2.0/fcos/fcos_x101_64x4d_fpn_gn-head_mstrain_640-800_4x2_2x_coco/fcos_x101_64x4d_fpn_gn-head_mstrain_640-800_4x2_2x_coco_20200229-11f8c079.pth",
},
{
'model_name': "faster_rcnn",
'model_type': models.mmdet.faster_rcnn,
'cfg_filepath': "mmdetection/configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py",
'weights_url': "http://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth",
},
{
'model_name': "mask_rcnn",
'model_type': models.mmdet.mask_rcnn,
'cfg_filepath': "mmdetection/configs/mask_rcnn/mask_rcnn_r50_fpn_1x_coco.py",
'weights_url': "http://download.openmmlab.com/mmdetection/v2.0/mask_rcnn/mask_rcnn_r50_fpn_1x_coco/mask_rcnn_r50_fpn_1x_coco_20200205-d4b0c5d6.pth",
},
]
Select a Model to train
You can select one of the following models: "retinanet", "fcos", "faster_rcnn", "mask_rcnn"
model_name = "retinanet" # "cornernet", "centripetalnet", "retinanet", "fcos", "faster_rcnn", "mask_rcnn"
model_info = next(m_info for m_info in all_models_info if m_info["model_name"] == model_name)
model_info
model_type = model_info["model_type"]
cfg_filepath = model_info["cfg_filepath"]
weights_url = model_info["weights_url"]
{'cfg_filepath': 'mmdetection/configs/_base_/models/retinanet_r50_fpn.py',
'model_name': 'retinanet',
'model_type': <module 'icevision.models.mmdet.models.retinanet' from '/usr/local/lib/python3.6/dist-packages/icevision/models/mmdet/models/retinanet/__init__.py'>,
'weights_url': 'http://download.openmmlab.com/mmdetection/v2.0/retinanet/retinanet_r50_fpn_1x_coco/retinanet_r50_fpn_1x_coco_20200130-c2398f9e.pth'}
Datasets :
- For Object Detection the Fridge Object Dataset will be used
- For Mask Detection the PennFudan Dataset will be used
if "mask" in model_name:
data_dir = icedata.pennfudan.load_data()
parser = icedata.pennfudan.parser(data_dir)
else:
data_dir = icedata.fridge.load_data()
parser = icedata.fridge.parser(data_dir)
train_records, valid_records = parser.parse()
# train_records[0]
presize, size = 512, 384
train_tfms = tfms.A.Adapter(
[*tfms.A.aug_tfms(size=size, presize=presize), tfms.A.Normalize()]
)
valid_tfms = tfms.A.Adapter([*tfms.A.resize_and_pad(size=size), tfms.A.Normalize()])
train_ds = Dataset(train_records, train_tfms)
valid_ds = Dataset(valid_records, valid_tfms)
train_dl = model_type.train_dl(train_ds, batch_size=8, num_workers=4, shuffle=True)
valid_dl = model_type.valid_dl(valid_ds, batch_size=8, num_workers=4, shuffle=False)
parser.class_map
0%| | 0/128 [00:00<?, ?it/s]
[1m[1mINFO [0m[1m[0m - [1m[34m[1mAutofixing records[0m[1m[34m[0m[1m[0m | [36micevision.parsers.parser[0m:[36mparse[0m:[36m132[0m
<ClassMap: {'background': 0, 'carton': 1, 'milk_bottle': 2, 'can': 3, 'water_bottle': 4}>
Visualization
Showing some images
samples = [train_ds[0] for _ in range(3)]
show_samples(samples, ncols=3, class_map=parser.class_map)
Downloading Pretrained Weights
weights_url
checkpoints_dir = "checkpoints"
!mkdir {checkpoints_dir}
!wget -c -P checkpoints/ {weights_url}
'http://download.openmmlab.com/mmdetection/v2.0/retinanet/retinanet_r50_fpn_1x_coco/retinanet_r50_fpn_1x_coco_20200130-c2398f9e.pth'
--2021-02-19 17:46:07-- http://download.openmmlab.com/mmdetection/v2.0/retinanet/retinanet_r50_fpn_1x_coco/retinanet_r50_fpn_1x_coco_20200130-c2398f9e.pth
Resolving download.openmmlab.com (download.openmmlab.com)... 47.254.186.225
Connecting to download.openmmlab.com (download.openmmlab.com)|47.254.186.225|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 152149505 (145M) [application/octet-stream]
Saving to: ‘checkpoints/retinanet_r50_fpn_1x_coco_20200130-c2398f9e.pth’
retinanet_r50_fpn_1 100%[===================>] 145.10M 8.53MB/s in 23s
2021-02-19 17:46:31 (6.44 MB/s) - ‘checkpoints/retinanet_r50_fpn_1x_coco_20200130-c2398f9e.pth’ saved [152149505/152149505]
!ls {checkpoints_dir}
retinanet_r50_fpn_1x_coco_20200130-c2398f9e.pth
MMDetection Configuration File
Updating the Model Config File
Note: You don't need to change the default config. Here, we are only showing how to change any default value stored in the config file. As an example, we are showing how to update the loss_weight(s)
The original config files use the default loss_weight=1
.
# Get the weights_path
weights_fname = Path(weights_url).name
weights_path = f"{checkpoints_dir}/{weights_fname}"
weights_path
cfg_filepath
from mmcv import Config
cfg = Config.fromfile(cfg_filepath)
# cfg.model.bbox_head
'checkpoints/retinanet_r50_fpn_1x_coco_20200130-c2398f9e.pth'
'mmdetection/configs/_base_/models/retinanet_r50_fpn.py'
Default loss_weigt
(s) = 1
# cfg.model.bbox_head.loss_cls, cfg.model.bbox_head.loss_bbox
Updating Model Config attributes
Note: We can update any attributes defined in the python file where those attributes are populated
In this example, we are updating the loss_weigt
(s) with the following values
# cfg.model.bbox_head.loss_cls.loss_weight = 0.8
# cfg.model.bbox_head.loss_bbox.loss_weight = 2
# cfg.model.bbox_head.loss_cls, cfg.model.bbox_head.loss_bbox
Creating a Model
weights_path
model = model_type.model(cfg, num_classes=len(parser.class_map), weights_path=weights_path)
'checkpoints/retinanet_r50_fpn_1x_coco_20200130-c2398f9e.pth'
Training
Training - Fastai
learn = model_type.fastai.learner(dls=[train_dl, valid_dl], model=model, splitter=fastai.trainable_params)
learn.lr_find()
SuggestedLRs(lr_min=5.754399462603033e-05, lr_steep=0.00010964782268274575)
learn.fine_tune(20, 3e-4)
epoch | train_loss | valid_loss | time |
---|---|---|---|
0 | 1.192961 | 0.856517 | 00:06 |
epoch | train_loss | valid_loss | time |
---|---|---|---|
0 | 0.692504 | 0.536435 | 00:05 |
1 | 0.568239 | 0.376043 | 00:05 |
2 | 0.492997 | 0.340800 | 00:05 |
3 | 0.432057 | 0.257431 | 00:05 |
4 | 0.383656 | 0.228422 | 00:05 |
5 | 0.351317 | 0.213184 | 00:05 |
6 | 0.333522 | 0.237355 | 00:05 |
7 | 0.310363 | 0.181096 | 00:05 |
8 | 0.294222 | 0.193166 | 00:05 |
9 | 0.273112 | 0.145784 | 00:05 |
10 | 0.252149 | 0.161463 | 00:05 |
11 | 0.236207 | 0.139669 | 00:05 |
12 | 0.219127 | 0.149458 | 00:05 |
13 | 0.207551 | 0.131850 | 00:05 |
14 | 0.198437 | 0.144513 | 00:05 |
15 | 0.189129 | 0.133218 | 00:05 |
16 | 0.177614 | 0.119760 | 00:05 |
17 | 0.166518 | 0.116883 | 00:05 |
18 | 0.158119 | 0.114125 | 00:05 |
19 | 0.151817 | 0.114225 | 00:05 |
Training - Pytorch-Lightning
class LitModel(model_type.lightning.ModelAdapter):
def configure_optimizers(self):
return Adam(self.parameters(), lr=1e-4)
lit_model = LitModel(model)
trainer = pl.Trainer(max_epochs=10, gpus=1, num_sanity_val_steps=0, check_val_every_n_epoch=1)
lr_finder = trainer.tuner.lr_find(lit_model, train_dl, valid_dl)
/usr/local/lib/python3.6/dist-packages/pytorch_lightning/utilities/distributed.py:50: UserWarning: You have set progress_bar_refresh_rate < 20 on Google Colab. This may crash. Consider using progress_bar_refresh_rate >= 20 in Trainer.
warnings.warn(*args, **kwargs)
GPU available: True, used: True
TPU available: None, using: 0 TPU cores
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
fig = lr_finder.plot(suggest=True)
fig.show()
| Name | Type | Params
------------------------------------
0 | model | RetinaNet | 36.4 M
------------------------------------
36.2 M Trainable params
225 K Non-trainable params
36.4 M Total params
Finding best initial lr: 0%| | 0/100 [00:00<?, ?it/s]
LR finder stopped early due to diverging loss.
Restored states from the checkpoint file at /content/lr_find_temp_model.ckpt
trainer.fit(lit_model, train_dl, valid_dl)
Show Results
model_type.show_results(model, valid_ds, detection_threshold=.5)
Inference
infer_dl = model_type.infer_dl(valid_ds, batch_size=1, shuffle=False)
samples, preds = model_type.predict_dl(model, infer_dl)
show_preds(
samples=samples[:6],
preds=preds[:6],
class_map=parser.class_map,
denormalize_fn=denormalize_imagenet,
ncols=3,
)
0%| | 0/26 [00:00<?, ?it/s]
Happy Learning!
If you need any assistance, feel free to join our forum.