示例#1
0
    def __init__(
        self,
        space: Space,
        optimizer: Optimizer,
        function: Function,
        save_agents: Optional[bool] = False,
    ) -> None:
        """Initialization method.

        Args:
            space: Space-child instance.
            optimizer: Optimizer-child instance.
            function: Function or Function-child instance.
            save_agents: Saves all agents in the search space.

        """

        logger.info("Creating class: Opytimizer.")

        # Space
        self.space = space

        # Optimizer (and its additional variables)
        self.optimizer = optimizer
        self.optimizer.compile(space)

        # Function
        self.function = function

        # Optimization history
        self.history = History(save_agents)

        # Current iteration
        self.iteration = 0

        # Total number of iterations
        self.total_iterations = 0

        logger.debug(
            "Space: %s | Optimizer: %s| Function: %s.",
            self.space,
            self.optimizer,
            self.function,
        )
        logger.info("Class created.")
示例#2
0
    def __init__(self, space, optimizer, function, save_agents=False):
        """Initialization method.

        Args:
            space (Space): Space-child instance.
            optimizer (Optimizer): Optimizer-child instance.
            function (Function): Function or Function-child instance.
            save_agents (bool): Saves all agents in the search space.

        """

        logger.info('Creating class: Opytimizer.')

        # Space
        self.space = space

        # Optimizer (and its additional variables)
        self.optimizer = optimizer
        self.optimizer.compile(space)

        # Function
        self.function = function

        # Optimization history
        self.history = History(save_agents)

        # Current iteration
        self.iteration = 0

        # Total number of iterations
        self.total_iterations = 0

        # Logs the properties
        logger.debug('Space: %s | Optimizer: %s| Function: %s.',
                     self.space, self.optimizer, self.function)
        logger.info('Class created.')
示例#3
0
class Opytimizer:
    """An Opytimizer class holds all the information needed
    in order to perform an optimization task.

    """

    def __init__(
        self,
        space: Space,
        optimizer: Optimizer,
        function: Function,
        save_agents: Optional[bool] = False,
    ) -> None:
        """Initialization method.

        Args:
            space: Space-child instance.
            optimizer: Optimizer-child instance.
            function: Function or Function-child instance.
            save_agents: Saves all agents in the search space.

        """

        logger.info("Creating class: Opytimizer.")

        # Space
        self.space = space

        # Optimizer (and its additional variables)
        self.optimizer = optimizer
        self.optimizer.compile(space)

        # Function
        self.function = function

        # Optimization history
        self.history = History(save_agents)

        # Current iteration
        self.iteration = 0

        # Total number of iterations
        self.total_iterations = 0

        logger.debug(
            "Space: %s | Optimizer: %s| Function: %s.",
            self.space,
            self.optimizer,
            self.function,
        )
        logger.info("Class created.")

    @property
    def space(self) -> Space:
        """Space-child instance (SearchSpace, HyperComplexSpace, etc)."""

        return self._space

    @space.setter
    def space(self, space: Space) -> None:
        if not space.built:
            raise e.BuildError("`space` should be built before using Opytimizer")

        self._space = space

    @property
    def optimizer(self) -> Optimizer:
        """Optimizer-child instance (PSO, BA, etc)."""

        return self._optimizer

    @optimizer.setter
    def optimizer(self, optimizer: Optimizer) -> None:
        if not optimizer.built:
            raise e.BuildError("`optimizer` should be built before using Opytimizer")

        self._optimizer = optimizer

    @property
    def function(self) -> Function:
        """Function or Function-child instance (ConstrainedFunction, WeightedFunction, etc)."""

        return self._function

    @function.setter
    def function(self, function: Function) -> None:
        if not function.built:
            raise e.BuildError("`function` should be built before using Opytimizer")

        self._function = function

    @property
    def history(self) -> History:
        """Optimization history."""

        return self._history

    @history.setter
    def history(self, history: History) -> None:
        if not isinstance(history, History):
            raise e.TypeError("`history` should be a History")

        self._history = history

    @property
    def iteration(self) -> int:
        """Current iteration."""

        return self._iteration

    @iteration.setter
    def iteration(self, iteration: int) -> None:
        if not isinstance(iteration, int):
            raise e.TypeError("`iteration` should be an integer")
        if iteration < 0:
            raise e.ValueError("`iteration` should be >= 0")

        self._iteration = iteration

    @property
    def total_iterations(self) -> int:
        """Total number of iterations."""

        return self._total_iterations

    @total_iterations.setter
    def total_iterations(self, total_iterations: int) -> None:
        if not isinstance(total_iterations, int):
            raise e.TypeError("`total_iterations` should be an integer")
        if total_iterations < 0:
            raise e.ValueError("`total_iterations` should be >= 0")

        self._total_iterations = total_iterations

    @property
    def evaluate_args(self) -> List[Any]:
        """Converts the optimizer `evaluate` arguments into real variables.

        Returns:
            (List[Any]): List of real-attribute variables.

        """

        args = signature(self.optimizer.evaluate).parameters

        return [getattr(self, v) for v in args]

    @property
    def update_args(self) -> List[Any]:
        """Converts the optimizer `update` arguments into real variables.

        Returns:
            (List[Any]): List of real-attribute variables.

        """

        args = signature(self.optimizer.update).parameters

        return [getattr(self, v) for v in args]

    def evaluate(self, callbacks: List[Callback]) -> None:
        """Wraps the `evaluate` pipeline with its corresponding callbacks.

        Args:
            callbacks: List of callbacks.

        """

        # Invokes the `on_evaluate_before` callback
        callbacks.on_evaluate_before(*self.evaluate_args)

        # Performs an evaluation over the search space
        self.optimizer.evaluate(*self.evaluate_args)

        # Invokes the `on_evaluate_after` callback
        callbacks.on_evaluate_after(*self.evaluate_args)

    def update(self, callbacks: List[Callback]) -> None:
        """Wraps the `update` pipeline with its corresponding callbacks.

        Args:
            callback: List of callbacks.

        """

        # Invokes the `on_update_before` callback
        callbacks.on_update_before(*self.update_args)

        # Performs an update over the search space
        self.optimizer.update(*self.update_args)

        # Invokes the `on_update_after` callback
        callbacks.on_update_after(*self.update_args)

        # Regardless of callbacks or not, every update on the search space
        # must meet the bounds limits
        self.space.clip_by_bound()

    def start(
        self,
        n_iterations: Optional[int] = 1,
        callbacks: Optional[List[Callback]] = None,
    ) -> None:
        """Starts the optimization task.

        Args
            n_iterations: Maximum number of iterations.
            callback: List of callbacks.

        """

        logger.info("Starting optimization task.")

        # Additional properties
        self.n_iterations = n_iterations
        callbacks = CallbackVessel(callbacks)

        # Triggers starting time
        start = time.time()

        # Invokes the `on_task_begin` callback
        callbacks.on_task_begin(self)

        # Evaluates the search space
        self.evaluate(callbacks)

        # Initializes a progress bar
        with tqdm(total=n_iterations, ascii=True) as b:
            for t in range(n_iterations):
                logger.to_file(f"Iteration {t+1}/{n_iterations}")

                # Saves the number of total iterations and current iteration
                self.total_iterations += 1
                self.iteration = t

                # Invokes the `on_iteration_begin` callback
                callbacks.on_iteration_begin(self.total_iterations, self)

                # Updates the search space
                self.update(callbacks)

                # Re-evaluates the search space
                self.evaluate(callbacks)

                # Updates the progress bar status
                b.set_postfix(fitness=self.space.best_agent.fit)
                b.update()

                # Dumps keyword arguments to model's history
                self.history.dump(
                    agents=self.space.agents, best_agent=self.space.best_agent
                )

                # Invokes the `on_iteration_end` callback
                callbacks.on_iteration_end(self.total_iterations, self)

                logger.to_file(f"Fitness: {self.space.best_agent.fit}")
                logger.to_file(f"Position: {self.space.best_agent.position}")

        # Invokes the `on_task_end` callback
        callbacks.on_task_end(self)

        # Stops the timer and calculates the optimization time
        end = time.time()
        opt_time = end - start

        # Dumps the elapsed time to model's history
        self.history.dump(time=opt_time)

        logger.info("Optimization task ended.")
        logger.info("It took %s seconds.", opt_time)

    def save(self, file_path: str) -> None:
        """Saves the optimization model to a dill (pickle) file.

        Args:
            file_path: Path of file to be saved.

        """

        with open(file_path, "wb") as output_file:
            dill.dump(self, output_file)

    @classmethod
    def load(cls, file_path: str) -> None:
        """Loads the optimization model from a dill (pickle) file without needing
        to instantiate the class.

        Args:
            file_path: Path of file to be loaded.

        """

        with open(file_path, "rb") as input_file:
            opt_model = dill.load(input_file)

            return opt_model
