コード例 #1
0
def test_local_grid_searcher_categorical():
    search_space = dict(
        a=Categorical('a', 7, ['hello', 2]),
        b=Categorical(12, 15),
    )

    searcher = LocalGridSearcher(search_space=search_space)

    expected_config_1 = {'b': 12, 'a': 'a'}
    expected_config_2 = {'b': 15, 'a': 'a'}
    expected_config_3 = {'b': 12, 'a': 7}
    expected_config_4 = {'b': 15, 'a': 7}
    expected_config_5 = {'b': 12, 'a': ['hello', 2]}
    expected_config_6 = {'b': 15, 'a': ['hello', 2]}

    config1 = searcher.get_config()
    searcher.update(config1, reward=0.2)
    assert searcher.get_reward(config1) == 0.2
    assert searcher.get_best_reward() == 0.2
    assert searcher.get_best_config() == config1

    config2 = searcher.get_config()

    config3 = searcher.get_config()

    config4 = searcher.get_config()
    searcher.update(config4, reward=0.1)
    assert searcher.get_reward(config4) == 0.1
    assert searcher.get_best_reward() == 0.2
    assert searcher.get_best_config() == config1
    searcher.update(config4, reward=0.5)
    assert searcher.get_reward(config4) == 0.5
    assert searcher.get_best_reward() == 0.5
    assert searcher.get_best_config() == config4

    config5 = searcher.get_config()

    config6 = searcher.get_config()

    assert expected_config_1 == config1
    assert expected_config_2 == config2
    assert expected_config_3 == config3
    assert expected_config_4 == config4
    assert expected_config_5 == config5
    assert expected_config_6 == config6

    assert len(searcher._results) == 2

    try:
        searcher.get_config()
    except AssertionError:
        pass
    else:
        raise AssertionError(
            'GridSearcher should error due to being out of configs')
コード例 #2
0
def test_object_detection_estimator_transfer():
    dataset = get_dataset('https://autogluon.s3.amazonaws.com/datasets/tiny_motorbike.zip')
    train_data, val_data, test_data = dataset.random_split(val_size=0.3, test_size=0.2, random_state=0)
    task = ObjectDetection({'num_trials': 1, 'epochs': 1, 'transfer': Categorical('yolo3_darknet53_coco', 'ssd_512_resnet50_v1_voc'), 'estimator': 'ssd', 'batch_size': 4})
    detector = task.fit(train_data)
    assert task.fit_summary().get('valid_map', 0) > 0
    test_result = detector.predict(test_data)
コード例 #3
0
def test_search_space_dot_key():
    search_space = {'model.name': Categorical('mxnet', 'pytorch')}

    def train_fn(args, reporter):
        assert args['model.name'] == 'mxnet' or args['model.name'] == 'pytorch'

    scheduler = LocalSequentialScheduler(train_fn, search_space=search_space, num_trials=2)
    scheduler.run()
    scheduler.join_jobs()
コード例 #4
0
    def test_local_searcher_pickle(self):
        search_space = {1: Categorical(1, 2), 2: Categorical(1, 2)}
        searcher = LocalSearcher(search_space=search_space)

        # Identical configs should have same pkl key, different configs should have different pkl keys
        config_1 = {1: 1, 2: 2}
        config_2 = {2: 2, 1: 1}
        config_diff = {1: 2, 2: 1}
        config_pkl_1 = searcher._pickle_config(config_1)
        config_pkl_2 = searcher._pickle_config(config_2)
        config_pkl_diff = searcher._pickle_config(config_diff)

        assert config_pkl_1 == config_pkl_2
        assert config_pkl_1 != config_pkl_diff

        config_unpkl = searcher._unpickle_config(config_pkl_1)
        config_unpkl_diff = searcher._unpickle_config(config_pkl_diff)

        assert config_unpkl == config_1
        assert config_unpkl == config_2
        assert config_unpkl_diff == config_diff
