cotengra.experimental.hyper_scipy ================================= .. py:module:: cotengra.experimental.hyper_scipy .. autoapi-nested-parse:: Hyper optimization using scipy gradient-free optimizers. Supported methods: ``differential_evolution``, ``dual_annealing``, ``direct``, ``shgo``. Since these optimizers use a callback-style objective, a background thread is used to invert the control flow into an ask/tell interface. Multiple workers are maintained per method to support parallel pre-dispatch (ask-ask-...-tell-tell-...). Attributes ---------- .. autoapisummary:: cotengra.experimental.hyper_scipy._OPTIMIZER_NAMES Exceptions ---------- .. autoapisummary:: cotengra.experimental.hyper_scipy._StopOptimization Classes ------- .. autoapisummary:: cotengra.experimental.hyper_scipy.ScipyAskTell cotengra.experimental.hyper_scipy.HyperScipySampler cotengra.experimental.hyper_scipy.ScipyOptLib Module Contents --------------- .. py:data:: _OPTIMIZER_NAMES .. py:exception:: _StopOptimization Bases: :py:obj:`Exception` Raised inside the objective to abort the scipy optimizer. .. py:class:: ScipyAskTell(method, bounds, **kwargs) Ask/tell wrapper around a scipy global optimizer. The optimizer runs in a background thread. Each time it needs an objective evaluation it posts the candidate vector to ``_ask_q`` and blocks on ``_tell_q``. The caller drives progress by alternating ``ask()`` / ``tell()`` calls from the main thread. :param method: One of the supported scipy optimizer names. :type method: str :param bounds: Bounds for every raw dimension. :type bounds: list[tuple[float, float]] :param kwargs: Forwarded to the underlying scipy optimizer. .. py:attribute:: method .. py:attribute:: bounds .. py:attribute:: kwargs .. py:attribute:: _ask_q .. py:attribute:: _tell_q .. py:attribute:: _thread :value: None .. py:attribute:: _stop .. py:attribute:: done :value: False .. py:method:: _get_optimizer_fn() .. py:method:: _objective(x) .. py:method:: _run() .. py:method:: start() Launch the optimizer in a background thread. .. py:method:: ask() Block until the optimizer requests an evaluation. :returns: **x** -- The candidate vector, or ``None`` if the optimizer finished. :rtype: ndarray or None .. py:method:: tell(score) Provide the objective value back to the optimizer. .. py:method:: stop() Signal the background thread to stop and wait for it. .. py:class:: HyperScipySampler(space, method='differential_evolution', n_workers=1, exponential_param_power=None, **kwargs) Per-method optimizer that wraps a pool of ``ScipyAskTell`` workers with the ``Param``-based space mapping. Each ``ScipyAskTell`` worker is strictly serial (ask-tell-ask-tell), so to support parallel pre-dispatch (multiple ``ask`` calls before any ``tell``), we maintain a pool of workers. Each ``ask`` grabs a candidate from the next idle worker; each ``tell`` feeds the score back to the specific worker that produced that candidate. :param space: The search space for one method. :type space: dict[str, dict] :param method: Which scipy optimizer to use. :type method: str :param n_workers: Number of concurrent ``ScipyAskTell`` threads to run. :type n_workers: int, optional :param exponential_param_power: Power for ``ParamFloatExp``. :type exponential_param_power: float, optional :param kwargs: Extra keyword arguments forwarded to the scipy optimizer. .. py:attribute:: params .. py:attribute:: _ndim .. py:attribute:: _method :value: 'differential_evolution' .. py:attribute:: _scipy_opts .. py:attribute:: _n_workers :value: 1 .. py:attribute:: _trial_counter :value: 0 .. py:attribute:: _trial_to_worker .. py:attribute:: _workers :value: [] .. py:attribute:: _worker_idx :value: 0 .. py:method:: _make_worker() Create and start a fresh ``ScipyAskTell`` instance. .. py:method:: _next_worker() Pick the next worker in round-robin order, restarting any that have finished. .. py:method:: ask() Return ``(trial_number, params_dict)``. Picks the next idle worker (round-robin), blocking until it has a candidate ready. If a worker has converged, it is automatically restarted. .. py:method:: tell(trial_number, score) Report a score back to the specific worker that produced this trial. .. py:method:: stop() Stop all background threads. .. py:class:: ScipyOptLib Bases: :py:obj:`cotengra.experimental.hyper.HyperOptLib` Hyper-optimization using scipy gradient-free optimizers with an LCB method selector. .. py:method:: setup(methods, space, optimizer=None, method='differential_evolution', method_exploration=1.0, method_temperature=1.0, exponential_param_power=None, **scipy_opts) Initialize per-method scipy optimizers. :param methods: The contraction methods to optimize over. :type methods: list[str] :param space: The search space. :type space: dict[str, dict[str, dict]] :param optimizer: The parent optimizer instance. :type optimizer: HyperOptimizer, optional :param method: Which scipy global optimizer to use. One of ``'differential_evolution'``, ``'dual_annealing'``, ``'direct'``, ``'shgo'``. :type method: str, optional :param method_exploration: Exploration parameter for the LCB method selector. :type method_exploration: float, optional :param method_temperature: Temperature parameter for the LCB method selector. :type method_temperature: float, optional :param exponential_param_power: Power for ``ParamFloatExp``. :type exponential_param_power: float, optional :param scipy_opts: Extra keyword arguments forwarded to the scipy optimizer. .. py:method:: get_setting() .. py:method:: report_result(setting, trial, score) .. py:method:: cleanup() Stop all background optimizer threads.