Unverified Commit df4f05c7 authored by Chi Song's avatar Chi Song Committed by GitHub
Browse files

add Chinese translation (#661)

parent b38c0431
# NNI 中使用 Hyperband
## 1. 介绍
[Hyperband](https://arxiv.org/pdf/1603.06560.pdf) 是一种流行的自动机器学习算法。 Hyperband 的基本思想是对配置分组,每组有 `n` 个随机生成的超参配置,每个配置使用 `r` 次资源(如,epoch 数量,批处理数量等)。 当 `n` 个配置完成后,会选择最好的 `n/eta` 个配置,并增加 `r*eta` 次使用的资源。 最后,会选择出的最好配置。
## 2. 实现并行
首先,此样例是基于 MsgDispatcherBase 来实现的自动机器学习算法,而不是基于 Tuner 和Assessor。 这种实现方法下,Hyperband 集成了 Tuner 和 Assessor 两者的功能,因而将它叫做 Advisor。
其次,本实现完全利用了 Hyperband 内部的并行性。 具体来说,下一个分组不会严格的在当前分组结束后再运行,只要有资源,就可以开始运行新的分组。
## 3. 用法
要使用 Hyperband,需要在 Experiment 的 YAML 配置文件进行如下改动。
advisor:
#可选项: Hyperband
builtinAdvisorName: Hyperband
classArgs:
#R: 最大的步骤
R: 100
#eta: 丢弃的 Trial 的比例
eta: 3
#可选项: maximize, minimize
optimize_mode: maximize
注意,一旦使用了 Advisor,就不能在配置文件中添加 Tuner 和 Assessor。 使用 Hyperband 时,Trial 代码收到的超参(如键值对)中,除了用户定义的超参,会多一个 `STEPS`**使用 `STEPS`,Trial 能够控制其运行的时间。</p>
对于 Trial 代码中 `report_intermediate_result(metric)``report_final_result(metric)`**`指标` 应该是数值,或者用一个 dict,并保证其中有键值为 default 的项目,其值也为数值型**。 这是需要进行最大化或者最小化优化的数值,如精度或者损失度。
`R``eta` 是 Hyperband 中可以改动的参数。 `R` 表示可以分配给配置的最大步数(STEPS)。 这里,STEPS 可以代表 epoch 或 批处理数量。 `STEPS` 应该被 Trial 代码用来控制运行的次数。 参考样例 `examples/trials/mnist-hyperband/` ,了解详细信息。
`eta` 表示 `n` 个配置中的 `n/eta` 个配置会留存下来,并用更多的 STEPS 来运行。
下面是 `R=81``eta=3` 时的样例:
| | s=4 | s=3 | s=2 | s=1 | s=0 |
| - | ---- | ---- | ---- | ---- | ---- |
| i | n r | n r | n r | n r | n r |
| 0 | 81 1 | 27 3 | 9 9 | 6 27 | 5 81 |
| 1 | 27 3 | 9 9 | 3 27 | 2 81 | |
| 2 | 9 9 | 3 27 | 1 81 | | |
| 3 | 3 27 | 1 81 | | | |
| 4 | 1 81 | | | | |
`s` 表示分组, `n` 表示生成的配置数量,相应的 `r` 表示配置会运行多少 STEPS。 `i` 表示轮数,如分组 4 有 5 轮,分组 3 有 4 轮。
关于如何实现 Trial 代码,参考 `examples/trials/mnist-hyperband/` 中的说明。
## 4. 待改进
当前实现的 Hyperband 算法可以通过改进支持的提前终止算法来提高,原因是最好的 `n/eta` 个配置并不一定都表现很好。 不好的配置可以更早的终止。
在当前实现中,遵循了[此论文](https://arxiv.org/pdf/1603.06560.pdf)的设计,配置都是随机生成的。 要进一步提升,配置生成过程可以利用更高级的算法。
\ No newline at end of file
# NNI 中的 Network Morphism Tuner
## 1. 介绍
[Autokeras](https://arxiv.org/abs/1806.10282) 是使用 Network Morphism 算法的流行的自动机器学习工具。 Autokeras 的基本理念是使用贝叶斯回归来预测神经网络架构的指标。 每次都会从父网络生成几个子网络。 然后使用朴素贝叶斯回归,从网络的历史训练结果来预测它的指标值。 接下来,会选择预测结果最好的子网络加入训练队列中。 在[此代码](https://github.com/jhfjhfj1/autokeras)的启发下,我们在 NNI 中实现了 Network Morphism 算法。
要了解 Network Morphism Trial 的用法,参考 [Readme.md](../../../../../examples/trials/network-morphism/README.md),了解更多细节。
## 2. 用法
要使用 Network Morphism,需要如下配置 `config.yml` 文件:
```yaml
tuner:
#选择: NetworkMorphism
builtinTunerName: NetworkMorphism
classArgs:
#可选项: maximize, minimize
optimize_mode: maximize
#当前仅支持 cv 领域
task: cv
#修改来支持实际图像宽度
input_width: 32
#修改来支持实际图像通道
input_channel: 3
#修改来支持实际的分类数量
n_output_node: 10
```
在训练过程中,会生成一个 JSON 文件来表示网络图。 可调用 "json\_to\_graph()" 函数来将 JSON 文件转化为 Pytoch 或 Keras 模型。
```python
import nni
from nni.networkmorphism_tuner.graph import json_to_graph
def build_graph_from_json(ir_model_json):
"""从 JSON 生成 Pytorch 模型
"""
graph = json_to_graph(ir_model_json)
model = graph.produce_torch_model()
return model
# 从网络形态 Tuner 中获得下一组参数
RCV_CONFIG = nni.get_next_parameter()
# 调用函数来生成 Pytorch 或 Keras 模型
net = build_graph_from_json(RCV_CONFIG)
# 训练过程
# ....
# 将最终精度返回给 NNI
nni.report_final_result(best_acc)
```
## 3. 文件结构
Tuner 有大量的文件、函数和类。 这里只简单介绍最重要的文件:
- `networkmorphism_tuner.py` 是使用 network morphism 算法的 Tuner。
- `bayesian.py` 是用来基于已经搜索道德模型来预测未知模型指标的贝叶斯算法。
- `graph.py` 是元图数据结构。 类 Graph 表示了模型的神经网络图。
- Graph 从模型中抽取神经网络。
- 图中的每个节点都是层之间的中间张量。
- 在图中,边表示层。
- 注意,多条边可能会表示同一层。
- `graph_transformer.py` 包含了一些图转换,包括变宽,变深,或在图中增加跳跃连接。
- `layers.py` 包括模型中用到的所有层。
- `layer_transformer.py` 包含了一些层转换,包括变宽,变深,或在层中增加跳跃连接。
- `nn.py` 包含生成初始化网的类。
- `metric.py` 包括了一些指标类,如 Accuracy 和 MSE。
- `utils.py` 是使用 Keras 在数据集 `cifar10` 上搜索神经网络的样例。
## 4. 网络表示的 JSON 样例
这是样例定义的中间表示 JSON 文件,它会在架构搜索过程中从 Tuner 传到 Trial。 可调用 "json\_to\_graph()" 函数来将 JSON 文件转化为 Pytoch 或 Keras 模型。 样例如下。
```json
{
"input_shape": [32, 32, 3],
"weighted": false,
"operation_history": [],
"layer_id_to_input_node_ids": {"0": [0],"1": [1],"2": [2],"3": [3],"4": [4],"5": [5],"6": [6],"7": [7],"8": [8],"9": [9],"10": [10],"11": [11],"12": [12],"13": [13],"14": [14],"15": [15],"16": [16]
},
"layer_id_to_output_node_ids": {"0": [1],"1": [2],"2": [3],"3": [4],"4": [5],"5": [6],"6": [7],"7": [8],"8": [9],"9": [10],"10": [11],"11": [12],"12": [13],"13": [14],"14": [15],"15": [16],"16": [17]
},
"adj_list": {
"0": [[1, 0]],
"1": [[2, 1]],
"2": [[3, 2]],
"3": [[4, 3]],
"4": [[5, 4]],
"5": [[6, 5]],
"6": [[7, 6]],
"7": [[8, 7]],
"8": [[9, 8]],
"9": [[10, 9]],
"10": [[11, 10]],
"11": [[12, 11]],
"12": [[13, 12]],
"13": [[14, 13]],
"14": [[15, 14]],
"15": [[16, 15]],
"16": [[17, 16]],
"17": []
},
"reverse_adj_list": {
"0": [],
"1": [[0, 0]],
"2": [[1, 1]],
"3": [[2, 2]],
"4": [[3, 3]],
"5": [[4, 4]],
"6": [[5, 5]],
"7": [[6, 6]],
"8": [[7, 7]],
"9": [[8, 8]],
"10": [[9, 9]],
"11": [[10, 10]],
"12": [[11, 11]],
"13": [[12, 12]],
"14": [[13, 13]],
"15": [[14, 14]],
"16": [[15, 15]],
"17": [[16, 16]]
},
"node_list": [
[0, [32, 32, 3]],
[1, [32, 32, 3]],
[2, [32, 32, 64]],
[3, [32, 32, 64]],
[4, [16, 16, 64]],
[5, [16, 16, 64]],
[6, [16, 16, 64]],
[7, [16, 16, 64]],
[8, [8, 8, 64]],
[9, [8, 8, 64]],
[10, [8, 8, 64]],
[11, [8, 8, 64]],
[12, [4, 4, 64]],
[13, [64]],
[14, [64]],
[15, [64]],
[16, [64]],
[17, [10]]
],
"layer_list": [
[0, ["StubReLU", 0, 1]],
[1, ["StubConv2d", 1, 2, 3, 64, 3]],
[2, ["StubBatchNormalization2d", 2, 3, 64]],
[3, ["StubPooling2d", 3, 4, 2, 2, 0]],
[4, ["StubReLU", 4, 5]],
[5, ["StubConv2d", 5, 6, 64, 64, 3]],
[6, ["StubBatchNormalization2d", 6, 7, 64]],
[7, ["StubPooling2d", 7, 8, 2, 2, 0]],
[8, ["StubReLU", 8, 9]],
[9, ["StubConv2d", 9, 10, 64, 64, 3]],
[10, ["StubBatchNormalization2d", 10, 11, 64]],
[11, ["StubPooling2d", 11, 12, 2, 2, 0]],
[12, ["StubGlobalPooling2d", 12, 13]],
[13, ["StubDropout2d", 13, 14, 0.25]],
[14, ["StubDense", 14, 15, 64, 64]],
[15, ["StubReLU", 15, 16]],
[16, ["StubDense", 16, 17, 64, 10]]
]
}
```
每个模型的定义都是一个 JSON 对象 (也可以认为模型是一个 [有向无环图](https://en.wikipedia.org/wiki/Directed_acyclic_graph)):
- `input_shape` 是整数的列表,不包括批量维度。
- `weighted` 表示是否权重和偏移值应该包含在此神经网络图中。
- `operation_history` 是保存了所有网络形态操作的列表。
- `layer_id_to_input_node_ids` 是字典实例,将层的标识映射到输入节点标识。
- `layer_id_to_output_node_ids` 是字典实例,将层的标识映射到输出节点标识。
- `adj_list` 是二维列表。 是图的邻接列表。 第一维是张量标识。 在每条边的列表中,元素是两元组(张量标识,层标识)。
- `reverse_adj_list` 是与 adj_list 格式一样的反向邻接列表。
- `node_list` 是一个整数列表。 列表的索引是标识。
- `layer_list` 是层的列表。 列表的索引是标识。
- 对于 `StubConv (StubConv1d, StubConv2d, StubConv3d)`,后面的数字表示节点的输入 id(或 id 列表),节点输出 id,input_channel,filters,kernel_size,stride 和 padding。
- 对于 `StubDense`,后面的数字表示节点的输入 id (或 id 列表),节点输出 id,input_units 和 units。
- 对于 `StubBatchNormalization (StubBatchNormalization1d, StubBatchNormalization2d, StubBatchNormalization3d)`,后面的数字表示节点输入 id(或 id 列表),节点输出 id,和特征数量。
- 对于 `StubDropout(StubDropout1d, StubDropout2d, StubDropout3d)`,后面的数字表示节点的输入 id (或 id 列表),节点的输出 id 和 dropout 率。
- 对于 `StubPooling (StubPooling1d, StubPooling2d, StubPooling3d)`后面的数字表示节点的输入 id(或 id 列表),节点输出 id,kernel_size, stride 和 padding。
- 对于其它层,后面的数字表示节点的输入 id(或 id 列表)以及节点的输出 id。
## 5. TODO
下一步,会将 API 从固定的网络生成方法改为更多的网络操作生成方法。 此外,还会使用 ONNX 格式来替代 JSON 作为中间表示结果。
\ No newline at end of file
# 集成文档:NNI 上使用 SMAC
\ No newline at end of file
# Web 界面
## 查看概要页面
点击标签 "Overview"。
* 查看 Experiment 参数。
* 查看最好结果的 Trial。
* 查看搜索空间 JSON 文件。
## 查看任务准确度
点击 "Default Metric" 来查看所有 Trial 的点图。 将鼠标悬停到某个点查看其准确度。
## 查看超参
点击 "Hyper Parameter" 标签查看图像。
* 可选择百分比查看最好的 Trial。
* 选择两个轴来交换位置。
## 查看 Trial 状态
点击 "Trials Detail" 标签查看所有 Trial 的状态。 特别是:
* Trial duration:Trial 执行时间的条形图。
* Trial 详情:Trial 的 id,持续时间,开始时间,结束时间,状态,精度和搜索空间。
* Kill: 可终止正在运行的任务。
## 反馈
[已知问题](https://github.com/Microsoft/nni/issues)
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment