1- from benchopt import BaseSolver , safe_import_context
1+ from benchopt import BaseSolver
22
3- # Protect the import with `safe_import_context()`. This allows:
4- # - skipping import to speed up autocompletion in CLI.
5- # - getting requirements info when all dependencies are not installed.
6- with safe_import_context () as import_ctx :
7- import numpy as np
3+ import numpy as np
84
9- # import your reusable functions here
10- from benchmark_utils import gradient_ols
5+ # Reusable function can be imported from the benchmark_utils module, which is
6+ # dynamically installed when running the benchmark.
7+ from benchmark_utils import gradient_ols
118
129
1310# The benchmark solvers must be named `Solver` and
@@ -17,16 +14,27 @@ class Solver(BaseSolver):
1714 # Name to select the solver in the CLI and to display the results.
1815 name = 'GD'
1916
17+ # List of packages needed to run the solver. See the corresponding
18+ # section in objective.py. This is an optional attribute.
19+ requirements = []
20+
2021 # List of parameters for the solver. The benchmark will consider
2122 # the cross product for each key in the dictionary.
2223 # All parameters 'p' defined here are available as 'self.p'.
2324 parameters = {
24- 'scale_step ' : [1 , 1.99 ],
25+ 'learning_rate ' : [0. 1 , 0.5 ],
2526 }
2627
27- # List of packages needed to run the solver. See the corresponding
28- # section in objective.py
29- requirements = []
28+ # Evaluation strategy for the performance curve.
29+ # It describe when how and when the solver will be evaluated.
30+ # You can also use `iteration`, `tolerance` or `run_once`, as described in
31+ # https://benchopt.github.io/performance_curves.html
32+ # For optimization solvers, we recommend to use 'callback' which can be
33+ # used regularly to log the progress of the solver and implement a stopping
34+ # criterion.
35+ # For machine learning methods, `run_once` is usually more adapted, to
36+ # evaluate method only at the end of the training phase.
37+ sampling_strategy = 'callback'
3038
3139 def set_objective (self , X , y ):
3240 # Define the information received by each solver from the objective.
@@ -36,22 +44,23 @@ def set_objective(self, X, y):
3644 # It is customizable for each benchmark.
3745 self .X , self .y = X , y
3846
39- def run (self , n_iter ):
40- # This is the function that is called to evaluate the solver.
41- # It runs the algorithm for a given a number of iterations `n_iter`.
42- # You can also use a `tolerance` or a `callback`, as described in
43- # https://benchopt.github.io/performance_curves.html
44-
45- L = np .linalg .norm (self .X , ord = 2 ) ** 2
46- step_size = self .scale_step / L
47- beta = np .zeros (self .X .shape [1 ])
48- for _ in range (n_iter ):
49- beta -= step_size * gradient_ols (self .X , self .y , beta )
47+ def run (self , callback ):
48+ # This is the function that is called to run the method.
49+ # When using ``sampling_strategy='callback'``, the function is provided
50+ # with a ``callback`` function that must be called regularly to
51+ # log the progress of the solver. The callback function returns
52+ # ``True`` until the solver should stop.
53+ # See https://benchopt.github.io/guide/auto_stop.html for more details.
5054
51- self .beta = beta
55+ self .beta = np .zeros (self .X .shape [1 ])
56+ while callback ():
57+ self .beta -= self .learning_rate * gradient_ols (
58+ self .X , self .y , self .beta
59+ )
5260
5361 def get_result (self ):
54- # Return the result from one optimization run.
62+ # Return the result of the method.
63+ #
5564 # The outputs of this function is a dictionary which defines the
5665 # keyword arguments for `Objective.evaluate_result`
5766 # This defines the benchmark's API for solvers' results.
0 commit comments