03. Train classifier or detector with HPO using GluonCV Auto task

The previous image classification example shows the basic usages to train/evaluate/predict using estimators provided by gluoncv.auto.estimators. Similarly, you can train object detectors using SSDEstimator, YOLOv3Estimator, CenterNetEstimator, FasterRCNNEstimator.

In this tutorial, we will move forward a little bit, into the hyper-parameter tunning space! We will show you how to offload an experiment to the backend HPO searcher, to offer better result if computational cost is abundant.

HPO with GluonCV auto tasks

from gluoncv.auto.tasks.image_classification import ImageClassification
from gluoncv.auto.tasks.object_detection import ObjectDetection
import autogluon.core as ag

In this tutorial, we use a small sample dataset for object detection For image classification, please refer to 02. Train Image Classification with Auto Estimator.

train = ObjectDetection.Dataset.from_voc(
    'https://autogluon.s3.amazonaws.com/datasets/tiny_motorbike.zip')
train, val, test = train.random_split(val_size=0.1, test_size=0.1)

Out:

tiny_motorbike/
├── Annotations/
├── ImageSets/
└── JPEGImages/

Define search space

We show a minimal example to run HPO for object detection. For image classification, the code change is negalected, just swap the dataset and ObjectDetection to ImageClassification.

We use very conservative search space to reduce CI runtime, and we will cap the number of trials to be 1 to reduce building time, feel free to adjust the num_trials, time_limits, epochs and tune other search spaces with ag.Categorical, ag.Int, ag.Real for example in order to achieve better results

time_limits = 60 * 60  # 1hr
search_args = {'lr': ag.Categorical(1e-3, 1e-2),
               'num_trials': 1,
               'epochs': 2,
               'num_workers': 16,
               'batch_size': ag.Categorical(4, 8),
               'ngpus_per_trial': 1,
               'search_strategy': 'random',
               'time_limits': time_limits}

Construct a object detection task based on the config.

task = ObjectDetection(search_args)

Automatically fit a model.

detector = task.fit(train, val)

Out:

/usr/local/lib/python3.6/dist-packages/mxnet/gluon/block.py:1512: UserWarning: Cannot decide type for the following arguments. Consider providing them as input:
        data: None
  input_sym_arg_type = in_param.infer_type()[0]
Downloading /root/.mxnet/models/ssd_512_resnet50_v1_coco-c4835162.zip from https://apache-mxnet.s3-accelerate.dualstack.amazonaws.com/gluon/models/ssd_512_resnet50_v1_coco-c4835162.zip...

  0%|          | 0/181188 [00:00<?, ?KB/s]
  0%|          | 102/181188 [00:00<03:45, 804.38KB/s]
  0%|          | 510/181188 [00:00<01:21, 2222.93KB/s]
  1%|1         | 2182/181188 [00:00<00:24, 7211.57KB/s]
  4%|4         | 7549/181188 [00:00<00:07, 22966.10KB/s]
  8%|7         | 13735/181188 [00:00<00:04, 35658.31KB/s]
 12%|#2        | 22266/181188 [00:00<00:03, 51445.39KB/s]
 16%|#6        | 29643/181188 [00:00<00:02, 58417.34KB/s]
 21%|##1       | 38238/181188 [00:00<00:02, 66907.39KB/s]
 25%|##5       | 45503/181188 [00:00<00:01, 68662.98KB/s]
 30%|##9       | 53467/181188 [00:01<00:01, 71512.42KB/s]
 34%|###4      | 61721/181188 [00:01<00:01, 74835.29KB/s]
 38%|###8      | 69274/181188 [00:01<00:01, 74705.17KB/s]
 43%|####2     | 77166/181188 [00:01<00:01, 75966.98KB/s]
 47%|####6     | 84798/181188 [00:01<00:01, 74113.26KB/s]
 51%|#####1    | 93002/181188 [00:01<00:01, 76167.78KB/s]
 56%|#####5    | 100646/181188 [00:01<00:01, 75728.33KB/s]
 60%|#####9    | 108620/181188 [00:01<00:00, 76911.50KB/s]
 64%|######4   | 116631/181188 [00:01<00:00, 77858.78KB/s]
 69%|######8   | 124429/181188 [00:02<00:00, 76685.95KB/s]
 73%|#######3  | 132829/181188 [00:02<00:00, 78842.09KB/s]
 78%|#######7  | 140725/181188 [00:02<00:00, 66991.48KB/s]
 82%|########1 | 147734/181188 [00:02<00:00, 65527.36KB/s]
 85%|########5 | 154661/181188 [00:02<00:00, 66526.31KB/s]
 90%|########9 | 162901/181188 [00:02<00:00, 70911.20KB/s]
 94%|#########3| 170142/181188 [00:02<00:00, 69750.56KB/s]
 98%|#########8| 177589/181188 [00:02<00:00, 69904.37KB/s]