if __name__ == '__main__':
    # Gathers the input arguments
    args = get_arguments()

    # Gathering variables from arguments
    dataset = args.dataset
    descriptor = args.descriptor
    fold = args.fold
    type = args.type
    meta = args.mh

    # Defining an input file
    input_file = f'output/{meta}_{type}_{dataset}_val_{fold}.pkl'

    # Creating a History object
    h = History()

    # Loading the input file
    h.load(input_file)

    # Loading the predictions and labels
    preds, y = l.load_candidates(dataset, 'test', fold)

    # If descriptor is global-based
    if descriptor == 'global':
        # Gets the global predictors
        preds = preds[:, :35]

    # If descriptor is cnn-based
    elif descriptor == 'cnn':
        # Gets the CNN predictors
示例#5
0
from opytimizer.utils.history import History

# File name to be loaded
file_name = ''

# Creating an empty History object
h = History()

# Loading history from pickle file
h.load(file_name)

# Displaying content
print(h)
示例#6
0
import numpy as np

import opytimizer.visualization.convergence as c
from opytimizer.utils.history import History

# Creating the history object
history = History()

# Loading saved optimization task
history.load('')

# Gathering desired keys from the object
# In this case, we will the first agent's position and fitness
agent_pos = history.get(key='agents', index=(0, 0))
agent_fit = history.get(key='agents', index=(0, 1))

# We will also gather the best agent's position and fitness
best_agent_pos = history.get(key='best_agent', index=(0,))
best_agent_fit = history.get(key='best_agent', index=(1,))

# Plotting convergence graphs
# Plotting the convergence of agent's positions
c.plot(agent_pos[0], agent_pos[1], labels=['$x_0$', '$x_1$'],
       title='Sphere Function: $x^2 \mid x \in [-10, 10]$', subtitle='Agent: 0 | Algorithm: Particle Swarm Optimization')

# Plotting the convergence of best agent's positions
c.plot(best_agent_pos[0], best_agent_pos[1], labels=['$x^*_0$', '$x^*_1$'],
       title='Sphere Function: $x^2 \mid x \in [-10, 10]$', subtitle="Agent: Best | Algorithm: Particle Swarm Optimization")

