search_space.rst 9.05 KB
Newer Older
1
2
3
4
5
6
Search Space
============

Overview
--------

liuzhe-lz's avatar
liuzhe-lz committed
7
In NNI, tuner will sample hyperparameters according to the search space.
8
9
10

To define a search space, users should define the name of the variable, the type of sampling strategy and its parameters.

liuzhe-lz's avatar
liuzhe-lz committed
11
* An example of a search space definition in JSON format is as follow:
12

13
.. code-block:: json 
14
15
16
17
18
19
20
21
22

   {
       "dropout_rate": {"_type": "uniform", "_value": [0.1, 0.5]},
       "conv_size": {"_type": "choice", "_value": [2, 3, 5, 7]},
       "hidden_size": {"_type": "choice", "_value": [124, 512, 1024]},
       "batch_size": {"_type": "choice", "_value": [50, 250, 500]},
       "learning_rate": {"_type": "uniform", "_value": [0.0001, 0.1]}
   }

liuzhe-lz's avatar
liuzhe-lz committed
23
24
25
26
Take the first line as an example.
``dropout_rate`` is defined as a variable whose prior distribution is a uniform distribution with a range from ``0.1`` to ``0.5``.

.. attention::
27

liuzhe-lz's avatar
liuzhe-lz committed
28
29
    The available sampling strategies within a search space depend on the tuner you want to use.
    We list the supported types for each built-in tuner :ref:`below <hpo-space-support>`.
30

liuzhe-lz's avatar
liuzhe-lz committed
31
    For a customized tuner, you don't have to follow our convention and you will have the flexibility to define any type you want.
32
33
34
35
36
37

Types
-----

All types of sampling strategies and their parameter are listed here:

liuzhe-lz's avatar
liuzhe-lz committed
38
39
40
41
42
43
44
45
46
47
48
49
50
51
choice
^^^^^^

.. code-block:: python 

    {"_type": "choice", "_value": options}

* The variable's value is one of the options. Here ``options`` should be a list of **numbers** or a list of **strings**. Using arbitrary objects as members of this list (like sublists, a mixture of numbers and strings, or null values) should work in most cases, but may trigger undefined behaviors.
* ``options`` can also be a nested sub-search-space, this sub-search-space takes effect only when the corresponding element is chosen. The variables in this sub-search-space can be seen as conditional variables. Here is an simple :githublink:`example of nested search space definition <examples/trials/mnist-nested-search-space/search_space.json>`. If an element in the options list is a dict, it is a sub-search-space, and for our built-in tuners you have to add a ``_name`` key in this dict, which helps you to identify which element is chosen. Accordingly, here is a :githublink:`sample <examples/trials/mnist-nested-search-space/sample.json>` which users can get from nni with nested search space definition. See the table below for the tuners which support nested search spaces.

randint
^^^^^^^

.. code-block:: python 
52

liuzhe-lz's avatar
liuzhe-lz committed
53
    {"_type": "randint", "_value": [lower, upper]}
54

liuzhe-lz's avatar
liuzhe-lz committed
55
56
57
58
* Choosing a random integer between ``lower`` (inclusive) and ``upper`` (exclusive).
* Note: Different tuners may interpret ``randint`` differently. Some (e.g., TPE, GridSearch) treat integers from lower
  to upper as unordered ones, while others respect the ordering (e.g., SMAC). If you want all the tuners to respect
  the ordering, please use ``quniform`` with ``q=1``.
59

liuzhe-lz's avatar
liuzhe-lz committed
60
61
uniform
^^^^^^^
62

liuzhe-lz's avatar
liuzhe-lz committed
63
.. code-block:: python 
64

liuzhe-lz's avatar
liuzhe-lz committed
65
    {"_type": "uniform", "_value": [low, high]}
66

liuzhe-lz's avatar
liuzhe-lz committed
67
68
* The variable value is uniformly sampled between low and high.
* When optimizing, this variable is constrained to a two-sided interval.
69

liuzhe-lz's avatar
liuzhe-lz committed
70
71
quniform
^^^^^^^^
72

