# NNI Annotation

## 概述

为了获得良好的用户体验并减少对以后代码的影响，NNI 设计了通过 Annotation（标记）来使用的语法。 通过 Annotation，只需要在代码中加入一些注释字符串，就能启用 NNI，完全不影响代码原先的执行逻辑。

样例如下：

```python
'''@nni.variable(nni.choice(0.1, 0.01, 0.001), name=learning_rate)'''
learning_rate = 0.1
```

此样例中，NNI 会从 (0.1, 0.01, 0.001) 中选择一个值赋给 learning_rate 变量。 第一行就是 NNI 的 Annotation，是 Python 中的一个字符串。 接下来的一行需要是赋值语句。 NNI 会根据 Annotation 行的信息，来给这一行的变量赋上相应的值。

通过这种方式，不需要修改任何代码，代码既可以直接运行，又可以使用 NNI 来调参。

## Annotation 的类型：

NNI 中，有 4 种类型的 Annotation；

### 1. 变量

`'''@nni.variable(sampling_algo, name)'''`

`@nni.variable` 用来标记变量。

**参数**

- **sampling_algo**: 指定搜索空间的采样算法。 可将其换成 NNI 支持的其它采样函数，函数要以 `nni.` 开头。例如，`choice` 或 `uniform`，详见 [SearchSpaceSpec](SearchSpaceSpec.md)。 
- **name**: 将被赋值的变量名称。 注意，此参数应该与下面一行等号左边的值相同。

例如：

```python
'''@nni.variable(nni.choice(0.1, 0.01, 0.001), name=learning_rate)'''
learning_rate = 0.1
```

### 2. 函数

`'''@nni.function_choice(*functions, name)'''`

`@nni.function_choice` 可以从几个函数中选择一个来执行。

**参数**

- **\*functions**: 可选择的函数。 注意，必须是包括参数的完整函数调用。 例如 `max_pool(hidden_layer, pool_size)`。
- **name**: 将被替换的函数名称。

例如：

```python
"""@nni.function_choice(max_pool(hidden_layer, pool_size), avg_pool(hidden_layer, pool_size), name=max_pool)"""
h_pooling = max_pool(hidden_layer, pool_size)
```

### 3. 中间结果

`'''@nni.report_intermediate_result(metrics)'''`

`@nni.report_intermediate_result` 用来返回中间结果，这和 <Trials.md> 中的 `nni.report_intermediate_result` 用法一样。

### 4. 最终结果

`'''@nni.report_final_result(metrics)'''`

`@nni.report_final_result` 用来返回当前 Trial 的最终结果，这和 <Trials.md> 中的 `nni.report_final_result` 用法一样。