Skip to content
This repository has been archived by the owner on Sep 18, 2024. It is now read-only.

docstr/pylint of GP Tuner & CurveFitting Assessor #1692

Merged
merged 13 commits into from
Nov 11, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ def assess_trial(self, trial_job_id, trial_history):
Exception
unrecognize exception in curvefitting_assessor
"""
trial_job_id = trial_job_id
xuehui1991 marked this conversation as resolved.
Show resolved Hide resolved
self.trial_history = trial_history
if not self.set_best_performance:
return AssessResult.Good
Expand Down
5 changes: 4 additions & 1 deletion src/sdk/pynni/nni/curvefitting_assessor/curvefunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

"""
A family of functions used by CurvefittingAssessor
"""
import numpy as np

all_models = {}
Expand Down Expand Up @@ -100,6 +102,7 @@ def logx_linear(x, a, b):
float
a * np.log(x) + b
"""
# pylint: disable=assignment-from-no-return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed.

x = np.log(x)
return a*x + b

Expand Down
1 change: 1 addition & 0 deletions src/sdk/pynni/nni/curvefitting_assessor/model_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ def mcmc_sampling(self):
new_values = np.random.randn(NUM_OF_INSTANCE, self.effective_model_num) * STEP_SIZE + self.weight_samples
new_values = self.normalize_weight(new_values)
# compute alpha(i, j) = min{1, P(j)Q(j, i)/P(i)Q(i, j)}
# pylint: disable=assignment-from-no-return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed. Use latest pylintrc.

alpha = np.minimum(1, self.target_distribution(new_values) / self.target_distribution(self.weight_samples))
# sample u
u = np.random.rand(NUM_OF_INSTANCE)
Expand Down
89 changes: 52 additions & 37 deletions src/sdk/pynni/nni/gp_tuner/gp_tuner.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
'''
gp_tuner.py
'''
"""
GPTuner is a Bayesian Optimization method where Gaussian Process is used for modeling loss functions.

See : class:`GPTuner` for details.
Copy link
Contributor

@liuzhe-lz liuzhe-lz Nov 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Space after colon. :class:`ClassName` is the syntax of sphinx cross-reference.

"""

import warnings
import logging
import numpy as np

# pylint: disable=no-name-in-module, import-error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why ? This is not included in pylintrc

from sklearn.gaussian_process.kernels import Matern
from sklearn.gaussian_process import GaussianProcessRegressor

Expand All @@ -38,9 +41,31 @@


class GPTuner(Tuner):
'''
GPTuner
'''
"""
GPTuner is a Bayesian Optimization method where Gaussian Process is used for modeling loss functions.

Parameters
----------
optimize_mode: str
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a space before colon here. My example was incorrect.

optimize mode, 'maximize' or 'minimize', by default 'maximize'
utility: str
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documented attributes are public APIs. Use underscore name for internal states.

utility function(also called 'acquisition funcition') to use, which can be 'ei', 'ucb' or 'poi'. By default 'ei'.
kappa: float
value used by utility function 'ucb'. The bigger kappa is, the more the tuner will be exploratory. By default 5.
xi: float
used by utility function 'ei' and 'poi'. The bigger xi is, the more the tuner will be exploratory. By default 0.
nu: float
used to specify Matern kernel. The smaller nu, the less smooth the approximated function is. By default 2.5.
alpha: float
Used to specify Gaussian Process Regressor. Larger values correspond to increased noise level in the observations.
By default 1e-6.
cold_start_num: int
Number of random exploration to perform before Gaussian Process. By default 10.
selection_num_warm_up: int
Number of random points to evaluate for getting the point which maximizes the acquisition function. By default 100000
selection_num_starting_points: int
Number of times to run L-BFGS-B from a random starting point after the warmup. By default 250.
"""

def __init__(self, optimize_mode="maximize", utility='ei', kappa=5, xi=0, nu=2.5, alpha=1e-6, cold_start_num=10,
selection_num_warm_up=100000, selection_num_starting_points=250):
Expand Down Expand Up @@ -75,27 +100,20 @@ def __init__(self, optimize_mode="maximize", utility='ei', kappa=5, xi=0, nu=2.5
self.supplement_data_num = 0

def update_search_space(self, search_space):
"""Update the self.bounds and self.types by the search_space.json
"""
Update the self.bounds and self.types by the search_space.json file.

Parameters
----------
search_space : dict
Override of the abstract method in class:`Tuner`.
Copy link
Contributor

@liuzhe-lz liuzhe-lz Nov 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please build and check html locally.
If this link does not work, it should be :class:`~nni.tuner.Tuner`.

"""
self._space = TargetSpace(search_space, self._random_state)

def generate_parameters(self, parameter_id, **kwargs):
"""Generate next parameter for trial
If the number of trial result is lower than cold start number,
gp will first randomly generate some parameters.
Otherwise, choose the parameters by the Gussian Process Model

Parameters
----------
parameter_id : int

Returns
-------
result : dict
"""
Method which provides one set of hyper-parameters.
If the number of trial result is lower than cold_start_number, GPTuner will first randomly generate some parameters.
Otherwise, choose the parameters by the Gussian Process Model.

Override of the abstract method in class:`Tuner`.
"""
if self._space.len() < self._cold_start_num:
results = self._space.random_sample()
Expand Down Expand Up @@ -124,14 +142,10 @@ def generate_parameters(self, parameter_id, **kwargs):
return results

def receive_trial_result(self, parameter_id, parameters, value, **kwargs):
"""Tuner receive result from trial.

Parameters
----------
parameter_id : int
parameters : dict
value : dict/float
if value is dict, it should have "default" key.
"""
Method invoked when a trial reports its final result.

Override of the abstract method in class:`Tuner`.
"""
value = extract_scalar_reward(value)
if self.optimize_mode == OptimizeMode.Minimize:
Expand All @@ -143,22 +157,23 @@ def receive_trial_result(self, parameter_id, parameters, value, **kwargs):
self._space.register(parameters, value)

def import_data(self, data):
"""Import additional data for tuning
Parameters
----------
data:
a list of dictionarys, each of which has at least two keys, 'parameter' and 'value'
"""
Import additional data for tuning.

Override of the abstract method in class:`Tuner`.
"""
_completed_num = 0
for trial_info in data:
logger.info("Importing data, current processing progress %s / %s", _completed_num, len(data))
logger.info(
"Importing data, current processing progress %s / %s", _completed_num, len(data))
_completed_num += 1
assert "parameter" in trial_info
_params = trial_info["parameter"]
assert "value" in trial_info
_value = trial_info['value']
if not _value:
logger.info("Useless trial data, value is %s, skip this trial data.", _value)
logger.info(
"Useless trial data, value is %s, skip this trial data.", _value)
continue
self.supplement_data_num += 1
_parameter_id = '_'.join(
Expand Down
Loading