コード例 #5
0
def test_local_random_searcher():
    search_space = dict(
        a=Real(0, 1, default=0.2),
        b=Real(0.05, 1, default=0.4, log=True),
        c=Int(5, 15),
        d=Int(7, 23, default=16),
        e=Categorical('a', 7, ['hello', 2]),
    )

    searcher = LocalRandomSearcher(search_space=search_space)

    expected_config_1 = {'a': 0.2, 'b': 0.4, 'c': 5, 'd': 16, 'e': 'a'}
    expected_config_2 = {'a': 0.5488135039273248, 'b': 0.4260424000595025, 'c': 8, 'd': 10, 'e': 7}
    expected_config_3 = {'a': 0.6235636967859723, 'b': 0.15814742875130683, 'c': 12, 'd': 13, 'e': 'a'}
    expected_config_4 = {'a': 0.9636627605010293, 'b': 0.1577026248478398, 'c': 11, 'd': 14, 'e': ['hello', 2]}
    expected_config_5 = {'a': 0.5680445610939323, 'b': 0.800200824711684, 'c': 13, 'd': 16, 'e': 'a'}

    assert searcher.get_best_reward() == float("-inf")
    config1 = searcher.get_config()
    assert searcher.get_reward(config1) == float("-inf")
    assert searcher.get_best_reward() == float("-inf")
    searcher.update(config1, accuracy=0.2)
    assert searcher.get_reward(config1) == 0.2
    assert searcher.get_best_reward() == 0.2
    assert searcher.get_best_config() == config1

    config2 = searcher.get_config()

    config3 = searcher.get_config()

    config4 = searcher.get_config()
    searcher.update(config4, accuracy=0.1)
    assert searcher.get_reward(config4) == 0.1
    assert searcher.get_best_reward() == 0.2
    assert searcher.get_best_config() == config1
    searcher.update(config4, accuracy=0.5)
    assert searcher.get_reward(config4) == 0.5
    assert searcher.get_best_reward() == 0.5
    assert searcher.get_best_config() == config4

    config5 = searcher.get_config()

    assert expected_config_1 == config1
    assert expected_config_2 == config2
    assert expected_config_3 == config3
    assert expected_config_4 == config4
    assert expected_config_5 == config5

    assert len(searcher._results) == 5
コード例 #6
0
def test_search_space():
    search_space = dict(
        a=Real(1e-3, 1e-2, log=True),
        b=Real(1e-3, 1e-2),
        c=Int(1, 10),
        d=Categorical('a', 'b', 'c', 'd'),
    )

    def train_fn(args, reporter):
        a, b, c, d = args['a'], args['b'], args['c'], args['d']
        assert 1e-2 >= a >= 1e-3
        assert 1e-2 >= b >= 1e-3
        assert 10 >= c >= 1
        assert d in ['a', 'b', 'c', 'd']
        reporter(epoch=1, reward=0)

    scheduler = LocalSequentialScheduler(train_fn,
                                         search_space=search_space,
                                         num_trials=10,
                                         time_attr='epoch')
    scheduler.run()
    scheduler.join_jobs()