# Plotting the convergence of agent's and best agent's fitness
c.plot(agent_fit, best_agent_fit, labels=[
示例#7
0
from opytimizer.utils.history import History

# Instantiates the History
h = History()

# Dumps a variable (it will be converted into a list)
h.dump(x=1)
h.dump(x=2)
h.dump(x=3)

# Any variable will be converted into a list
# Even lists, dictionaries, etc
h.dump(y=[1])

# Access the variables
print(h.x)
print(h.y)
示例#8
0
class Opytimizer:
    """An Opytimizer class holds all the information needed
    in order to perform an optimization task.

    """

    def __init__(self, space, optimizer, function, save_agents=False):
        """Initialization method.

        Args:
            space (Space): Space-child instance.
            optimizer (Optimizer): Optimizer-child instance.
            function (Function): Function or Function-child instance.
            save_agents (bool): Saves all agents in the search space.

        """

        logger.info('Creating class: Opytimizer.')

        # Space
        self.space = space

        # Optimizer (and its additional variables)
        self.optimizer = optimizer
        self.optimizer.compile(space)

        # Function
        self.function = function

        # Optimization history
        self.history = History(save_agents)

        # Current iteration
        self.iteration = 0

        # Total number of iterations
        self.total_iterations = 0

        # Logs the properties
        logger.debug('Space: %s | Optimizer: %s| Function: %s.',
                     self.space, self.optimizer, self.function)
        logger.info('Class created.')

    @property
    def space(self):
        """Space: Space-child instance (SearchSpace, HyperComplexSpace, etc).

        """

        return self._space

    @space.setter
    def space(self, space):
        if not space.built:
            raise e.BuildError('`space` should be built before using Opytimizer')

        self._space = space

    @property
    def optimizer(self):
        """Optimizer: Optimizer-child instance (PSO, BA, etc).

        """

        return self._optimizer

    @optimizer.setter
    def optimizer(self, optimizer):
        if not optimizer.built:
            raise e.BuildError('`optimizer` should be built before using Opytimizer')

        self._optimizer = optimizer

    @property
    def function(self):
        """Function: Function or Function-child instance (ConstrainedFunction, WeightedFunction, etc).

        """

        return self._function

    @function.setter
    def function(self, function):
        if not function.built:
            raise e.BuildError('`function` should be built before using Opytimizer')

        self._function = function

    @property
    def history(self):
        """History: Optimization history.

        """

        return self._history

    @history.setter
    def history(self, history):
        if not isinstance(history, History):
            raise e.TypeError('`history` should be a History')

        self._history = history

    @property
    def iteration(self):
        """int: Current iteration.

        """

        return self._iteration

    @iteration.setter
    def iteration(self, iteration):
        if not isinstance(iteration, int):
            raise e.TypeError('`iteration` should be an integer')
        if iteration < 0:
            raise e.ValueError('`iteration` should be >= 0')

        self._iteration = iteration

    @property
    def total_iterations(self):
        """int: Total number of iterations.

        """

        return self._total_iterations

    @total_iterations.setter
    def total_iterations(self, total_iterations):
        if not isinstance(total_iterations, int):
            raise e.TypeError('`total_iterations` should be an integer')
        if total_iterations < 0:
            raise e.ValueError('`total_iterations` should be >= 0')

        self._total_iterations = total_iterations

    @property
    def evaluate_args(self):
        """Converts the optimizer `evaluate` arguments into real variables.

        """

        # Inspects the `evaluate` and retrieves its parameters
        args = signature(self.optimizer.evaluate).parameters

        return [getattr(self, v) for v in args]

    @property
    def update_args(self):
        """Converts the optimizer `update` arguments into real variables.

        """

        # Inspects the `update` and retrieves its parameters
        args = signature(self.optimizer.update).parameters

        return [getattr(self, v) for v in args]

    def evaluate(self, callbacks):
        """Wraps the `evaluate` pipeline with its corresponding callbacks.

        Args:
            callback (list): List of callbacks.

        """

        # Invokes the `on_evaluate_before` callback
        callbacks.on_evaluate_before(*self.evaluate_args)

        # Performs an evaluation over the search space
        self.optimizer.evaluate(*self.evaluate_args)

        # Invokes the `on_evaluate_after` callback
        callbacks.on_evaluate_after(*self.evaluate_args)

    def update(self, callbacks):
        """Wraps the `update` pipeline with its corresponding callbacks.

        Args:
            callback (list): List of callbacks.

        """

        # Invokes the `on_update_before` callback
        callbacks.on_update_before(*self.update_args)

        # Performs an update over the search space
        self.optimizer.update(*self.update_args)

        # Invokes the `on_update_after` callback
        callbacks.on_update_after(*self.update_args)

        # Regardless of callbacks or not, every update on the search space
        # must meet the bounds limits
        self.space.clip_by_bound()

    def start(self, n_iterations=1, callbacks=None):
        """Starts the optimization task.

        Args
            n_iterations (int): Maximum number of iterations.
            callback (list): List of callbacks.

        """

        logger.info('Starting optimization task.')

        # Additional properties
        self.n_iterations = n_iterations
        callbacks = CallbackVessel(callbacks)

        # Triggers starting time
        start = time.time()

        # Evaluates the search space
        self.evaluate(callbacks)

        # Initializes a progress bar
        with tqdm(total=n_iterations) as b:
            # Loops through all iterations
            for t in range(n_iterations):
                logger.to_file(f'Iteration {t+1}/{n_iterations}')

                # Saves the number of total iterations and current iteration
                self.total_iterations += 1
                self.iteration = t

                # Invokes the `on_iteration_begin` callback
                callbacks.on_iteration_begin(self.total_iterations, self)

                # Updates the search space
                self.update(callbacks)

                # Re-evaluates the search space
                self.evaluate(callbacks)

                # Updates the progress bar status
                b.set_postfix(fitness=self.space.best_agent.fit)
                b.update()

                # Dumps keyword arguments to model's history
                self.history.dump(agents=self.space.agents,
                                  best_agent=self.space.best_agent)

                # Invokes the `on_iteration_end` callback
                callbacks.on_iteration_end(self.total_iterations, self)

                logger.to_file(f'Fitness: {self.space.best_agent.fit}')
                logger.to_file(f'Position: {self.space.best_agent.position}')

        # Stops the timer and calculates the optimization time
        end = time.time()
        opt_time = end - start

        # Dumps the elapsed time to model's history
        self.history.dump(time=opt_time)

        logger.info('Optimization task ended.')
        logger.info('It took %s seconds.', opt_time)

    def save(self, file_path):
        """Saves the optimization model to a pickle file.

        Args:
            file_path (str): Path of file to be saved.

        """

        # Opens an output file
        with open(file_path, 'wb') as output_file:
            # Dumps object to file
            pickle.dump(self, output_file)

    @classmethod
    def load(cls, file_path):
        """Loads the optimization model from a pickle file without needing
        to instantiate the class.

        Args:
            file_path (str): Path of file to be loaded.

        """

        # Opens an input file
        with open(file_path, "rb") as input_file:
            # Loads object from file
            opt_model = pickle.load(input_file)

            return opt_model