예제 #1
0
    def __init__(self, laboratory, args):
        self.lab = laboratory

        # Get a list of every parameter to experiment with.
        target_parameters = []
        for start in args.grid_search.split(','):
            node = self.lab.default_parameters.get(start)
            subtree = ParameterSet.enumerate(node)
            target_parameters.extend(start + end for end in subtree)

        # Suggest modifications to each parameter.
        self.experiments = []
        for path in target_parameters:
            value = self.lab.default_parameters.get(path)
            for mod in self.mod_funcs:
                params = ParameterSet(self.lab.default_parameters)
                params.apply(path, mod(value))
                X = self.lab.get_experiment(params)
                if not X.notes.strip():
                    X.notes += "Suggested by Grid Search.\n"
                self.experiments.append(X)

        self.lab.save(
        )  # Write all of the new grid-search experiments to the lab report.
예제 #2
0
class ParticleData:
    """
    Attributes:
        p.parameters - ParameterSet
        p.velocities - ParameterSet full of float
        p.best       - ParameterSet
        p.score      - float
        p.age        - Number of times this particle has been evaluated/updated.
        p.lock       - Is this particle currently being evaluated?
    """
    def __init__(self, initial_parameters, swarm=None):
        self.parameters = ParameterSet(initial_parameters)
        self.best = None
        self.best_score = None
        self.age = 0
        self.initialize_velocities(swarm)
        self.lock = False

    def initialize_velocities(self, swarm=None):
        # Make a new parameter structure for the velocity data.
        self.velocities = ParameterSet(self.parameters)
        # Iterate through every field in the structure.
        for path in self.parameters.enumerate():
            value = self.parameters.get(path)
            if swarm is not None:
                # Analyse the other particle velocities, so that the new
                # velocity is not too large or too small.
                data = [p.velocities.get(path) for p in swarm if p is not self]
                velocity = np.random.normal(np.mean(data), np.std(data))
            else:
                # New swarm, start with a large random velocity.
                max_percent_change = .10
                uniform = 2 * random.random() - 1
                if isinstance(value, float):
                    velocity = value * uniform * max_percent_change
                elif isinstance(value, int):
                    if abs(value) < 1. / max_percent_change:
                        velocity = uniform  # Parameters are rounded, so 50% chance this will mutate.
                    else:
                        velocity = value * uniform * max_percent_change
                else:
                    raise NotImplementedError()
            self.velocities.apply(path, velocity)

    def update_position(self):
        for path in self.parameters.enumerate():
            position = self.parameters.get(path)
            velocity = self.velocities.get(path)
            self.parameters.apply(path, position + velocity)

    def update_velocity(self, global_best):
        for path in self.parameters.enumerate():
            postition = self.parameters.get(path)
            velocity = self.velocities.get(path)
            particle_best = self.best.get(
                path) if self.best is not None else postition
            global_best_x = global_best.get(
                path) if global_best is not None else postition

            # Update velocity.
            particle_bias = (particle_best -
                             postition) * particle_strength * random.random()
            global_bias = (global_best_x -
                           postition) * global_strength * random.random()
            velocity = velocity * velocity_strength + particle_bias + global_bias
            self.velocities.apply(path, velocity)

    def update(self, score, global_best):
        self.age += 1
        if self.best_score is not None:
            self.best_score *= 1 - score_decay_rate
        if self.best is None or score > self.best_score:
            self.best = ParameterSet(self.parameters)
            self.best_score = score
            print("New particle best score %g." % self.best_score)
        self.update_position()
        self.update_velocity(global_best)