181189KB [00:02, 64041.11KB/s]
/usr/local/lib/python3.6/dist-packages/mxnet/gluon/block.py:1512: UserWarning: Cannot decide type for the following arguments. Consider providing them as input:
        data: None
  input_sym_arg_type = in_param.infer_type()[0]
/usr/local/lib/python3.6/dist-packages/mxnet/gluon/block.py:1512: UserWarning: Cannot decide type for the following arguments. Consider providing them as input:
        data: None
  input_sym_arg_type = in_param.infer_type()[0]

Evaluate the final model on test set.

test_map = detector.evaluate(test)
print("mAP on test dataset:")
for category, score in zip(*test_map):
    print(category, score)

Out:

mAP on test dataset:
motorbike 0.557581493355552
bus nan
boat nan
cow 0.0
person 0.4424933160156914
bicycle nan
car 1.0000000000000002
dog nan
chair nan
pottedplant nan
mAP 0.5000187023428109

Save our final model.

detector.save('detector.pkl')

load the model and run some prediction

detector2 = ObjectDetection.load('detector.pkl')
pred = detector2.predict(test.iloc[0]['image'])
print(pred)

Out:

/usr/local/lib/python3.6/dist-packages/mxnet/gluon/block.py:1512: UserWarning: Cannot decide type for the following arguments. Consider providing them as input:
        data: None
  input_sym_arg_type = in_param.infer_type()[0]
   predict_class  ...                                       predict_rois
0            car  ...  {'xmin': 0.2950457036495209, 'ymin': 0.1961218...
1            car  ...  {'xmin': 0.1063406690955162, 'ymin': 0.1650179...
2         person  ...  {'xmin': 0.9072394967079163, 'ymin': 0.0386775...
3            car  ...  {'xmin': 0.497192919254303, 'ymin': 0.32654511...
4         person  ...  {'xmin': 0.1039300486445427, 'ymin': 0.0214233...
..           ...  ...                                                ...
76        person  ...  {'xmin': 0.9762840270996094, 'ymin': 0.0143931...
77     motorbike  ...  {'xmin': 0.7977412939071655, 'ymin': 0.1901351...
78        person  ...  {'xmin': 0.14319948852062225, 'ymin': 0.497429...
79        person  ...  {'xmin': 0.7110783457756042, 'ymin': 0.1970322...
80        person  ...  {'xmin': 0.1752810776233673, 'ymin': 0.1064255...

[81 rows x 3 columns]

Pin the object detector algorithms

By default, the scheduler choose algorithms from SSDEstimator, YOLOv3Estimator, CenterNetEstimator, FasterRCNNEstimator. If you want to train a specific algorithm during HPO, you may pin the estimator.

For example, this tells the searcher to use YOLOv3 models only

search_args = {'lr': ag.Categorical(1e-3, 1e-2),
               'num_trials': 1,
               'estimator': 'yolo3',
               'epochs': 2,
               'num_workers': 16,
               'batch_size': ag.Categorical(4, 8),
               'ngpus_per_trial': 1,
               'search_strategy': 'random',
               'time_limits': time_limits}

Specify models for transfer learning

Allowing transfer learning from previous trained models is the key to fast convergence and high performance model with very limited training data. By default, we enable transfer learning from object detection networks trained on COCO dataset, downloaded automatically from gluoncv model zoo.

The selected pre-trained models by default is ‘ssd_512_resnet50_v1_coco’, ‘yolo3_darknet53_coco’, ‘faster_rcnn_resnet50_v1b_coco’ and ‘center_net_resnet50_v1b_coco’.

You may continue to use them, or replace with your favarite models, e.g.,

search_args = {'lr': ag.Categorical(1e-3, 1e-2),
               'num_trials': 1,
               'transfer': ag.Categorical('ssd_512_mobilenet1.0_coco',
                                          'yolo3_mobilenet1.0_coco'),
               'epochs': 10,
               'num_workers': 16,
               'batch_size': ag.Categorical(4, 8),
               'ngpus_per_trial': 1,
               'search_strategy': 'random',
               'time_limits': time_limits}

Now you are ready to use HPO feature in gluoncv.auto! Stay tuned as we are rolling out more features and tutorials for faster and more convenient training/test/inference experiences.

Total running time of the script: ( 1 minutes 0.965 seconds)

Gallery generated by Sphinx-Gallery