コード例 #7
0
    def fit(dataset='voc',
            net=Categorical('mobilenet1.0'),
            meta_arch='yolo3',
            lr=Categorical(5e-4, 1e-4),
            loss=gluon.loss.SoftmaxCrossEntropyLoss(),
            split_ratio=0.8,
            batch_size=16,
            epochs=50,
            num_trials=None,
            time_limits=None,
            nthreads_per_trial=12,
            num_workers=32,
            ngpus_per_trial=1,
            hybridize=True,
            scheduler_options=None,
            search_strategy='random',
            search_options=None,
            verbose=False,
            transfer='coco',
            resume='',
            checkpoint='checkpoint/exp1.ag',
            visualizer='none',
            dist_ip_addrs=None,
            auto_search=True,
            seed=223,
            data_shape=416,
            start_epoch=0,
            lr_mode='step',
            lr_decay=0.1,
            lr_decay_period=0,
            lr_decay_epoch='160,180',
            warmup_lr=0.0,
            warmup_epochs=2,
            warmup_iters=1000,
            warmup_factor=1. / 3.,
            momentum=0.9,
            wd=0.0005,
            log_interval=100,
            save_prefix='',
            save_interval=10,
            val_interval=1,
            num_samples=-1,
            no_random_shape=False,
            no_wd=False,
            mixup=False,
            no_mixup_epochs=20,
            label_smooth=False,
            syncbn=False,
            reuse_pred_weights=True,
            **kwargs):
        """
        Fit object detection models.

        Parameters
        ----------
        dataset : str or :class:`autogluon.task.ObjectDectection.Dataset`
            Training dataset containing images and corresponding object bounding boxes.
        net : str, :class:`autogluon.space.AutoGluonObject`
            Which existing neural network base models to consider as candidates.
        meta_arch : str
            Meta architecture of the model. Currently support YoloV3 (Default) and FasterRCNN.
            YoloV3 is faster, while FasterRCNN is more accurate.
        lr : float or :class:`autogluon.space`
            The learning rate to use in each update of the neural network weights during training.
        loss : mxnet.gluon.loss
            Loss function used during training of the neural network weights.
        split_ratio : float
            Fraction of dataset to hold-out during training in order to tune hyperparameters (i.e. validation data).
            The final returned model may be fit to all of the data (after hyperparameters have been selected).
        batch_size : int
            How many images to group in each mini-batch during gradient computations in training.
        epochs : int
            How many epochs to train the neural networks for at most.
        num_trials : int
            Maximal number of hyperparameter configurations to try out.
        time_limits : int
            Approximately how long should `fit()` should run for (wallclock time in seconds).
            `fit()` will stop training new models after this amount of time has elapsed (but models which have already started training will continue to completion).
        nthreads_per_trial : int
            How many CPUs to use in each trial (ie. single training run of a model).
        num_workers : int
            How many CPUs to use for data loading during training of a model.
        ngpus_per_trial : int
            How many GPUs to use in each trial (ie. single training run of a model). 
        hybridize : bool
            Whether or not the MXNet neural network should be hybridized (for increased efficiency).
        scheduler_options : dict
            Extra arguments passed to __init__ of scheduler, to configure the
            orchestration of training jobs during hyperparameter-tuning.
        search_strategy : str
            Which hyperparameter search algorithm to use.
            Options include: 'random' (random search), 'skopt' (SKopt Bayesian
            optimization), 'grid' (grid search), 'hyperband' (Hyperband random),
            'rl' (reinforcement learner).
        search_options : dict
            Auxiliary keyword arguments to pass to the searcher that performs
            hyperparameter optimization.
        verbose : bool
            Whether or not to print out intermediate information during training.
        resume : str
            Path to checkpoint file of existing model, from which model training
            should resume.
            If not empty, we also start the hyperparameter search from the state
            loaded from checkpoint.
        checkpoint : str or None
            State of hyperparameter search is stored to this local file
        visualizer : str
            Describes method to visualize training progress during `fit()`. Options: ['mxboard', 'tensorboard', 'none']. 
        dist_ip_addrs : list
            List of IP addresses corresponding to remote workers, in order to leverage distributed computation.
        auto_search : bool
            If True, enables automatic suggestion of network types and hyper-parameter ranges adaptively based on provided dataset.
        seed : int
            Random seed to set for reproducibility.
        data_shape : int
            Shape of the image data.
        start_epoch : int
            Which epoch we begin training from 
            (eg. if we resume training of an existing model, then this
            argument may be set to the number of epochs the model has already been trained for previously).
        lr_mode : str
            What sort of learning rate schedule should be followed during training.
        lr_decay : float
            How much learning rate should be decayed during training.
        lr_decay_period : int
            How often learning rate should be decayed during training.
        warmup_lr : float
            Learning rate to use during warm up period at the start of training.
        warmup_epochs : int
            How many initial epochs constitute the "warm up" period of model training.
        warmup_iters : int
            How many initial iterations constitute the "warm up" period of model training.
            This is used by R-CNNs
        warmup_factor : float
            warmup factor of target lr. initial lr starts from target lr * warmup_factor
        momentum : float or  :class:`autogluon.space`
            Momentum to use in optimization of neural network weights during training.
        wd : float or :class:`autogluon.space`
            Weight decay to use in optimization of neural network weights during training.
        log_interval : int
            Log results every so many epochs during training.
        save_prefix : str
            Prefix to append to file name for saved model.
        save_interval : int
            Save a copy of model every so many epochs during training.
        val_interval : int
            Evaluate performance on held-out validation data every so many epochs during training.
        no_random_shape : bool
            Whether random shapes should not be used.
        no_wd : bool
            Whether weight decay should be turned off.
        mixup : bool
            Whether or not to utilize mixup data augmentation strategy.
        no_mixup_epochs : int
            If using mixup, we first train model for this many epochs without mixup data augmentation.
        label_smooth : bool
            Whether or not to utilize label smoothing.
        syncbn : bool
            Whether or not to utilize synchronized batch normalization.
        
        Returns
        -------
            :class:`autogluon.task.object_detection.Detector` object which can make predictions on new data and summarize what happened during `fit()`.
        
        Examples
        --------
        >>> from autogluon.vision.object_detection import ObjectDetection as task
        >>> detector = task.fit(dataset = 'voc', net = 'mobilenet1.0',
        >>>                     time_limits = 600, ngpus_per_trial = 1, num_trials = 1)
        """
        assert search_strategy not in {'bayesopt', 'bayesopt_hyperband'}, \
            "search_strategy == 'bayesopt' or 'bayesopt_hyperband' not yet supported"
        if auto_search:
            # The strategies can be injected here, for example: automatic suggest some hps
            # based on the dataset statistics
            pass

        nthreads_per_trial = get_cpu_count(
        ) if nthreads_per_trial > get_cpu_count() else nthreads_per_trial
        if ngpus_per_trial > get_gpu_count():
            logger.warning(
                "The number of requested GPUs is greater than the number of available GPUs."
            )
        ngpus_per_trial = get_gpu_count(
        ) if ngpus_per_trial > get_gpu_count() else ngpus_per_trial

        # If only time_limits is given, the scheduler starts trials until the
        # time limit is reached
        if num_trials is None and time_limits is None:
            num_trials = 2

        train_object_detection.register_args(
            meta_arch=meta_arch,
            dataset=dataset,
            net=net,
            lr=lr,
            loss=loss,
            num_gpus=ngpus_per_trial,
            batch_size=batch_size,
            split_ratio=split_ratio,
            epochs=epochs,
            num_workers=nthreads_per_trial,
            hybridize=hybridize,
            verbose=verbose,
            final_fit=False,
            seed=seed,
            data_shape=data_shape,
            start_epoch=0,
            transfer=transfer,
            lr_mode=lr_mode,
            lr_decay=lr_decay,
            lr_decay_period=lr_decay_period,
            lr_decay_epoch=lr_decay_epoch,
            warmup_lr=warmup_lr,
            warmup_epochs=warmup_epochs,
            warmup_iters=warmup_iters,
            warmup_factor=warmup_factor,
            momentum=momentum,
            wd=wd,
            log_interval=log_interval,
            save_prefix=save_prefix,
            save_interval=save_interval,
            val_interval=val_interval,
            num_samples=num_samples,
            no_random_shape=no_random_shape,
            no_wd=no_wd,
            mixup=mixup,
            no_mixup_epochs=no_mixup_epochs,
            label_smooth=label_smooth,
            resume=resume,
            syncbn=syncbn,
            reuse_pred_weights=reuse_pred_weights)

        # Backward compatibility:
        grace_period = kwargs.get('grace_period')
        if grace_period is not None:
            if scheduler_options is None:
                scheduler_options = {'grace_period': grace_period}
            else:
                assert 'grace_period' not in scheduler_options, \
                    "grace_period appears both in scheduler_options and as direct argument"
                scheduler_options = copy.copy(scheduler_options)
                scheduler_options['grace_period'] = grace_period
            logger.warning("grace_period is deprecated, use "
                           "scheduler_options={'grace_period': ...} instead")
        scheduler_options = compile_scheduler_options(
            scheduler_options=scheduler_options,
            search_strategy=search_strategy,
            search_options=search_options,
            nthreads_per_trial=nthreads_per_trial,
            ngpus_per_trial=ngpus_per_trial,
            checkpoint=checkpoint,
            num_trials=num_trials,
            time_out=time_limits,
            resume=(len(resume) > 0),
            visualizer=visualizer,
            time_attr='epoch',
            reward_attr='map_reward',
            dist_ip_addrs=dist_ip_addrs,
            epochs=epochs)
        results = BaseTask.run_fit(train_object_detection, search_strategy,
                                   scheduler_options)
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> finish model fitting")
        args = sample_config(train_object_detection.args,
                             results['best_config'])
        logger.info('The best config: {}'.format(results['best_config']))

        ngpus = get_gpu_count()
        ctx = [mx.gpu(i) for i in range(ngpus)] if ngpus > 0 else [mx.cpu()]
        model = get_network(args.meta_arch,
                            args.net,
                            dataset.init().get_classes(),
                            transfer,
                            ctx,
                            syncbn=args.syncbn)
        update_params(model, results.pop('model_params'))
        return Detector(model, results, checkpoint, args)
