def test_fixed_knobs(self, budget):
     knob_config = {
         'fixed': FixedKnob('fixed'),
         'fixed2': FixedKnob(2),
         'early_stop': PolicyKnob('EARLY_STOP')
     }
     advisor = make_advisor(knob_config, budget)
     assert isinstance(advisor, FixedAdvisor)
 def test_standard_knobs(self, budget):
     knob_config = {
         'int': IntegerKnob(2, 128),
         'float': FloatKnob(1e-5, 1e-1, is_exp=True),
         'cat': CategoricalKnob([16, 32, 64, 128]),
     }
     advisor = make_advisor(knob_config, budget)
     assert isinstance(advisor, BayesOptAdvisor)
 def test_arch_knobs_with_standard_knobs(self, budget, arch_knob):
     knob_config = {
         'arch': arch_knob,
         'float': FloatKnob(1e-5, 1e-1, is_exp=True),
         'cat': CategoricalKnob([16, 32, 64, 128]),
     }
     advisor = make_advisor(knob_config, budget)
     assert isinstance(advisor, RandomAdvisor)
 def test_standard_knobs_with_params_sharing(self, budget):
     knob_config = {
         'int': IntegerKnob(2, 128),
         'float': FloatKnob(1e-5, 1e-1, is_exp=True),
         'cat': CategoricalKnob([16, 32, 64, 128]),
         'share_params': PolicyKnob('SHARE_PARAMS')
     }
     advisor = make_advisor(knob_config, budget)
     assert isinstance(advisor, BayesOptWithParamSharingAdvisor)
 def test_standard_knobs_with_early_stop(self, budget):
     knob_config = {
         'int': IntegerKnob(2, 128),
         'float': FloatKnob(1e-5, 1e-1, is_exp=True),
         'cat': CategoricalKnob([16, 32, 64, 128]),
         'early_stop': PolicyKnob('EARLY_STOP')
     }
     advisor = make_advisor(knob_config, budget)
     assert isinstance(advisor, BayesOptAdvisor)
 def test_arch_knob_without_enas_policies(self, day_budget, arch_knob):
     knob_config = {
         'arch': arch_knob,
         'downscale': PolicyKnob('DOWNSCALE'),
         'early_stop': PolicyKnob('EARLY_STOP'),
         'skip_train': PolicyKnob('SKIP_TRAIN')
         # No quick eval
     }
     advisor = make_advisor(knob_config, day_budget)
     assert isinstance(advisor, RandomAdvisor)
Exemple #7
0
    def _make_advisor(self):
        clazz = self._monitor.model_class
        budget = self._monitor.budget

        # Retrieve knob config
        knob_config = clazz.get_knob_config()
        advisor = make_advisor(knob_config, budget)
        logger.info(f'Using advisor "{type(advisor).__name__}"...')

        return advisor
 def test_arch_knob_without_budget(self, budget, arch_knob):
     knob_config = {
         'arch': arch_knob,
         'fixed': FixedKnob('fixed'),
         'downscale': PolicyKnob('DOWNSCALE'),
         'early_stop': PolicyKnob('EARLY_STOP'),
         'skip_train': PolicyKnob('SKIP_TRAIN'),
         'quick_eval': PolicyKnob('QUICK_EVAL')
     }
     advisor = make_advisor(knob_config, budget)
     assert isinstance(advisor, RandomAdvisor)
 def test_arch_knob_with_enas_policies(self, day_budget, arch_knob):
     knob_config = {
         'arch': arch_knob,
         'fixed': FixedKnob('fixed'),
         'share_params': PolicyKnob('SHARE_PARAMS'),
         'downscale': PolicyKnob('DOWNSCALE'),
         'early_stop': PolicyKnob('EARLY_STOP'),
         'skip_train': PolicyKnob('SKIP_TRAIN'),
         'quick_eval': PolicyKnob('QUICK_EVAL')
     }
     advisor = make_advisor(knob_config, day_budget)
     assert isinstance(advisor, EnasAdvisor)