liuzhe-lz's avatar
liuzhe-lz committed
73
.. code-block:: python 
74

liuzhe-lz's avatar
liuzhe-lz committed
75
    {"_type": "quniform", "_value": [low, high, q]}
76

liuzhe-lz's avatar
liuzhe-lz committed
77
78
* The variable value is determined using ``clip(round(uniform(low, high) / q) * q, low, high)``\ , where the clip operation is used to constrain the generated value within the bounds. 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 an integer from a range [low, high], you can write ``_value`` like this: ``[low, high, 1]``.
79

liuzhe-lz's avatar
liuzhe-lz committed
80
81
loguniform
^^^^^^^^^^
82

liuzhe-lz's avatar
liuzhe-lz committed
83
.. code-block:: python 
84

liuzhe-lz's avatar
liuzhe-lz committed
85
    {"_type": "loguniform", "_value": [low, high]}
86

liuzhe-lz's avatar
liuzhe-lz committed
87
88
* The variable value is 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.
89

liuzhe-lz's avatar
liuzhe-lz committed
90
91
qloguniform
^^^^^^^^^^^
92

liuzhe-lz's avatar
liuzhe-lz committed
93
.. code-block:: python 
94

liuzhe-lz's avatar
liuzhe-lz committed
95
    {"_type": "qloguniform", "_value": [low, high, q]}
96

liuzhe-lz's avatar
liuzhe-lz committed
97
98
* The variable value is determined using ``clip(round(loguniform(low, high) / q) * q, low, high)``\ , where the clip operation is used to constrain the generated value within the bounds.
* 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.
99

liuzhe-lz's avatar
liuzhe-lz committed
100
101
normal
^^^^^^
102

liuzhe-lz's avatar
liuzhe-lz committed
103
.. code-block:: python 
104

liuzhe-lz's avatar
liuzhe-lz committed
105
    {"_type": "normal", "_value": [mu, sigma]}
106

liuzhe-lz's avatar
liuzhe-lz committed
107
* The variable value is a real value that's normally-distributed with mean mu and standard deviation sigma. When optimizing, this is an unconstrained variable.
108

liuzhe-lz's avatar
liuzhe-lz committed
109
110
qnormal
^^^^^^^
111

liuzhe-lz's avatar
liuzhe-lz committed
112
.. code-block:: python 
113

liuzhe-lz's avatar
liuzhe-lz committed
114
    {"_type": "qnormal", "_value": [mu, sigma, q]}
115

liuzhe-lz's avatar
liuzhe-lz committed
116
117
* The variable value is determined using ``round(normal(mu, sigma) / q) * q``
* Suitable for a discrete variable that probably takes a value around mu, but is fundamentally unbounded.
118

liuzhe-lz's avatar
liuzhe-lz committed
119
120
lognormal
^^^^^^^^^
121

liuzhe-lz's avatar
liuzhe-lz committed
122
.. code-block:: python 
123

liuzhe-lz's avatar
liuzhe-lz committed
124
    {"_type": "lognormal", "_value": [mu, sigma]}
125

liuzhe-lz's avatar
liuzhe-lz committed
126
127
128
129
130
131
132
133
134
135
136
137
138
* The variable value is drawn according to ``exp(normal(mu, sigma))`` so that the logarithm of the return value is normally distributed. When optimizing, this variable is constrained to be positive.

qlognormal
^^^^^^^^^^

.. code-block:: python 

    {"_type": "qlognormal", "_value": [mu, sigma, q]}

* The variable value is determined using ``round(exp(normal(mu, sigma)) / q) * q``
* Suitable for a discrete variable with respect to which the objective is smooth and gets smoother with the size of the variable, which is bounded from one side.

.. _hpo-space-support:
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

Search Space Types Supported by Each Tuner
------------------------------------------

.. list-table::
   :header-rows: 1
   :widths: auto

   * - 
     - choice
     - choice(nested)
     - randint
     - uniform
     - quniform
     - loguniform
     - qloguniform
     - normal
     - qnormal
     - lognormal
     - qlognormal