コード例 #8
0
    def test_local_searcher(self):
        search_space = {'param1': Categorical('hello', 'world'), 7: 42}
        searcher = LocalSearcher(search_space=search_space)

        config1 = {'param1': 'hello', 7: 42}
        config2 = {'param1': 'world', 7: 42}
        config_edge_case_1 = {'param1': 'world', 7: 0}
        config_invalid_2 = {'param1': 'invalid', 7: 42}
        config_invalid_3 = {'param1': 'hello'}
        config_invalid_4 = {7: 42}
        config_invalid_5 = {}
        config_invalid_6 = {'param1': 'hello', 7: 42, 'unknown_param': 7}
        config_invalid_7 = 0

        assert searcher.get_best_reward() == float("-inf")
        searcher.update(config1, reward=0.2)
        assert searcher.get_best_reward() == 0.2
        assert searcher.get_best_config() == config1

        assert searcher.get_results() == [({'param1': 'hello', 7: 42}, 0.2)]

        searcher.update(config1, reward=0.1)
        assert searcher.get_best_reward() == 0.1
        assert searcher.get_best_config() == config1

        assert searcher.get_results() == [({'param1': 'hello', 7: 42}, 0.1)]

        searcher.update(config2, reward=0.7)
        assert searcher.get_best_reward() == 0.7
        assert searcher.get_best_config() == config2

        assert searcher.get_results() == [({
            'param1': 'world',
            7: 42
        }, 0.7), ({
            'param1': 'hello',
            7: 42
        }, 0.1)]
        assert len(searcher._results) == 2
        # This config is technically invalid, but for performance reasons is allowed to avoid having to pickle compare static parameters.
        # Since the static parameter should be fixed, this config is treated as being equivalent to config2
        searcher.update(config_edge_case_1, reward=0)
        assert searcher.get_best_reward() == 0.1
        assert len(searcher._results) == 2
        self.assertRaises(AssertionError,
                          searcher.update,
                          config_invalid_2,
                          reward=0)
        self.assertRaises(AssertionError,
                          searcher.update,
                          config_invalid_3,
                          reward=0)
        self.assertRaises(AssertionError,
                          searcher.update,
                          config_invalid_4,
                          reward=0)
        self.assertRaises(AssertionError,
                          searcher.update,
                          config_invalid_5,
                          reward=0)
        self.assertRaises(AssertionError,
                          searcher.update,
                          config_invalid_6,
                          reward=0)
        self.assertRaises(AssertionError,
                          searcher.update,
                          config_invalid_7,
                          reward=0)
        self.assertRaises(AssertionError,
                          searcher.update,
                          config1,
                          reward='invalid_reward')
        assert len(searcher._results) == 2
        assert searcher.get_results() == [({
            'param1': 'hello',
            7: 42
        }, 0.1), ({
            'param1': 'world',
            7: 42
        }, 0)]
コード例 #9
0
 def kwspaces(self):
     return Categorical(*list(range(len(self.module_list))))
コード例 #10
0
import pytest

from autogluon.core.hpo.space_converter import RaySpaceConverterFactory
from autogluon.core.space import Space, Categorical, Real, Int, Bool
from ray import tune


@pytest.mark.parametrize('space, expected_space', [
    (Categorical([1, 2]), tune.choice([1, 2])),
    (Real(1, 2, log=True), tune.loguniform(1, 2)),
    (Real(1, 2, log=False), tune.uniform(1, 2)),
    (Int(1, 2), tune.randint(1, 3)),
    (Bool(), tune.randint(0, 2)),
])
def test_space_converter(space, expected_space):
    ray_space = RaySpaceConverterFactory.get_space_converter(
        space.__class__.__name__).convert(space)
    assert type(ray_space) == type(expected_space)