예제 #1
0
    def reserve_trial(self, score_handle=None):
        """Find *new* trials that exist currently in database and select one of
        them based on the highest score return from `score_handle` callable.

        :param score_handle: A way to decide which trial out of the *new* ones to
           to pick as *reserved*, defaults to a random choice.
        :type score_handle: callable

        :return: selected `Trial` object, None if could not find any.
        """
        if score_handle is not None and not callable(score_handle):
            raise ValueError("Argument `score_handle` must be callable with a `Trial`.")

        query = dict(
            experiment=self._id,
            status={'$in': ['new', 'suspended', 'interrupted']}
            )
        new_trials = Trial.build(self._db.read('trials', query))

        if not new_trials:
            return None

        if score_handle is not None and self.space:
            scores = list(map(score_handle,
                              map(lambda x: trial_to_tuple(x, self.space), new_trials)))
            scored_trials = zip(scores, new_trials)
            best_trials = filter(lambda st: st[0] == max(scores), scored_trials)
            new_trials = list(zip(*best_trials))[1]
        elif score_handle is not None:
            log.warning("While reserving trial: `score_handle` was provided, but "
                        "parameter space has not been defined yet.")

        selected_trial = random.sample(new_trials, 1)[0]

        # Query on status to ensure atomicity. If another process change the
        # status meanwhile, read_and_write will fail, because query will fail.
        query = {'_id': selected_trial.id, 'status': selected_trial.status}

        update = dict(status='reserved')

        if selected_trial.status == 'new':
            update["start_time"] = datetime.datetime.utcnow()

        selected_trial_dict = self._db.read_and_write(
            'trials', query=query, data=update)

        if selected_trial_dict is None:
            selected_trial = self.reserve_trial(score_handle=score_handle)
        else:
            selected_trial = Trial(**selected_trial_dict)

        return selected_trial
예제 #2
0
    def fetch_completed_trials(self):
        """Fetch recent completed trials that this `Experiment` instance has not
        yet seen.

        .. note:: It will return only those with `Trial.end_time` after
           `_last_fetched`, for performance reasons.

        :return: list of completed `Trial` objects
        """
        query = dict(experiment=self._id,
                     status='completed',
                     end_time={'$gte': self._last_fetched})
        completed_trials = Trial.build(self._db.read('trials', query))
        self._last_fetched = datetime.datetime.utcnow()

        return completed_trials
예제 #3
0
    def reserve_trial(self, score_handle=None):
        """Find *new* trials that exist currently in database and select one of
        them based on the highest score return from `score_handle` callable.

        :param score_handle: A way to decide which trial out of the *new* ones to
           to pick as *reserved*, defaults to a random choice.
        :type score_handle: callable

        :return: selected `Trial` object, None if could not find any.
        """
        if score_handle is not None and not callable(score_handle):
            raise ValueError(
                "Argument `score_handle` must be callable with a `Trial`.")

        query = dict(experiment=self._id,
                     status={'$in': ['new', 'suspended', 'interrupted']})
        new_trials = Trial.build(self._db.read('trials', query))

        if not new_trials:
            return None

        if score_handle is None:
            selected_trial = random.sample(new_trials, 1)[0]
        else:
            raise NotImplementedError(
                "scoring will be supported in the next iteration.")

        if selected_trial.status == 'new':
            selected_trial.start_time = datetime.datetime.utcnow()
        selected_trial.status = 'reserved'

        self._db.write('trials',
                       selected_trial.to_dict(),
                       query={'_id': selected_trial.id})

        return selected_trial
예제 #4
0
 def test_build_trials(self, exp_config):
     """Convert to objects form using `Trial.build`."""
     trials = Trial.build(exp_config[1])
     assert list(map(lambda x: x.to_dict(), trials)) == exp_config[1]