liuzhe-lz's avatar
liuzhe-lz committed
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226

   * - :class:`TPE <nni.algorithms.hpo.tpe_tuner.TpeTuner>`
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓

   * - :class:`Random <nni.algorithms.hpo.random_tuner.RandomTuner>`
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓

   * - :class:`Grid Search <nni.algorithms.hpo.gridsearch_tuner.GridSearchTuner>`
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓

   * - :class:`Anneal <nni.algorithms.hpo.hyperopt_tuner.HyperoptTuner>`
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓

   * - :class:`Evolution <nni.algorithms.hpo.evolution_tuner.EvolutionTuner>`
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓

   * - :class:`SMAC <nni.algorithms.hpo.smac_tuner.SMACTuner>`
     - ✓
227
     - 
liuzhe-lz's avatar
liuzhe-lz committed
228
229
230
231
     - ✓
     - ✓
     - ✓
     - ✓
232
233
234
235
236
     - 
     - 
     - 
     - 
     - 
liuzhe-lz's avatar
liuzhe-lz committed
237
238
239

   * - :class:`Batch <nni.algorithms.hpo.batch_tuner.BatchTuner>`
     - ✓
240
241
242
243
244
245
246
247
248
249
     - 
     - 
     - 
     - 
     - 
     - 
     - 
     - 
     - 
     - 
liuzhe-lz's avatar
liuzhe-lz committed
250
251
252

   * - :class:`Hyperband <nni.algorithms.hpo.hyperband_advisor.Hyperband>`
     - ✓
253
     - 
liuzhe-lz's avatar
liuzhe-lz committed
254
255
256
257
258
259
260
261
262
263
264
265
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓

   * - :class:`Metis <nni.algorithms.hpo.metis_tuner.MetisTuner>`
     - ✓
266
     - 
liuzhe-lz's avatar
liuzhe-lz committed
267
268
269
     - ✓
     - ✓
     - ✓
270
271
272
273
274
275
     - 
     - 
     - 
     - 
     - 
     - 
liuzhe-lz's avatar
liuzhe-lz committed
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291

   * - :class:`BOHB <nni.algorithms.hpo.bohb_advisor.BOHB>`
     - choice
     - choice(nested)
     - randint
     - uniform
     - quniform
     - loguniform
     - qloguniform
     - normal
     - qnormal
     - lognormal
     - qlognormal

   * - :class:`GP <nni.algorithms.hpo.gp_tuner.GPTuner>`
     - ✓
292
     - 
liuzhe-lz's avatar
liuzhe-lz committed
293
294
295
296
297
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
298
299
300
301
     - 
     - 
     - 
     - 
liuzhe-lz's avatar
liuzhe-lz committed
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

   * - :class:`PBT <nni.algorithms.hpo.pbt_tuner.PBTTuner>`
     - choice
     - choice(nested)
     - randint
     - uniform
     - quniform
     - loguniform
     - qloguniform
     - normal
     - qnormal
     - lognormal
     - qlognormal

   * - :class:`DNGO <nni.algorithms.hpo.dngo_tuner.DNGOTuner>`
     - ✓
98may's avatar
98may committed
318
     - 
liuzhe-lz's avatar
liuzhe-lz committed
319
320
321
322
323
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓
98may's avatar
98may committed
324
325
326
327
     - 
     - 
     - 
     - 
328
329
330
331


Known Limitations:

liuzhe-lz's avatar
liuzhe-lz committed
332
333
334
335
336
* GP Tuner, Metis Tuner and DNGO tuner support only **numerical values** in search space
  (``choice`` type values can be no-numerical with other tuners, e.g. string values).
  Both GP Tuner and Metis Tuner use Gaussian Process Regressor(GPR).
  GPR make predictions based on a kernel function and the 'distance' between different points,
  it's hard to get the true distance between no-numerical values.
337

liuzhe-lz's avatar
liuzhe-lz committed
338
* Note that for nested search space:
339

liuzhe-lz's avatar
liuzhe-lz committed
340
  * Only TPE/Random/Grid Search/Anneal/Evolution tuners support nested search space.