Exemple #10
0
def tune_model(
        py_model_class: Type[BaseModel],
        train_dataset_path: str,
        val_dataset_path: str,
        test_dataset_path: str = None,
        budget: Budget = None,
        train_args: Dict[str, any] = None) -> (Dict[str, Any], float, Params):

    worker_id = 'local'

    # Note start time
    start_time = time.time()

    # Retrieve config of model
    _print_header('Checking model configuration...')
    knob_config = py_model_class.get_knob_config()
    _check_knob_config(knob_config)

    # Read knob values from CLI args
    _print_header('Starting trials...')
    knobs_from_args = _maybe_read_knobs_from_args(knob_config)

    # Read budget options from CLI args
    budget_from_args = _maybe_read_budget_from_args()
    budget = {**(budget or {}), **budget_from_args}
    inform_user(f'Using budget {budget}...')

    # Make advisor
    advisor = make_advisor(knob_config, budget)
    inform_user(f'Using advisor "{type(advisor).__name__}"...')

    # Create caches & stores
    param_store: ParamStore = FileParamStore()
    param_cache: ParamCache = ParamCache()
    train_cache: TrainCache = TrainCache()

    # Variables to track over trials
    best_model_score = -1
    best_trial_no = 0
    best_model_test_score = None
    best_proposal = None
    best_store_params_id = None

    # Train worker tells advisor that it is free
    train_cache.add_worker(worker_id)

    # Until there's no more proposals, keep conducting trials
    trial_no = 0
    while True:
        trial_no += 1

        # Advisor checks free workers
        worker_ids = train_cache.get_workers()
        assert worker_id in worker_ids

        # Advisor checks worker doesn't already have a proposal
        proposal = train_cache.get_proposal(worker_id)
        assert proposal is None

        # Advisor sends a proposal to worker
        # Overriding knobs from args
        proposal = advisor.propose(worker_id, trial_no)
        if proposal is None:
            print('No more proposals from advisor - to stop training')
            break
        proposal.knobs = {**proposal.knobs, **knobs_from_args}
        train_cache.create_proposal(worker_id, proposal)

        # Worker receives proposal
        proposal = train_cache.get_proposal(worker_id)
        assert proposal is not None

        # Worker starts trial
        _print_header(f'Trial #{trial_no}')
        print('Proposal from advisor:', proposal)

        # Worker loads model
        model_inst = py_model_class(**proposal.knobs)

        # Worker pulls shared params
        shared_params = _pull_shared_params(proposal, param_cache)

        # Worker trains model
        print('Training model...')
        model_inst.train(train_dataset_path,
                         shared_params=shared_params,
                         **(train_args or {}))

        # Worker evaluates model
        result = _evaluate_model(model_inst, proposal, val_dataset_path)

        # Worker caches/saves model parameters
        store_params_id = _save_model(model_inst, proposal, result,
                                      param_cache, param_store)

        # Update best saved model
        if result.score is not None and store_params_id is not None and result.score > best_model_score:
            inform_user(
                'Best saved model so far! Beats previous best of score {}!'.
                format(best_model_score))
            best_store_params_id = store_params_id
            best_proposal = proposal
            best_model_score = result.score
            best_trial_no = trial_no

            # Test best model, if test dataset provided
            if test_dataset_path is not None:
                print('Evaluating new best model on test dataset...')
                best_model_test_score = model_inst.evaluate(test_dataset_path)
                inform_user(
                    'Score on test dataset: {}'.format(best_model_test_score))

        # Worker sends result to advisor
        print('Giving feedback to advisor...')
        train_cache.create_result(worker_id, result)
        train_cache.delete_proposal(worker_id)

        # Advisor receives result
        # Advisor ingests feedback
        result = train_cache.take_result(worker_id)
        assert result is not None
        advisor.feedback(worker_id, result)

        # Destroy model
        model_inst.destroy()

    # Train worker tells advisor that it is no longer free
    train_cache.delete_worker(worker_id)

    # Declare best model
    if best_proposal is not None:
        inform_user('Best trial #{} has knobs {} with score of {}'.format(
            best_trial_no, best_proposal.knobs, best_model_score))
        if best_model_test_score is not None:
            inform_user(
                '...with test score of {}'.format(best_model_test_score))

    # Load params for best model
    best_params = None
    if best_store_params_id is not None:
        best_params = param_store.load(best_store_params_id)

    # Teardown model class
    print('Running model class teardown...')
    py_model_class.teardown()

    # Print duration
    duration = time.time() - start_time
    print('Tuning took a total of {}s'.format(duration))

    return (best_proposal, best_model_test_score, best_params)
