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

fix quniform issue ; change related doc #1378

Merged
merged 7 commits into from
Aug 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/en_US/Tutorial/AnnotationSpec.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ There are 10 types to express your search space as follows:
* `@nni.variable(nni.uniform(low, high),name=variable)`
Which means the variable value is a value uniformly between low and high.
* `@nni.variable(nni.quniform(low, high, q),name=variable)`
Which means the variable value is a value like round(uniform(low, high) / q) * q
Which means the variable value is a value like clip(round(uniform(low, high) / q) * q, low, high), where the clip operation is used to constraint the generated value in the bound.
* `@nni.variable(nni.loguniform(low, high),name=variable)`
Which means the variable value is a value drawn according to exp(uniform(low, high)) so that the logarithm of the return value is uniformly distributed.
* `@nni.variable(nni.qloguniform(low, high, q),name=variable)`
Which means the variable value is a value like round(exp(uniform(low, high)) / q) * q
Which means the variable value is a value like clip(round(loguniform(low, high) / q) * q, low, high), where the clip operation is used to constraint the generated value in the bound.
* `@nni.variable(nni.normal(mu, sigma),name=variable)`
Which means the variable value is a real value that's normally-distributed with mean mu and standard deviation sigma.
* `@nni.variable(nni.qnormal(mu, sigma, q),name=variable)`
Expand Down
5 changes: 3 additions & 2 deletions docs/en_US/Tutorial/SearchSpaceSpec.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,16 @@ All types of sampling strategies and their parameter are listed here:
* When optimizing, this variable is constrained to a two-sided interval.

* {"_type":"quniform","_value":[low, high, q]}
* Which means the variable value is a value like round(uniform(low, high) / q) * q
* Which means the variable value is a value like clip(round(uniform(low, high) / q) * q, low, high), where the clip operation is used to constraint the generated value in the bound. For example, for _value specified as [0, 10, 2.5], possible values are [0, 2.5, 5.0, 7.5, 10.0]; For _value specified as [2, 10, 5], possible values are [2, 5, 10].

* Suitable for a discrete value with respect to which the objective is still somewhat "smooth", but which should be bounded both above and below. If you want to uniformly choose integer from a range [low, high], you can write `_value` like this: `[low, high, 1]`.

* {"_type":"loguniform","_value":[low, high]}
* Which means the variable value is a value drawn from a range [low, high] according to a loguniform distribution like exp(uniform(log(low), log(high))), so that the logarithm of the return value is uniformly distributed.
* When optimizing, this variable is constrained to be positive.

* {"_type":"qloguniform","_value":[low, high, q]}
* Which means the variable value is a value like round(loguniform(low, high)) / q) * q
* Which means the variable value is a value like clip(round(loguniform(low, high)) / q) * q, low, high), where the clip operation is used to constraint the generated value in the bound.
* Suitable for a discrete variable with respect to which the objective is "smooth" and gets smoother with the size of the value, but which should be bounded both above and below.

* {"_type":"normal","_value":[mu, sigma]}
Expand Down
5 changes: 2 additions & 3 deletions src/sdk/pynni/nni/gridsearch_tuner/gridsearch_tuner.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,8 @@ def json2parameter(self, ss_spec):

def _parse_quniform(self, param_value):
'''parse type of quniform parameter and return a list'''
low, high, interval = param_value[0], param_value[1], param_value[2]
count = int(np.floor((high - low) / interval)) + 1
return [low + interval * i for i in range(count)]
low, high, q = param_value[0], param_value[1], param_value[2]
return np.clip(np.arange(np.round(low/q), np.round(high/q)+1) * q, low, high)

def _parse_randint(self, param_value):
'''parse type of randint parameter and return a list'''
Expand Down
5 changes: 4 additions & 1 deletion src/sdk/pynni/nni/hyperopt_tuner/hyperopt_tuner.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@ def json2parameter(in_x, parameter, name=NodeType.ROOT):
name=name + '[%d]' % _index)
}
else:
out_y = parameter[name]
if _type in ['quniform', 'qloguniform']:
out_y = np.clip(parameter[name], in_x[NodeType.VALUE][0], in_x[NodeType.VALUE][1])
else:
out_y = parameter[name]
else:
out_y = dict()
for key in in_x.keys():
Expand Down
4 changes: 2 additions & 2 deletions src/sdk/pynni/nni/parameter_expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def quniform(low, high, q, random_state):
q: sample step
random_state: an object of numpy.random.RandomState
xuehui1991 marked this conversation as resolved.
Show resolved Hide resolved
'''
return np.round(uniform(low, high, random_state) / q) * q
return np.clip(np.round(uniform(low, high, random_state) / q) * q, low, high)


def loguniform(low, high, random_state):
Expand All @@ -77,7 +77,7 @@ def qloguniform(low, high, q, random_state):
q: sample step
random_state: an object of numpy.random.RandomState
'''
return np.round(loguniform(low, high, random_state) / q) * q
return np.clip(np.round(loguniform(low, high, random_state) / q) * q, low, high)


def normal(mu, sigma, random_state):
Expand Down
4 changes: 2 additions & 2 deletions src/sdk/pynni/nni/smartparam.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ def uniform(low, high, name=None):

def quniform(low, high, q, name=None):
assert high > low, 'Upper bound must be larger than lower bound'
return round(random.uniform(low, high) / q) * q
return np.clip(round(random.uniform(low, high) / q) * q, low, high)

def loguniform(low, high, name=None):
assert low > 0, 'Lower bound must be positive'
return np.exp(random.uniform(np.log(low), np.log(high)))

def qloguniform(low, high, q, name=None):
return round(loguniform(low, high) / q) * q
return np.clip(round(loguniform(low, high) / q) * q, low, high)

def normal(mu, sigma, name=None):
return random.gauss(mu, sigma)
Expand Down