Exemple #11
0
def validate_model_class(model_class,
                         train_dataset_uri,
                         test_dataset_uri,
                         task,
                         queries=[],
                         knobs=None):
    '''
    Validates whether a model class is properly defined. 
    The model instance's methods will be called in an order similar to that in Rafiki.

    :param str train_dataset_uri: URI of the train dataset for testing the training of model
    :param str test_dataset_uri: URI of the test dataset for testing the evaluating of model
    :param str task: Task type of model
    :param list[any] queries: List of queries for testing predictions with the trained model
    :param knobs: Knobs to train the model with. If not specified, knobs from an advisor will be used
    :type knobs: dict[str, any]
    :returns: The trained model
    '''

    print('Testing instantiation of model...')
    model_inst = model_class()

    print('Testing getting of model\'s knob config...')
    knob_config = model_inst.get_knob_config()

    if not isinstance(knob_config, dict):
        raise InvalidModelClassException(
            '`get_knob_config()` should return a dict[str, any]')

    if 'knobs' not in knob_config:
        raise InvalidModelClassException(
            '`knob_config` should have a \'knobs\' key')

    advisor = make_advisor(knob_config)

    if knobs is None:
        knobs = advisor.propose()

    print('Testing initialization of model...')
    print('Using knobs: {}'.format(knobs))
    model_inst.init(knobs)

    print('Testing training of model...')
    model_inst.train(train_dataset_uri, task)

    print('Testing evaluation of model...')
    score = model_inst.evaluate(test_dataset_uri, task)

    if not isinstance(score, float):
        raise InvalidModelClassException('`evaluate()` should return a float!')

    print('Score: {}'.format(score))

    print('Testing dumping of parameters of model...')
    parameters = model_inst.dump_parameters()

    if not isinstance(parameters, dict):
        raise InvalidModelClassException(
            '`dump_parameters()` should return a dict[str, any]')

    try:
        json.dumps(parameters)
    except Exception:
        traceback.print_stack()
        raise InvalidModelClassException(
            '`parameters` should be JSON serializable')

    print('Testing destroying of model...')
    model_inst.destroy()

    print('Testing loading of parameters of model...')
    model_inst = model_class()
    model_inst.init(knobs)
    model_inst.load_parameters(parameters)

    print('Testing retrieving of predict label mapping...')
    predict_label_mapping = model_inst.get_predict_label_mapping()

    if not isinstance(predict_label_mapping, dict):
        raise InvalidModelClassException(
            '`get_predict_label_mapping()` should return a dict[int, str]')

    print('Testing predictions with model...')
    print('Using queries: {}'.format(queries))
    predictions = model_inst.predict(queries)
    predictions = ensemble_predictions([predictions], [predict_label_mapping],
                                       task)

    try:
        for prediction in predictions:
            prediction = parse_model_prediction(prediction)
            json.dumps(prediction)

    except Exception:
        traceback.print_stack()
        raise InvalidModelClassException(
            'Each `prediction` should be JSON serializable')

    print('Predictions: {}'.format(predictions))

    print('The model definition is valid!')

    return model_inst
 def test_arch_knobs(self, budget, arch_knob):
     knob_config = {'arch': arch_knob, 'arch2': arch_knob}
     advisor = make_advisor(knob_config, budget)
     assert isinstance(advisor, RandomAdvisor)