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

Chinese translation (#984)

parent c8ef4141
...@@ -60,7 +60,8 @@ NNI (Neural Network Intelligence) 是自动机器学习(AutoML)的工具包 ...@@ -60,7 +60,8 @@ NNI (Neural Network Intelligence) 是自动机器学习(AutoML)的工具包
<li><a href="docs/zh_CN/Builtin_Tuner.md#NetworkMorphism">Network Morphism</a></li> <li><a href="docs/zh_CN/Builtin_Tuner.md#NetworkMorphism">Network Morphism</a></li>
<li><a href="examples/tuners/enas_nni/README_zh_CN.md">ENAS</a></li> <li><a href="examples/tuners/enas_nni/README_zh_CN.md">ENAS</a></li>
<li><a href="docs/zh_CN/Builtin_Tuner.md#NetworkMorphism#MetisTuner">Metis Tuner</a></li> <li><a href="docs/zh_CN/Builtin_Tuner.md#NetworkMorphism#MetisTuner">Metis Tuner</a></li>
</ul> <li><a href="docs/zh_CN/Builtin_Tuner.md#BOHB">BOHB</a></li>
</ul>
<a href="docs/zh_CN/Builtin_Assessors.md#assessor">Assessor(评估器)</a> <a href="docs/zh_CN/Builtin_Assessors.md#assessor">Assessor(评估器)</a>
<ul> <ul>
<li><a href="docs/zh_CN/Builtin_Assessors.md#Medianstop">Median Stop</a></li> <li><a href="docs/zh_CN/Builtin_Assessors.md#Medianstop">Median Stop</a></li>
...@@ -69,7 +70,7 @@ NNI (Neural Network Intelligence) 是自动机器学习(AutoML)的工具包 ...@@ -69,7 +70,7 @@ NNI (Neural Network Intelligence) 是自动机器学习(AutoML)的工具包
</td> </td>
<td> <td>
<ul> <ul>
<li><a href="docs/zh_CN/tutorial_1_CR_exp_local_api.md">本地计算机</a></li> <li><a href="docs/zh_CN/LocalMode.md">本地计算机</a></li>
<li><a href="docs/zh_CN/RemoteMachineMode.md">远程计算机</a></li> <li><a href="docs/zh_CN/RemoteMachineMode.md">远程计算机</a></li>
<li><a href="docs/zh_CN/PAIMode.md">OpenPAI</a></li> <li><a href="docs/zh_CN/PAIMode.md">OpenPAI</a></li>
<li><a href="docs/zh_CN/KubeflowMode.md">Kubeflow</a></li> <li><a href="docs/zh_CN/KubeflowMode.md">Kubeflow</a></li>
...@@ -193,7 +194,7 @@ NNI (Neural Network Intelligence) 是自动机器学习(AutoML)的工具包 ...@@ -193,7 +194,7 @@ NNI (Neural Network Intelligence) 是自动机器学习(AutoML)的工具包
## **教程** ## **教程**
* [在本机运行 Experiment (支持多 GPU 卡)](docs/zh_CN/tutorial_1_CR_exp_local_api.md) * [在本机运行 Experiment (支持多 GPU 卡)](docs/zh_CN/LocalMode.md)
* [在多机上运行 Experiment](docs/zh_CN/RemoteMachineMode.md) * [在多机上运行 Experiment](docs/zh_CN/RemoteMachineMode.md)
* [在 OpenPAI 上运行 Experiment](docs/zh_CN/PAIMode.md) * [在 OpenPAI 上运行 Experiment](docs/zh_CN/PAIMode.md)
* [在 Kubeflow 上运行 Experiment。](docs/zh_CN/KubeflowMode.md) * [在 Kubeflow 上运行 Experiment。](docs/zh_CN/KubeflowMode.md)
......
# NAS 算法对比
*匿名作者*
训练并对比 Autokeras, DARTS, ENAS 和 NAO 这些算法的效果。
源码链接如下:
- Autokeras: <https://github.com/jhfjhfj1/autokeras>
- DARTS: <https://github.com/quark0/darts>
- ENAS: <https://github.com/melodyguan/enas>
- NAO: <https://github.com/renqianluo/NAO>
## 实验描述
为了避免算法仅仅在 **CIFAR-10** 数据集上过拟合,还对比了包括 Fashion-MNIST, CIFAR-100, OUI-Adience-Age, ImageNet-10-1 (ImageNet的子集) 和 ImageNet-10-2 (ImageNet 的另一个子集) 在内的其它 5 个数据集。 分别从 ImageNet 中抽取 10 种不同类别标签的子集,组成 ImageNet10-1 和 ImageNet10-2 数据集 。
| 数据集 | 训练数据集大小 | 类别标签数 | 数据集说明 |
|:--------------------------------------------------------------------------------------- | ------- | ----- | ----------------------------------------------------------- |
| [Fashion-MNIST](https://github.com/zalandoresearch/fashion-mnist) | 60,000 | 10 | T恤上衣,裤子,套头衫,连衣裙,外套,凉鞋,衬衫,运动鞋,包和踝靴。 |
| [CIFAR-10](https://www.cs.toronto.edu/~kriz/cifar.html) | 50,000 | 10 | 飞机,汽车,鸟类,猫,鹿,狗,青蛙,马,船和卡车。 |
| [CIFAR-100](https://www.cs.toronto.edu/~kriz/cifar.html) | 50,000 | 100 | 和 CIFAR-10 类似,但总共有 100 个类,每个类有 600 张图。 |
| [OUI-Adience-Age](https://talhassner.github.io/home/projects/Adience/Adience-data.html) | 26,580 | 8 | 8 个年龄组类别 (0-2, 4-6, 8-13, 15-20, 25-32, 38-43, 48-53, 60-)。 |
| [ImageNet-10-1](http://www.image-net.org/) | 9,750 | 10 | 咖啡杯、电脑键盘、餐桌、衣柜、割草机、麦克风、秋千、缝纫机、里程表和燃气泵。 |
| [ImageNet-10-2](http://www.image-net.org/) | 9,750 | 10 | 鼓,班吉,口哨,三角钢琴,小提琴,管风琴,原声吉他,长号,长笛和萨克斯。 |
没有改变源码中的 Fine-tuning 方法。 为了匹配每个任务,改变了源码中模型的输入图片大小和输出类别数目的部分。
所有 NAS 方法模型搜索时间和重训练时间都是**两天**。 所有结果都是基于**三次重复实验**。 评估计算机有一块 Nvidia Tesla P100 GPU、112GB 内存和 2.60GHz CPU (Intel E5-2690)。
NAO 需要太多的计算资源,因此只使用提供 Pipeline 脚本的 NAO-WS。
对于 Autkeras,使用了 0.2.18 版本的代码, 因为这是开始实验时的最新版本。
## NAS 结果对比
| NAS | AutoKeras (%) | ENAS (macro) (%) | ENAS (micro) (%) | DARTS (%) | NAO-WS (%) |
| --------------- |:-------------:|:----------------:|:----------------:|:---------:|:----------:|
| Fashion-MNIST | 91.84 | 95.44 | 95.53 | **95.74** | 95.20 |
| CIFAR-10 | 75.78 | 95.68 | **96.16** | 94.23 | 95.64 |
| CIFAR-100 | 43.61 | 78.13 | 78.84 | **79.74** | 75.75 |
| OUI-Adience-Age | 63.20 | **80.34** | 78.55 | 76.83 | 72.96 |
| ImageNet-10-1 | 61.80 | 77.07 | 79.80 | **80.48** | 77.20 |
| ImageNet-10-2 | 37.20 | 58.13 | 56.47 | 60.53 | **61.20** |
很遗憾,我们无法复现论文中所有的结果。
论文中提供的最佳或平均结果:
| NAS | AutoKeras(%) | ENAS (macro) (%) | ENAS (micro) (%) | DARTS (%) | NAO-WS (%) |
| --------- | ------------ |:----------------:|:----------------:|:--------------:|:-----------:|
| CIFAR- 10 | 88.56(best) | 96.13(best) | 97.11(best) | 97.17(average) | 96.47(best) |
对于 AutoKeras,由于其算法中的随机因素,它在所有数据集中的表现相对较差。
对于ENAS,ENAS(macro)在 OUI-Adience-Age 数据集中表现较好,并且 ENAS(micro)在 CIFAR-10 数据集中表现较好。
对于DARTS,在某些数据集上具有良好的结果,但在某些数据集中具有比较大的方差。 DARTS 三次实验中的差异在 OUI-Audience-Age 数据集上可达 5.37%(绝对值),在 ImageNet-10-1 数据集上可达4.36%(绝对值)。
对于 NAO-WS,它在 ImageNet-10-2 中显示良好,但在 OUI-Adience-Age 中表现非常差。
## 参考文献
1. Jin, Haifeng, Qingquan Song, and Xia Hu. "Efficient neural architecture search with network morphism." *arXiv preprint arXiv:1806.10282* (2018).
2. Liu, Hanxiao, Karen Simonyan, and Yiming Yang. "Darts: Differentiable architecture search." arXiv preprint arXiv:1806.09055 (2018).
3. Pham, Hieu, et al. "Efficient Neural Architecture Search via Parameters Sharing." international conference on machine learning (2018): 4092-4101.
4. Luo, Renqian, et al. "Neural Architecture Optimization." neural information processing systems (2018): 7827-7838.
\ No newline at end of file
######################
博客
######################
.. toctree::
:maxdepth: 2
NAS 算法比较<NASComparison>
...@@ -15,9 +15,10 @@ NNI 提供了先进的调优算法,使用上也很简单。 下面是内置 Tu ...@@ -15,9 +15,10 @@ NNI 提供了先进的调优算法,使用上也很简单。 下面是内置 Tu
| [**SMAC**](#SMAC) | SMAC 基于 Sequential Model-Based Optimization (SMBO,即序列的基于模型优化方法)。 它会利用使用过的结果好的模型(高斯随机过程模型),并将随机森林引入到 SMBO 中,来处理分类参数。 SMAC 算法包装了 Github 的 SMAC3。 注意:SMAC 需要通过 `nnictl package` 命令来安装。 [参考论文,](https://www.cs.ubc.ca/~hutter/papers/10-TR-SMAC.pdf) [Github 代码库](https://github.com/automl/SMAC3) | | [**SMAC**](#SMAC) | SMAC 基于 Sequential Model-Based Optimization (SMBO,即序列的基于模型优化方法)。 它会利用使用过的结果好的模型(高斯随机过程模型),并将随机森林引入到 SMBO 中,来处理分类参数。 SMAC 算法包装了 Github 的 SMAC3。 注意:SMAC 需要通过 `nnictl package` 命令来安装。 [参考论文,](https://www.cs.ubc.ca/~hutter/papers/10-TR-SMAC.pdf) [Github 代码库](https://github.com/automl/SMAC3) |
| [**Batch tuner**](#Batch) | Batch Tuner 能让用户简单的提供几组配置(如,超参选项的组合)。 当所有配置都执行完后,Experiment 即结束。 Batch Tuner 仅支持 choice 类型。 | | [**Batch tuner**](#Batch) | Batch Tuner 能让用户简单的提供几组配置(如,超参选项的组合)。 当所有配置都执行完后,Experiment 即结束。 Batch Tuner 仅支持 choice 类型。 |
| [**Grid Search**](#GridSearch) | Grid Search 会穷举定义在搜索空间文件中的所有超参组合。 网格搜索可以使用的类型有 choice, quniform, qloguniform。 quniform 和 qloguniform 中的数值 q 具有特别的含义(不同于搜索空间文档中的说明)。 它表示了在最高值与最低值之间采样的值的数量。 | | [**Grid Search**](#GridSearch) | Grid Search 会穷举定义在搜索空间文件中的所有超参组合。 网格搜索可以使用的类型有 choice, quniform, qloguniform。 quniform 和 qloguniform 中的数值 q 具有特别的含义(不同于搜索空间文档中的说明)。 它表示了在最高值与最低值之间采样的值的数量。 |
| [**Hyperband**](#Hyperband) | Hyperband 试图用有限的资源来探索尽可能多的组合,并发现最好的结果。 它的基本思路是生成大量的配置,并运行少量的步骤来找到有可能好的配置,然后继续训练找到其中更好的配置。 [参考论文](https://arxiv.org/pdf/1603.06560.pdf) | | [**Hyperband**](#Hyperband) | Hyperband 试图用有限的资源来探索尽可能多的组合,并发现最好的结果。 它的基本思路是生成大量的配置,并使用少量的资源来找到有可能好的配置,然后继续训练找到其中更好的配置。 [参考论文](https://arxiv.org/pdf/1603.06560.pdf) |
| [**Network Morphism**](#NetworkMorphism) | Network Morphism 提供了深度学习模型的自动架构搜索功能。 每个子网络都继承于父网络的知识和形态,并变换网络的不同形态,包括深度,宽度,跨层连接(skip-connection)。 然后使用历史的架构和指标,来估计子网络的值。 最后会选择最有希望的模型进行训练。 [参考论文](https://arxiv.org/abs/1806.10282) | | [**Network Morphism**](#NetworkMorphism) | Network Morphism 提供了深度学习模型的自动架构搜索功能。 每个子网络都继承于父网络的知识和形态,并变换网络的不同形态,包括深度,宽度,跨层连接(skip-connection)。 然后使用历史的架构和指标,来估计子网络的值。 最后会选择最有希望的模型进行训练。 [参考论文](https://arxiv.org/abs/1806.10282) |
| [**Metis Tuner**](#MetisTuner) | 大多数调参工具仅仅预测最优配置,而 Metis 的优势在于有两个输出:(a) 最优配置的当前预测结果, 以及 (b) 下一次 Trial 的建议。 它不进行随机取样。 大多数工具假设训练集没有噪声数据,但 Metis 会知道是否需要对某个超参重新采样。 [参考论文](https://www.microsoft.com/en-us/research/publication/metis-robustly-tuning-tail-latencies-cloud-systems/) | | [**Metis Tuner**](#MetisTuner) | 大多数调参工具仅仅预测最优配置,而 Metis 的优势在于有两个输出:(a) 最优配置的当前预测结果, 以及 (b) 下一次 Trial 的建议。 它不进行随机取样。 大多数工具假设训练集没有噪声数据,但 Metis 会知道是否需要对某个超参重新采样。 [参考论文](https://www.microsoft.com/en-us/research/publication/metis-robustly-tuning-tail-latencies-cloud-systems/) |
| [**BOHB**](#BOHB) | BOHB 是 Hyperband 算法的后续工作。 Hyperband 在生成新的配置时,没有利用已有的 Trial 结果,而本算法利用了 Trial 结果。 BOHB 中,HB 表示 Hyperband,BO 表示贝叶斯优化(Byesian Optimization)。 BOHB 会建立多个 TPE 模型,从而利用已完成的 Trial 生成新的配置。 [参考论文](https://arxiv.org/abs/1807.01774) |
<br /> <br />
...@@ -39,7 +40,7 @@ TPE 是一种黑盒优化方法,可以使用在各种场景中,通常情况 ...@@ -39,7 +40,7 @@ TPE 是一种黑盒优化方法,可以使用在各种场景中,通常情况
**参数** **参数**
* **optimize_mode** (*maximize 或 minimize,可选,默认值为 maximize*) - 如果为 'maximize',Tuner 会给出有可能产生较大值的参数组合。 如果为 'minimize',Tuner 会给出有可能产生较小值的参数组合 * **optimize_mode** (*maximize 或 minimize, 可选项, 默认值为 maximize*) - 如果为 'maximize',表示 Tuner 的目标是将指标最大化。 如果为 'minimize',表示 Tuner 的目标是将指标最小化
**使用样例:** **使用样例:**
...@@ -65,7 +66,7 @@ tuner: ...@@ -65,7 +66,7 @@ tuner:
**参数** **参数**
* **optimize_mode** (*maximize 或 minimize,可选,默认值为 maximize*) - 如果为 'maximize',Tuner 会给出有可能产生较大值的参数组合。 如果为 'minimize',Tuner 会给出有可能产生较小值的参数组合 * **optimize_mode** (*maximize 或 minimize, 可选项, 默认值为 maximize*) - 如果为 'maximize',表示 Tuner 的目标是将指标最大化。 如果为 'minimize',表示 Tuner 的目标是将指标最小化
**使用样例:** **使用样例:**
...@@ -89,7 +90,7 @@ tuner: ...@@ -89,7 +90,7 @@ tuner:
**参数** **参数**
* **optimize_mode** (*maximize 或 minimize,可选,默认值为 maximize*) - 如果为 'maximize',Tuner 会给出有可能产生较大值的参数组合。 如果为 'minimize',Tuner 会给出有可能产生较小值的参数组合 * **optimize_mode** (*maximize 或 minimize, 可选项, 默认值为 maximize*) - 如果为 'maximize',表示 Tuner 的目标是将指标最大化。 如果为 'minimize',表示 Tuner 的目标是将指标最小化
**使用样例:** **使用样例:**
...@@ -145,7 +146,7 @@ nnictl package install --name=SMAC ...@@ -145,7 +146,7 @@ nnictl package install --name=SMAC
**参数** **参数**
* **optimize_mode** (*maximize 或 minimize,可选,默认值为 maximize*) - 如果为 'maximize',Tuner 会给出有可能产生较大值的参数组合。 如果为 'minimize',Tuner 会给出有可能产生较小值的参数组合 * **optimize_mode** (*maximize 或 minimize, 可选项, 默认值为 maximize*) - 如果为 'maximize',表示 Tuner 的目标是将指标最大化。 如果为 'minimize',表示 Tuner 的目标是将指标最小化
**使用样例:** **使用样例:**
...@@ -232,8 +233,8 @@ tuner: ...@@ -232,8 +233,8 @@ tuner:
**参数** **参数**
* **optimize_mode** (*maximize 或 minimize,可选,默认值为 maximize*) - 如果为 'maximize',Tuner 会给出有可能产生较大值的参数组合。 如果为 'minimize',Tuner 会给出有可能产生较小值的参数组合 * **optimize_mode** (*maximize 或 minimize, 可选项, 默认值为 maximize*) - 如果为 'maximize',表示 Tuner 的目标是将指标最大化。 如果为 'minimize',表示 Tuner 的目标是将指标最小化
* **R** (*int, 可选, 默认为 60*) - 分配给 Trial 的最大 STEPS (可以是 mini-batches 或 epochs 的数值)。 每个 Trial 都需要用 STEPS 来控制运行的时间 * **R** (*int, 可选, 默认为 60*) - 分配给 Trial 的最大资源(可以是 mini-batches 或 epochs 的数值。 每个 Trial 都需要用 TRIAL_BUDGET 来控制运行的步数
* **eta** (*int, 可选, 默认为 3*) - `(eta-1)/eta` 是丢弃 Trial 的比例。 * **eta** (*int, 可选, 默认为 3*) - `(eta-1)/eta` 是丢弃 Trial 的比例。
**使用样例:** **使用样例:**
...@@ -266,7 +267,7 @@ advisor: ...@@ -266,7 +267,7 @@ advisor:
**参数** **参数**
* **optimize_mode** (*maximize 或 minimize,可选,默认值为 maximize*) - 如果为 'maximize',Tuner 会给出有可能产生较大值的参数组合。 如果为 'minimize',Tuner 会给出有可能产生较小值的参数组合 * **optimize_mode** (*maximize 或 minimize, 可选项, 默认值为 maximize*) - 如果为 'maximize',表示 Tuner 的目标是将指标最大化。 如果为 'minimize',表示 Tuner 的目标是将指标最小化
* **task** (*('cv'), 可选, 默认为 'cv'*) - 实验的领域,当前仅支持视觉(cv)。 * **task** (*('cv'), 可选, 默认为 'cv'*) - 实验的领域,当前仅支持视觉(cv)。
* **input_width** (*int, 可选, 默认为 = 32*) - 输入图像的宽度 * **input_width** (*int, 可选, 默认为 = 32*) - 输入图像的宽度
* **input_channel** (*int, 可选, 默认为 3*) - 输入图像的通道数 * **input_channel** (*int, 可选, 默认为 3*) - 输入图像的通道数
...@@ -306,7 +307,7 @@ Metis Tuner 需要先安装 [sklearn](https://scikit-learn.org/)。 可通过 `p ...@@ -306,7 +307,7 @@ Metis Tuner 需要先安装 [sklearn](https://scikit-learn.org/)。 可通过 `p
**参数** **参数**
* **optimize_mode** (*maximize 或 minimize,可选,默认值为 maximize*) - 如果为 'maximize',Tuner 会给出有可能产生较大值的参数组合。 如果为 'minimize',Tuner 会给出有可能产生较小值的参数组合 * **optimize_mode** (*'maximize''minimize', 可选项, 默认值为 'maximize'*) - 如果为 'maximize',表示 Tuner 的目标是将指标最大化。 如果为 'minimize',表示 Tuner 的目标是将指标最小化
**使用样例:** **使用样例:**
...@@ -316,4 +317,51 @@ tuner: ...@@ -316,4 +317,51 @@ tuner:
builtinTunerName: MetisTuner builtinTunerName: MetisTuner
classArgs: classArgs:
optimize_mode: maximize optimize_mode: maximize
```
<br />
<a name="BOHB"></a>
![](https://placehold.it/15/1589F0/000000?text=+) `BOHB Adivisor`
> 名称:**BOHB**
**安装**
BOHB Advisor 的使用依赖 [ConfigSpace](https://github.com/automl/ConfigSpace) 包,在第一次使用 BOHB 的时候,在命令行运行以下的指令来安装 ConfigSpace。
```bash
nnictl package install --name=BOHB
```
**建议场景**
与 Hyperband 类似, 当计算资源有限但搜索空间相对较大时, 建议使用此方法。 中间结果能够很好的反映最终结果的情况下,此算法会非常有效。 在这种情况下, 由于贝叶斯优化使用, 它可能会收敛到更好的配置。
**参数**
* **optimize_mode** (*maximize 或 minimize, 可选项, 默认值为 maximize*) - 如果为 'maximize',表示 Tuner 的目标是将指标最大化。 如果为 'minimize',表示 Tuner 的目标是将指标最小化。
* **min_budget** (*整数, 可选项, 默认值为 1*) - 运行一个试验给予的最低计算资源(budget),这里的计算资源通常使用mini-batches 或者 epochs。 该参数必须为正数。
* **max_budget** (*整数, 可选项, 默认值为 3*) - 运行一个试验给予的最大计算资源(budget),这里的计算资源通常使用 mini-batches 或者 epochs。 该参数必须大于“min_budget”。
* **eta** (*整数, 可选项, 默认值为3*) - 在每次迭代中,执行完整的“连续减半”算法。 在这里,当一个使用相同计算资源的子集结束后,选择表现前 1/eta 好的参数,给予更高的优先级,进入下一轮比较(会获得更多计算资源)。 该参数必须大于等于 2。
* **min_points_in_model**(*整数, 可选项, 默认值为None*): 建立核密度估计(KDE)要求的最小观察到的点。 默认值 None 表示 dim+1,当在该计算资源(budget)下试验过的参数已经大于等于`max{dim+1, min_points_in_model}` 时,BOHB 将会开始建立这个计算资源(budget)下对应的核密度估计(KDE)模型,然后用这个模型来指导参数的选取。 该参数必须为正数。(dim 指的是搜索空间中超参数的维度)
* **top_n_percent**(*整数, 可选项, 默认值为15*): 认为观察点为好点的百分数(在 1 到 99 之间,默认值为 15)。 区分表现好的点与坏的点是为了建立树形核密度估计模型。 比如,如果观察到了100个点的表现情况,同时把 top_n_percent 设置为 15,那么表现最好的 15个点将会用于创建表现好的点的分布 "l(x)",剩下的85个点将用于创建表现坏的点的分布 “g(x)”。
* **num_samples** (*整数, 可选项, 默认值为64*): 用于优化 EI 值的采样个数(默认值为64)。 在这个例子中,将根据 l(x) 的分布采样“num_samples”(默认值为64)个点。若优化的目标为最大化指标,则会返回其中 l(x)/g(x) 的值最大的点作为下一个试验的参数。 否则,使用值最小的点。
* **random_fraction**(*浮点数, 可选项, 默认值为0.33*): 使用模型的先验(通常是均匀)来随机采样的比例。
* **bandwidth_factor**(< 1>浮点数, 可选, 默认值为3.0 </em>): 为了鼓励多样性,把优化EI的点加宽,即把KDE中采样的点乘以这个因子,从而增加KDE中的带宽。 如果不熟悉 KDE,建议保留默认值。
* **min_bandwidth**(< 1>float, 可选, 默认值 = 0.001 </em>): 为了保持多样性, 即使所有好的样本对其中一个参数具有相同的值,使用最小带宽 (默认值: 1e-3) 而不是零。 如果不熟悉 KDE,建议保留默认值。
*目前 NNI 的浮点类型仅支持十进制表示,必须使用 0.333 来代替 1/3,0.001代替 1e-3。*
**使用样例:**
```yml
advisor:
builtinAdvisorName: BOHB
classArgs:
optimize_mode: maximize
min_budget: 1
max_budget: 27
eta: 3
``` ```
\ No newline at end of file
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
文档使用了 [sphinx](http://sphinx-doc.org/) 来生成,支持 [Markdown](https://guides.github.com/features/mastering-markdown/)[reStructuredText](http://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html) 格式。 所有文档都在 <docs> 目录下。 文档使用了 [sphinx](http://sphinx-doc.org/) 来生成,支持 [Markdown](https://guides.github.com/features/mastering-markdown/)[reStructuredText](http://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html) 格式。 所有文档都在 <docs> 目录下。
* 在提交文档改动前,请先**在本地生成文档**`cd docs/en_US && make html`,然后,可以在 `docs/en_US/_build/html` 目录下找到所有生成的网页。 请认真分析生成日志中的**每个 WARNING**,这非常有可能是或**空连接**或其它问题。 * 在提交文档改动前,请先**在本地生成文档**`cd docs/zh_CN && make html`,然后,可以在 `docs/zh_CN/_build/html` 目录下找到所有生成的网页。 请认真分析生成日志中的**每个 WARNING**,这非常有可能是或**空连接**或其它问题。
* 需要链接时,尽量使用**相对路径**。 但如果文档是 Markdown 格式的,并且: * 需要链接时,尽量使用**相对路径**。 但如果文档是 Markdown 格式的,并且:
......
...@@ -417,6 +417,14 @@ machineList: ...@@ -417,6 +417,14 @@ machineList:
**image** 设置了 **worker** 使用的 docker 映像。 **image** 设置了 **worker** 使用的 docker 映像。
- **localConfig**
**localConfig** 仅在 **trainingServicePlatform** 设为 `local` 时有效,否则,配置文件中不应该有 **localConfig** 部分。
- **gpuIndices**
**gpuIndices** 用于指定 GPU。设置此值后,只有指定的 GPU 会被用来运行 Trial 任务。 可指定单个或多个 GPU 的索引,多个 GPU 之间用逗号(,)隔开,例如 `1``0,1,3`
- **machineList** - **machineList**
如果 **trainingServicePlatform** 为 remote,则需要设置 **machineList**。否则应将其置为空。 如果 **trainingServicePlatform** 为 remote,则需要设置 **machineList**。否则应将其置为空。
...@@ -448,6 +456,10 @@ machineList: ...@@ -448,6 +456,10 @@ machineList:
- **passphrase** - **passphrase**
**passphrase** 用于保护 ssh 密钥,如果没有使用,可为空。 **passphrase** 用于保护 ssh 密钥,如果没有使用,可为空。
- **gpuIndices**
**gpuIndices** 用于指定 GPU。设置此值后,远程计算机上只有指定的 GPU 会被用来运行 Trial 任务。 可指定单个或多个 GPU 的索引,多个 GPU 之间用逗号(,)隔开,例如 `1``0,1,3`
- **kubeflowConfig**: - **kubeflowConfig**:
......
# **How to Implement TrainingService in NNI** # **实现 NNI TrainingService**
## Overview ## 概述
TrainingService is a module related to platform management and job schedule in NNI. TrainingService is designed to be easily implemented, we define an abstract class TrainingService as the parent class of all kinds of TrainignService, users just need to inherit the parent class and complete their own clild class if they want to implement customized TrainingService. TrainingService 是与平台管理、任务调度相关的模块。 TrainingService 在设计上为了便于实现,将平台相关的公共属性抽象成类。用户只需要继承这个抽象类,并根据平台特点实现子类,便能够实现 TrainingService
## System architecture ## 系统架构
![](../img/NNIDesign.jpg) ![](../img/NNIDesign.jpg)
The brief system architecture of NNI is shown in the picture. NNIManager is the core management module of system, in charge of calling TrainingService to manage trial jobs and the communication between different modules. Dispatcher is a message processing center responsible for message dispatch. TrainingService is a module to manage trial jobs, it communicates with nniManager module, and has different instance according to different training platform. For the time being, NNI supports local platfrom, [remote platfrom](RemoteMachineMode.md), [PAI platfrom](PAIMode.md), [kubeflow platform](KubeflowMode.md) and [FrameworkController platfrom](FrameworkController.md). NNI 的架构如图所示。 NNIManager 是系统的核心管理模块,负责调用 TrainingService 来管理 Trial,并负责不同模块之间的通信。 Dispatcher 是消息处理中心。 TrainingService 是管理任务的模块,它和 NNIManager 通信,并且根据平台的特点有不同的实现。 当前,NNI 支持本地平台、[远程平台](RemoteMachineMode.md)[OpenPAI 平台](PAIMode.md)[Kubeflow 平台](KubeflowMode.md)[FrameworkController 平台](FrameworkController.md)
In this document, we introduce the brief design of TrainingService. If users want to add a new TrainingService instance, they just need to complete a child class to implement TrainingService, don't need to understand the code detail of NNIManager, Dispatcher or other modules. 在这个文档中,会简要介绍 TrainingService 的设计。 如果要添加新的 TrainingService,只需要继承 TrainingServcie 类并实现相应的方法,不需要理解NNIManagerDispatcher 等其它模块的细节。
## Folder structure of code ## 代码文件夹结构
NNI's folder structure is shown below: NNI 的文件夹结构如下:
nni nni
|- deployment |- deployment
...@@ -44,9 +44,9 @@ NNI's folder structure is shown below: ...@@ -44,9 +44,9 @@ NNI's folder structure is shown below:
| |-nni_trial_tool | |-nni_trial_tool
`nni/src/` folder stores the most source code of NNI. The code in this folder is related to NNIManager, TrainingService, SDK, WebUI and other modules. Users could find the abstract class of TrainingService in `nni/src/nni_manager/common/trainingService.ts` file, and they should put their own implemented TrainingService in `nni/src/nni_manager/training_service` folder. If users have implemented their own TrainingService code, they should also supplement the unit test of the code, and place them in `nni/src/nni_manager/training_service/test` folder. `nni/src` 文件夹存储 NNI 的大部分源代码。 这个文件夹中的代码和 NNIManagerTrainingServiceSDKWebUI 等模块有关。 用户可以在 `nni/src/nni_manager/common/trainingService.ts` 文件中找到 TrainingService 抽象类的代码,并且把自己实现的子类放到 `nni/src/nni_manager/training_service` 文件夹下。 如果用户实现了自己的 TrainingService,还需要同时实现相应的单元测试代码,并把单元测试放到 `nni/src/nni_manager/training_service/test` 文件夹下。
## Function annotation of TrainingService ## TrainingService 函数解释
abstract class TrainingService { abstract class TrainingService {
public abstract listTrialJobs(): Promise<TrialJobDetail[]>; public abstract listTrialJobs(): Promise<TrialJobDetail[]>;
...@@ -64,10 +64,10 @@ NNI's folder structure is shown below: ...@@ -64,10 +64,10 @@ NNI's folder structure is shown below:
} }
The parent class of TrainingService has a few abstract functions, users need to inherit the parent class and implement all of these abstract functions. TrainingService 父类有一些抽象方法,用户需要继承并实现这些抽象方法。
**setClusterMetadata(key: string, value: string)** **setClusterMetadata(key: string, value: string)**
ClusterMetadata is the data related to platform details, for examples, the ClusterMetadata defined in remote machine server is: ClusterMetadata 是与平台数据有关的方法,例如,在远程平台上的 ClusterMetadata 定义是:
export class RemoteMachineMeta { export class RemoteMachineMeta {
public readonly ip : string; public readonly ip : string;
...@@ -93,13 +93,13 @@ ClusterMetadata is the data related to platform details, for examples, the Clust ...@@ -93,13 +93,13 @@ ClusterMetadata is the data related to platform details, for examples, the Clust
} }
The metadata includes the host address, the username or other configuration related to the platform. Users need to define their own metadata format, and set the metadata instance in this function. This function is called before the experiment is started to set the configuration of remote machines. Metadata 中包括了主机地址,用户名和其它平台相关配置。 用户需要定义自己的 Metadata 格式,并在这个方法中相应实现。 这个方法在 Experiment 启动之前调用。
**getClusterMetadata(key: string)** **getClusterMetadata(key: string)**
This function will return the metadata value according to the values, it could be left empty if users don't need to use it. 这个方法返回 metadata 的内容,如果不需要使用这个方法,可将方法内容留空。
**submitTrialJob(form: JobApplicationForm)** **submitTrialJob(form: JobApplicationForm)**
SubmitTrialJob is a function to submit new trial jobs, users should generate a job instance in TrialJobDetail type. TrialJobDetail is defined as follow: SubmitTrialJob 是用来提交 Trial 任务的方法,用户需要在这个方法中生成 TrialJobDetail 类型的实例。 TrialJobDetail 定义如下:
interface TrialJobDetail { interface TrialJobDetail {
readonly id: string; readonly id: string;
...@@ -116,39 +116,39 @@ SubmitTrialJob is a function to submit new trial jobs, users should generate a j ...@@ -116,39 +116,39 @@ SubmitTrialJob is a function to submit new trial jobs, users should generate a j
} }
According to different kinds of implementation, users could put the job detail into a job queue, and keep fetching the job from the queue and start preparing and running them. Or they could finish preparing and running process in this function, and return job detail after the submit work. 根据不同的实现,用户可能需要把 Trial 任务放入队列中,并不断地从队里中取出任务进行提交。 或者也可以直接在这个方法中完成作业提交过程。
**cancelTrialJob(trialJobId: string, isEarlyStopped?: boolean)** **cancelTrialJob(trialJobId: string, isEarlyStopped?: boolean)**
If this function is called, the trial started by the platform should be canceled. Different kind of platform has diffenent methods to calcel a running job, this function should be implemented according to specific platform. 如果这个方法被调用, Trial 应该被取消执行。 不同的平台有不同的取消作业的方式,这个方法应该根据不同平台的特点,实现相应的细节。
**updateTrialJob(trialJobId: string, form: JobApplicationForm)** **updateTrialJob(trialJobId: string, form: JobApplicationForm)**
This function is called to update the trial job's status, trial job's status should be detected according to different platform, and be updated to `RUNNING`, `SUCCEED`, `FAILED` etc. 这个方法用来更新 Trial 的状态,不同平台有不同的检测作业状态的方法,并把状态更新为`RUNNING`, `SUCCEED`, `FAILED` 等。
**getTrialJob(trialJobId: string)** **getTrialJob(trialJobId: string)**
This function returns a trialJob detail instance according to trialJobId. 这个方法用来根据 Trial Id 来返回相应的 Trial 实例。
**listTrialJobs()** **listTrialJobs()**
Users should put all of trial job detail information into a list, and return the list. 用户需要在这个方法中把所有的 Trial 实例放入一个列表中,并返回。
**addTrialJobMetricListener(listener: (metric: TrialJobMetric) => void)** **addTrialJobMetricListener(listener: (metric: TrialJobMetric) => void)**
NNI will hold an EventEmitter to get job metrics, if there is new job metrics detected, the EventEmitter will be triggered. Users should start the EventEmitter in this function. NNI 会启动一个 EventEmitter 来处理作业的指标数据,如果有检测到有新的数据,EventEmitter就会被触发,来执行相应的事件。 用户需要在这个方法中开始 EventEmitter。
**removeTrialJobMetricListener(listener: (metric: TrialJobMetric) => void)** **removeTrialJobMetricListener(listener: (metric: TrialJobMetric) => void)**
Close the EventEmitter. 移除 EventEmitter
**run()** **run()**
The run() function is a main loop function in TrainingService, users could set a while loop to execute their logic code, and finish executing them when the experiment is stopped. Run() 函数是 TrainingService 的主循环,用户可以在这个函数中循环执行他们的代码逻辑,这个函数在实验结束前会一直循环执行。
**cleanUp()** **cleanUp()**
This function is called to clean up the environment when a experiment is stopped. Users should do the platform-related cleaning operation in this function. 当实验结束后,这个方法用来清除实验环境。 用户需要在这个方法中实现与平台相关的清除操作。
## TrialKeeper tool ## TrialKeeper 工具
NNI offers a TrialKeeper tool to help maintaining trial jobs. Users can find the source code in `nni/tools/nni_trial_tool`. If users want to run trial jobs in cloud platform, this tool will be a fine choice to help keeping trial running in the platform. The running architecture of TrialKeeper is show as follow: NNI 提供了 TrialKeeper 工具,用来帮助维护 Trial 任务。 可以在 `nni/tools/nni_trial_tool` 文件夹中找到 TrialKeeper 的源代码。 如果想要运行在云平台上,这是维护任务的好工具。 TrialKeeper 的架构如下:
![](../img/trialkeeper.jpg) ![](../img/trialkeeper.jpg)
When users submit a trial job to cloud platform, they should wrap their trial command into TrialKeeper, and start a TrialKeeper process in cloud platform. Notice that TrialKeeper use restful server to communicate with TrainingService, users should start a restful server in local machine to receive metrics sent from TrialKeeper. The source code about restful server could be found in `nni/src/nni_manager/training_service/common/clusterJobRestServer.ts`. 当用户需要在远程云平台上运行作业,要把作业启动的命令行传入 TrailKeeper 中,并在远程云平台上启动 TriakKeeper 进程。 注意,TrialKeeper 在远程平台中使用 RESTful 服务来和 TrainingService 进行通信,用户需要在本地机器启动一个 RESTful 服务来接受 TrialKeeper 的请求。 关于 RESTful 服务的源代码可以在 `nni/src/nni_manager/training_service/common/clusterJobRestServer.ts` 文件夹中找到.
## Reference ## 参考
For more information about how to debug, please [refer](HowToDebug.md). 更多关于如何调试的信息,请[参考这里](HowToDebug.md)
The guide line of how to contribute, please [refer](CONTRIBUTING). 关于如何贡献代码,请[参考这里](CONTRIBUTING)
\ No newline at end of file \ No newline at end of file
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
* [使用 NNIBoard](WebUI.md) * [使用 NNIBoard](WebUI.md)
* [定制搜索空间](SearchSpaceSpec.md) * [定制搜索空间](SearchSpaceSpec.md)
* [配置 Experiment](ExperimentConfig.md) * [配置 Experiment](ExperimentConfig.md)
* [如何在本机运行 Experiment (支持多 GPU 卡)?](tutorial_1_CR_exp_local_api.md) * [如何在本机运行 Experiment (支持多 GPU 卡)?](LocalMode.md)
* [如何在多机上运行 Experiment?](RemoteMachineMode.md) * [如何在多机上运行 Experiment?](RemoteMachineMode.md)
* [如何在 OpenPAI 上运行 Experiment?](PAIMode.md) * [如何在 OpenPAI 上运行 Experiment?](PAIMode.md)
* [如何通过 Kubeflow 在 Kubernetes 上运行 Experiment?](KubeflowMode.md) * [如何通过 Kubeflow 在 Kubernetes 上运行 Experiment?](KubeflowMode.md)
......
# **教程:使用 NNI API 在本地创建和运行 Experiment**
本教程会使用 [~/examples/trials/mnist] 样例来解释如何在本地使用 NNI API 来创建并运行 Experiment。
> 在开始前
要有一个使用卷积层对 MNIST 分类的代码,如 `mnist_before.py`
> 第一步:更新模型代码
对代码进行以下改动来启用 NNI API:
1.1 声明 NNI API
在 Trial 代码中通过 `import nni` 来导入 NNI API。
1.2 获取预定义的参数
参考下列代码片段:
RECEIVED_PARAMS = nni.get_next_parameter()
来获得 Tuner 分配的超参值。 `RECEIVED_PARAMS` 是一个对象,例如:
{"conv_size": 2, "hidden_size": 124, "learning_rate": 0.0307, "dropout_rate": 0.2029}
1.3 返回结果
使用 API:
`nni.report_intermediate_result(accuracy)`
返回 `accuracy` 的值给 Assessor。
使用 API:
`nni.report_final_result(accuracy)`
返回 `accuracy` 的值给 Tuner。
将改动保存到 `mnist.py` 文件中。
**注意**
accuracy - 如果使用 NNI 内置的 Tuner/Assessor,那么 `accuracy` 必须是数值(如 float, int)。在定制 Tuner/Assessor 时 `accuracy` 可以是任何类型的 Python 对象。
Assessor(评估器)- 会根据 Trial 的历史值(即其中间结果),来决定这次 Trial 是否应该提前终止。
Tuner(调参器) - 会根据探索的历史(所有 Trial 的最终结果)来生成下一组参数、架构。
> 第二步:定义搜索空间
`Step 1.2 获取预定义的参数` 中使用的超参定义在 `search_space.json` 文件中:
{
"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]},
"learning_rate":{"_type":"uniform","_value":[0.0001, 0.1]}
}
参考 [SearchSpaceSpec.md](./SearchSpaceSpec.md) 进一步了解搜索空间。
> 第三步:定义 Experiment
>
> > 3.1 启用 NNI API 模式
要启用 NNI 的 API 模式,需要将 useAnnotation 设置为 *false*,并提供搜索空间文件的路径(即第一步中定义的文件):
useAnnotation: false
searchSpacePath: /path/to/your/search_space.json
在 NNI 中运行 Experiment,只需要:
* 可运行的 Trial 的代码
* 实现或选择 Tuner
* 准备 YAML 的 Experiment 配置文件
* (可选) 实现或选择 Assessor
**准备 Trial**
> 在克隆代码后,可以在 ~/nni/examples 中找到一些样例,运行 `ls examples/trials` 查看所有 Trial 样例。
先从 NNI 提供的简单 Trial 样例,如 MNIST 开始。 NNI 样例在代码目录的 examples 中,运行 `ls ~/nni/examples/trials` 可以看到所有 Experiment 的样例。 执行下面的命令可轻松运行 NNI 的 mnist 样例:
python ~/nni/examples/trials/mnist-annotation/mnist.py
上面的命令会写在 YAML 文件中。 参考[这里](Trials.md)来写出自己的 Experiment 代码。
**准备 Tuner**: NNI 支持多种流行的自动机器学习算法,包括:Random Search(随机搜索),Tree of Parzen Estimators (TPE),Evolution(进化算法)等等。 也可以实现自己的 Tuner(参考[这里](Customize_Tuner.md))。下面使用了 NNI 内置的 Tuner:
tuner:
builtinTunerName: TPE
classArgs:
optimize_mode: maximize
*builtinTunerName* 用来指定 NNI 中的 Tuner,*classArgs* 是传入到 Tuner的参数(内置 Tuner 在[这里](Builtin_Tuner.md)),*optimization_mode* 表明需要最大化还是最小化 Trial 的结果。
**准备配置文件**:实现 Trial 的代码,并选择或实现自定义的 Tuner 后,就要准备 YAML 配置文件了。 NNI 为每个 Trial 样例都提供了演示的配置文件,用命令`cat ~/nni/examples/trials/mnist-annotation/config.yml` 来查看其内容。 大致内容如下:
authorName: your_name
experimentName: auto_mnist
# 并发运行数量
trialConcurrency: 2
# Experiment 运行时间
maxExecDuration: 3h
# 可为空,即数量不限
maxTrialNum: 100
# 可选值为: local, remote
trainingServicePlatform: local
# 可选值为: true, false
useAnnotation: true
tuner:
builtinTunerName: TPE
classArgs:
optimize_mode: maximize
trial:
command: python mnist.py
codeDir: ~/nni/examples/trials/mnist-annotation
gpuNum: 0
因为这个 Trial 代码使用了 NNI Annotation 的方法(参考[这里](AnnotationSpec.md) ),所以*useAnnotation* 为 true。 *command* 是运行 Trial 代码所需要的命令,*codeDir* 是 Trial 代码的相对位置。 命令会在此目录中执行。 同时,也需要提供每个 Trial 进程所需的 GPU 数量。
完成上述步骤后,可通过下列命令来启动 Experiment:
nnictl create --config ~/nni/examples/trials/mnist-annotation/config.yml
参考[这里](NNICTLDOC.md)来了解 *nnictl* 命令行工具的更多用法。
## 查看 Experiment 结果
Experiment 应该一直在运行。 除了 *nnictl* 以外,还可以通过 NNI 的网页来查看 Experiment 进程,进行控制和其它一些有意思的功能。
## 使用多个本地 GPU 加快搜索速度
下列步骤假设本机有 4 块 NVIDIA GPUs,参考 [tensorflow with GPU support](https://www.tensorflow.org/install/gpu)。 演示启用了 4 个并发的 Trial 任务,每个 Trial 任务使用了 1 块 GPU。
**准备配置文件**:NNI 提供了演示用的配置文件,使用 `cat examples/trials/mnist-annotation/config_gpu.yml` 来查看。 trailConcurrency 和 gpuNum 与基本配置文件不同:
...
# 可同时运行的 Trial 数量
trialConcurrency: 4
...
trial:
command: python mnist.py
codeDir: ~/nni/examples/trials/mnist-annotation
gpuNum: 1
用下列命令运行 Experiment:
nnictl create --config ~/nni/examples/trials/mnist-annotation/config_gpu.yml
可以用 *nnictl* 命令行工具或网页界面来跟踪训练过程。 *nvidia_smi* 命令行工具能在训练过程中查看 GPU 使用情况。
\ No newline at end of file
...@@ -25,223 +25,308 @@ nnictl 支持的命令: ...@@ -25,223 +25,308 @@ nnictl 支持的命令:
### 管理 Experiment ### 管理 Experiment
<a name="create"></a> <a name="create"></a>
![](https://placehold.it/15/1589F0/000000?text=+) `nnictl create`
* **nnictl create** * 说明
* 说明 此命令使用参数中的配置文件,来创建新的 Experiment。
此命令使用参数中的配置文件,来创建新的 Experiment。
此命令成功完成后,上下文会被设置为此 Experiment。这意味着如果不显式改变上下文(暂不支持),输入的以下命令,都作用于此 Experiment。
* 用法 此命令成功完成后,上下文会被设置为此 Experiment。这意味着如果不显式改变上下文(暂不支持),输入的以下命令,都作用于此 Experiment。
```bash * 用法
nnictl create [OPTIONS]
```
* 选项 ```bash
nnictl create [OPTIONS]
```
* 选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 | | 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ------------ | ----- | --- | ---------------------- | | ------------ | ----- | --- | ---------------------- |
| --config, -c | True | | Experiment 的 YAML 配置文件 | | --config, -c | True | | Experiment 的 YAML 配置文件 |
| --port, -p | False | | RESTful 服务的端口 | | --port, -p | False | | RESTful 服务的端口 |
| --debug, -d | False | | 设置为调试模式 | | --debug, -d | False | | 设置为调试模式 |
* 样例
> 在默认端口 8080 上创建一个新的 Experiment
注意: ```bash
nnictl create --config nni/examples/trials/mnist/config.yml
```
调试模式会禁用 Trialkeeper 中的版本校验功能。 > 在指定的端口 8088 上创建新的 Experiment
```bash
nnictl create --config nni/examples/trials/mnist/config.yml --port 8088
```
> 在指定的端口 8088 上创建新的 Experiment,并启用调试模式
```bash
nnictl create --config nni/examples/trials/mnist/config.yml --port 8088 --debug
```
注意:
```text
调试模式会禁用 Trialkeeper 中的版本校验功能。
```
<a name="resume"></a> <a name="resume"></a>
* **nnictl resume** ![](https://placehold.it/15/1589F0/000000?text=+) `nnictl resume`
* 说明 * 说明
使用此命令恢复已停止的 Experiment。
* 用法 使用此命令恢复已停止的 Experiment。
```bash * 用法
nnictl resume [OPTIONS]
```
* 选项 ```bash
nnictl resume [OPTIONS]
```
* 选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 | | 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ----------- | ----- | --- | -------------------------------- | | ----------- | ----- | --- | -------------------------------- |
| id | False | | 要恢复的 Experiment 标识 | | id | True | | 要恢复的 Experiment 标识 |
| --port, -p | False | | 要恢复的 Experiment 使用的 RESTful 服务端口 | | --port, -p | False | | 要恢复的 Experiment 使用的 RESTful 服务端口 |
| --debug, -d | False | | 设置为调试模式 | | --debug, -d | False | | 设置为调试模式 |
* 样例
> 在指定的端口 8088 上恢复 Experiment
```bash
nnictl resume [experiment_id] --port 8088
```
<a name="stop"></a> <a name="stop"></a>
![](https://placehold.it/15/1589F0/000000?text=+) `nnictl stop`
* **nnictl stop** * 说明
* 说明 使用此命令来停止正在运行的单个或多个 Experiment。
* 用法
```bash
nnictl stop [id]
```
* 详细信息及样例
1. 如果没有指定 id,并且当前有运行的 Experiment,则会停止该 Experiment,否则会输出错误信息。
使用此命令来停止正在运行的单个或多个 Experiment。 ```bash
nnictl stop
```
* 用法 2. 如果指定了 id,并且此 id 匹配正在运行的 Experiment,nnictl 会停止相应的 Experiment,否则会输出错误信息。
```bash ```bash
nnictl stop [id] nnictl stop [experiment_id]
``` ```
* 详细说明 3. 可使用 'nnictl stop all' 来停止所有的 Experiment。
1. 如果指定了 id,并且此 id 匹配正在运行的 Experiment,nnictl 会停止相应的 Experiment,否则会输出错误信息。 ```bash
2. 如果没有指定 id,并且当前有运行的 Experiment,则会停止该 Experiment,否则会输出错误信息。 nnictl stop all
3. 如果 id 以 * 结尾,nnictl 会停止所有匹配此通配符的 Experiment。 ```
4. 如果 id 不存在,但匹配了某个Experiment 的 id 前缀,nnictl 会停止匹配的Experiment 。
5. 如果 id 不存在,但匹配了多个 Experiment id 的前缀,nnictl 会输出这些 id 的信息。
6. 可使用 'nnictl stop all' 来停止所有的 Experiment。 4. 如果 id 以 * 结尾,nnictl 会停止所有匹配此通配符的 Experiment。
5. 如果 id 不存在,但匹配了某个Experiment 的 id 前缀,nnictl 会停止匹配的Experiment 。
6. 如果 id 不存在,但匹配了多个 Experiment id 的前缀,nnictl 会输出这些 id 的信息。
<a name="update"></a> <a name="update"></a>
* **nnictl update** ![](https://placehold.it/15/1589F0/000000?text=+) `nnictl update`
* **nnictl update searchspace**
* **nnictl update searchspace** * 说明
* 说明
可以用此命令来更新 Experiment 的搜索空间。
* 用法 可以用此命令来更新 Experiment 的搜索空间。
```bash * 用法
nnictl update searchspace [OPTIONS]
```
* 选项 ```bash
nnictl update searchspace [OPTIONS]
```
* 选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 | | 参数及缩写 | 是否必需 | 默认值 | 说明 |
| -------------- | ----- | --- | --------------------- | | -------------- | ----- | --- | --------------------- |
| id | False | | 需要设置的 Experiment 的 id | | id | False | | 需要设置的 Experiment 的 id |
| --filename, -f | True | | 新的搜索空间文件名 | | --filename, -f | True | | 新的搜索空间文件名 |
* **nnictl update concurrency** * 样例
* 说明 `使用 'examples/trials/mnist/search_space.json' 来更新 Experiment 的搜索空间`
可以用此命令来更新 Experiment 的并发设置。
* 用法 ```bash
nnictl update searchspace [experiment_id] --file examples/trials/mnist/search_space.json
```bash ```
nnictl update concurrency [OPTIONS]
``` * **nnictl update concurrency**
* 说明
* 选项 可以用此命令来更新 Experiment 的并发设置。
* 用法
```bash
nnictl update concurrency [OPTIONS]
```
* 选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 | | 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ----------- | ----- | --- | --------------------- | | ----------- | ----- | --- | --------------------- |
| id | False | | 需要设置的 Experiment 的 id | | id | False | | 需要设置的 Experiment 的 id |
| --value, -v | True | | 允许同时运行的 Trial 的数量 | | --value, -v | True | | 允许同时运行的 Trial 的数量 |
* **nnictl update duration** * 样例
* 说明 > 更新 Experiment 的并发数量
可以用此命令来更新 Experiment 的运行时间。
* 用法 ```bash
nnictl update concurrency [experiment_id] --value [concurrency_number]
```bash ```
nnictl update duration [OPTIONS]
``` * **nnictl update duration**
* 说明
* 选项 可以用此命令来更新 Experiment 的运行时间。
* 用法
```bash
nnictl update duration [OPTIONS]
```
* 选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 | | 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ----------- | ----- | --- | ----------------------------------------------------------------------- | | ----------- | ----- | --- | ----------------------------------------------------------------------- |
| id | False | | 需要设置的 Experiment 的 id | | id | False | | 需要设置的 Experiment 的 id |
| --value, -v | True | | Experiment 持续时间如没有单位,则为秒。 后缀可以为 's' 即秒 (默认值), 'm' 即分钟, 'h' 即小时或 'd' 即天。 | | --value, -v | True | | Experiment 持续时间如没有单位,则为秒。 后缀可以为 's' 即秒 (默认值), 'm' 即分钟, 'h' 即小时或 'd' 即天。 |
* **nnictl update trialnum** * 样例
> 修改 Experiment 的执行时间
* 说明 ```bash
nnictl update duration [experiment_id] --value [duration]
可以用此命令来更新 Experiment 的最大 Trial 数量。 ```
* **nnictl update trialnum**
* 说明
* 用法 可以用此命令来更新 Experiment 的最大 Trial 数量。
```bash * 用法
nnictl update trialnum [OPTIONS]
```
* 选项 ```bash
nnictl update trialnum [OPTIONS]
```
* 选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 | | 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ----------- | ----- | --- | --------------------- | | ----------- | ----- | --- | --------------------- |
| id | False | | 需要设置的 Experiment 的 id | | id | False | | 需要设置的 Experiment 的 id |
| --value, -v | True | | 需要设置的 maxtrialnum 的数量 | | --value, -v | True | | 需要设置的 maxtrialnum 的数量 |
* 样例
> 更新 Experiment 的 Trial 数量
```bash
nnictl update trialnum --id [experiment_id] --value [trial_num]
```
<a name="trial"></a> <a name="trial"></a>
![](https://placehold.it/15/1589F0/000000?text=+) `nnictl trial`
* **nnictl trial** * **nnictl trial ls**
* **nnictl trial ls** * 说明
* 说明
使用此命令来查看 Trial 的信息。
* 用法 使用此命令来查看 Trial 的信息。
```bash * 用法
nnictl trial ls
```
* 选项 ```bash
nnictl trial ls
```
* 选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 | | 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ----- | ----- | --- | --------------------- | | ----- | ----- | --- | --------------------- |
| id | False | | 需要设置的 Experiment 的 id | | id | False | | 需要设置的 Experiment 的 id |
* **nnictl trial kill**
* 说明
此命令用于终止 Trial。
* 用法
```bash
nnictl trial kill [OPTIONS]
```
* 选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ---------------- | ----- | --- | --------------------- |
| id | False | | 要终止的 Trial 的 id |
| --experiment, -E | True | | Trial 的 Experiment id |
<a name="top"></a>
* **nnictl top** * **nnictl trial kill**
* 说明 * 说明
查看正在运行的 Experiment 此命令用于终止 Trial
* 用法 * 用法
```bash ```bash
nnictl top nnictl trial kill [OPTIONS]
``` ```
* 选项 * 选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| -------------- | ----- | --- | --------------------- |
| id | False | | Trial 的 Experiment ID |
| --trial_id, -T | True | | 需要终止的 Trial 的 ID。 |
* 样例
> 结束 Trial 任务
```bash
nnictl trial [trial_id] --experiment [experiment_id]
```
<a name="top"></a>
![](https://placehold.it/15/1589F0/000000?text=+) `nnictl top`
* 说明
查看正在运行的 Experiment。
* 用法
```bash
nnictl top
```
* 选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 | | 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ---------- | ----- | --- | ------------------------------------ | | ---------- | ----- | --- | ------------------------------------ |
| id | False | | 需要设置的 Experiment 的 id | | id | False | | 需要设置的 Experiment 的 id |
| --time, -t | False | | 刷新 Experiment 状态的时间间隔,单位为秒,默认值为 3 秒。 | | --time, -t | False | | 刷新 Experiment 状态的时间间隔,单位为秒,默认值为 3 秒。 |
<a name="experiment"></a> <a name="experiment"></a>
![](https://placehold.it/15/1589F0/000000?text=+) `管理 Experiment 的信息`
### 管理 Experiment 信息
* **nnictl experiment show** * **nnictl experiment show**
...@@ -291,23 +376,110 @@ nnictl 支持的命令: ...@@ -291,23 +376,110 @@ nnictl 支持的命令:
nnictl experiment list nnictl experiment list
``` ```
<a name="config"></a> <a name="export"></a>
* **nnictl experiment export**
* 说明
使用此命令,可将 Trial 的 reward 和超参导出为 csv 文件。
* 用法
```bash
nnictl experiment export [OPTIONS]
```
* 选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ------ | ----- | --- | ------------------------- |
| id | False | | Experiment ID |
| --file | True | | 文件的输出路径 |
| --type | True | | 输出文件类型,仅支持 "csv" 和 "json" |
* 样例
> 将 Experiment 中所有 Trial 数据导出为 JSON 格式
```bash
nnictl experiment export [experiment_id] --file [file_path] --type json
```
* **nnictl config show** * **nnictl experiment import**
* 说明 * 说明
显示当前上下文信息 可使用此命令将以前的 Trial 超参和结果导入到 Tuner 中。 数据会传入调参算法中(即 Tuner 或 Advisor)
* 用法 * 用法
```bash ```bash
nnictl config show nnictl experiment import [OPTIONS]
``` ```
* 选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ---------- | ----- | --- | ------------------------ |
| id | False | | 需要将数据导入的 Experiment 的 ID |
| --file, -f | True | | 需要导入的 JSON 格式的数据文件 |
* 详细说明
NNI 支持导入用户的数据,确保数据格式正确。 样例如下:
```json
[
{"parameter": {"x": 0.5, "y": 0.9}, "value": 0.03},
{"parameter": {"x": 0.4, "y": 0.8}, "value": 0.05},
{"parameter": {"x": 0.3, "y": 0.7}, "value": 0.04}
]
```
最顶层列表的每个元素都是一个样例。 对于内置的 Tuner 和 Advisor,每个样本至少需要两个主键:`parameter``value``parameter` 必须与 Experiment 的搜索空间相匹配,`parameter` 中的所有的主键(或超参)都必须与搜索空间中的主键相匹配。 否则, Tuner 或 Advisor 可能会有无法预期的行为。 `Value` 应当遵循与 `nni.report_final_result` 的输入值一样的规则,即要么时一个数字,或者是包含 `default` 主键的 dict。 对于自定义的 Tuner 或 Advisor,根据实现的不同,此文件可以是任意的 JSON 内容(例如,`import_data`)。
也可以用 [nnictl experiment export](#export) 命令导出 Experiment 已经运行过的 Trial 超参和结果。
当前,以下 Tuner 和 Advisor 支持导入数据:
```yml
内置 Tuner: TPE, Anneal, GridSearch, MetisTuner
内置 Advisor: BOHB
```
*如果要将数据导入到 BOHB Advisor,建议像 NNI 一样,增加 "TRIAL_BUDGET" 参数,否则,BOHB 会使用 max_budget 作为 "TRIAL_BUDGET"。 样例如下:*
```json
[
{"parameter": {"x": 0.5, "y": 0.9, "TRIAL_BUDGET": 27}, "value": 0.03}
]
```
* 样例
> 将数据导入运行中的 Experiment
```bash
nnictl experiment [experiment_id] -f experiment_data.json
```
<a name="config"></a>
![](https://placehold.it/15/1589F0/000000?text=+) `nnictl config show`
* 说明
显示当前上下文信息。
* 用法
```bash
nnictl config show
```
<a name="log"></a> <a name="log"></a>
### 管理日志 ![](https://placehold.it/15/1589F0/000000?text=+) `管理日志`
* **nnictl log stdout** * **nnictl log stdout**
...@@ -329,6 +501,14 @@ nnictl 支持的命令: ...@@ -329,6 +501,14 @@ nnictl 支持的命令:
| --head, -h | False | | 显示 stdout 开始的若干行 | | --head, -h | False | | 显示 stdout 开始的若干行 |
| --tail, -t | False | | 显示 stdout 结尾的若干行 | | --tail, -t | False | | 显示 stdout 结尾的若干行 |
| --path, -p | False | | 显示 stdout 文件的路径 | | --path, -p | False | | 显示 stdout 文件的路径 |
* 样例
> 显示 stdout 结尾的若干行
```bash
nnictl log stdout [experiment_id] --tail [lines_number]
```
* **nnictl log stderr** * **nnictl log stderr**
...@@ -365,20 +545,18 @@ nnictl 支持的命令: ...@@ -365,20 +545,18 @@ nnictl 支持的命令:
* 选项 * 选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 | | 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ---------------- | ----- | --- | ----------------------------- | | -------------- | ----- | --- | -------------------------------------- |
| id | False | | 需要显示日志路径的 Trial id | | id | False | | Trial 的 Experiment ID |
| --experiment, -E | False | | 如果 id 为空,则需要添加 Experiment id。 | | --trial_id, -T | False | | 所需要找日志路径的 Trial 的 ID,当 id 为空时,此值也为必需。 |
<a name="webui"></a> <a name="webui"></a>
![](https://placehold.it/15/1589F0/000000?text=+) `管理 Web 界面`
### 管理网页
* **nnictl webui url** * **nnictl webui url**
<a name="tensorboard"></a> <a name="tensorboard"></a>
![](https://placehold.it/15/1589F0/000000?text=+) `管理 TensorBoard`
### 管理 tensorboard
* **nnictl tensorboard start** * **nnictl tensorboard start**
...@@ -394,11 +572,11 @@ nnictl 支持的命令: ...@@ -394,11 +572,11 @@ nnictl 支持的命令:
* 选项 * 选项
| 参数及缩写 | 是否必需 | 默认值 | 说明 | | 参数及缩写 | 是否必需 | 默认值 | 说明 |
| --------- | ----- | ---- | --------------------- | | -------------- | ----- | ---- | --------------------- |
| id | False | | 需要设置的 Experiment 的 id | | id | False | | 需要设置的 Experiment 的 ID |
| --trialid | False | | Trial 的 id | | --trial_id, -T | False | | Trial 的 id |
| --port | False | 6006 | tensorboard 进程的端口 | | --port | False | 6006 | Tensorboard 进程的端口 |
* 详细说明 * 详细说明
...@@ -406,7 +584,7 @@ nnictl 支持的命令: ...@@ -406,7 +584,7 @@ nnictl 支持的命令:
2. 如果要使用 tensorboard,需要将 tensorboard 日志输出到环境变量 [NNI_OUTPUT_DIR] 路径下。 2. 如果要使用 tensorboard,需要将 tensorboard 日志输出到环境变量 [NNI_OUTPUT_DIR] 路径下。
3. 在 local 模式中,nnictl 会直接设置 --logdir=[NNI_OUTPUT_DIR] 并启动 tensorboard 进程。 3. 在 local 模式中,nnictl 会直接设置 --logdir=[NNI_OUTPUT_DIR] 并启动 tensorboard 进程。
4. 在 remote 模式中,nnictl 会创建一个 ssh 客户端来将日志数据从远程计算机复制到本机临时目录中,然后在本机开始 tensorboard 进程。 需要注意的是,nnictl 只在使用此命令时复制日志数据,如果要查看最新的 tensorboard 结果,需要再次执行 nnictl tensorboard 命令。 4. 在 remote 模式中,nnictl 会创建一个 ssh 客户端来将日志数据从远程计算机复制到本机临时目录中,然后在本机开始 tensorboard 进程。 需要注意的是,nnictl 只在使用此命令时复制日志数据,如果要查看最新的 tensorboard 结果,需要再次执行 nnictl tensorboard 命令。
5. 如果只有一个 Trial 任务,不需要设置 trialid。 如果有多个运行的 Trial 作业,需要设置 trialid,或使用 [nnictl tensorboard start --trialid all] 来将 --logdir 映射到所有 Trial 的路径。 5. 如果只有一个 Trial 任务,不需要设置 Trial ID。 如果有多个运行的 Trial 作业,需要设置 Trial ID,或使用 [nnictl tensorboard start --trial_id all] 来将 --logdir 映射到所有 Trial 的路径。
* **nnictl tensorboard stop** * **nnictl tensorboard stop**
...@@ -428,7 +606,7 @@ nnictl 支持的命令: ...@@ -428,7 +606,7 @@ nnictl 支持的命令:
<a name="package"></a> <a name="package"></a>
### 管理安装包 ![](https://placehold.it/15/1589F0/000000?text=+) `管理包`
* **nnictl package install** * **nnictl package install**
...@@ -447,6 +625,14 @@ nnictl 支持的命令: ...@@ -447,6 +625,14 @@ nnictl 支持的命令:
| 参数及缩写 | 是否必需 | 默认值 | 说明 | | 参数及缩写 | 是否必需 | 默认值 | 说明 |
| ------ | ---- | --- | ------- | | ------ | ---- | --- | ------- |
| --name | True | | 要安装的包名称 | | --name | True | | 要安装的包名称 |
* 样例
> 安装 SMAC Tuner 所需要的包
```bash
nnictl package install --name=SMAC
```
* **nnictl package show** * **nnictl package show**
...@@ -462,7 +648,7 @@ nnictl 支持的命令: ...@@ -462,7 +648,7 @@ nnictl 支持的命令:
<a name="version"></a> <a name="version"></a>
### NNI 版本校验 ![](https://placehold.it/15/1589F0/000000?text=+) `检查 NNI 版本`
* **nnictl --version** * **nnictl --version**
......
...@@ -53,7 +53,7 @@ Experiment 的运行过程为:Tuner 接收搜索空间并生成配置。 这 ...@@ -53,7 +53,7 @@ Experiment 的运行过程为:Tuner 接收搜索空间并生成配置。 这
* [如何自定义 Tuner?](Customize_Tuner.md) * [如何自定义 Tuner?](Customize_Tuner.md)
* [NNI 支持哪些 Assessor?](Builtin_Assessors.md) * [NNI 支持哪些 Assessor?](Builtin_Assessors.md)
* [如何自定义 Assessor?](Customize_Assessor.md) * [如何自定义 Assessor?](Customize_Assessor.md)
* [如何在本机上运行 Experiment?](tutorial_1_CR_exp_local_api.md) * [如何在本机上运行 Experiment?](LocalMode.md)
* [如何在多机上运行 Experiment?](RemoteMachineMode.md) * [如何在多机上运行 Experiment?](RemoteMachineMode.md)
* [如何在 OpenPAI 上运行 Experiment?](PAIMode.md) * [如何在 OpenPAI 上运行 Experiment?](PAIMode.md)
* [样例](mnist_examples.md) * [样例](mnist_examples.md)
\ No newline at end of file
...@@ -225,7 +225,7 @@ Experiment 相关信息会显示在界面上,配置和搜索空间等。 可 ...@@ -225,7 +225,7 @@ Experiment 相关信息会显示在界面上,配置和搜索空间等。 可
* [尝试不同的 Assessor](Builtin_Assessors.md) * [尝试不同的 Assessor](Builtin_Assessors.md)
* [使用命令行工具 nnictl](NNICTLDOC.md) * [使用命令行工具 nnictl](NNICTLDOC.md)
* [如何编写 Trial 代码](Trials.md) * [如何编写 Trial 代码](Trials.md)
* [如何在本机运行 Experiment (支持多 GPU 卡)?](tutorial_1_CR_exp_local_api.md) * [如何在本机运行 Experiment (支持多 GPU 卡)?](LocalMode.md)
* [如何在多机上运行 Experiment?](RemoteMachineMode.md) * [如何在多机上运行 Experiment?](RemoteMachineMode.md)
* [如何在 OpenPAI 上运行 Experiment?](PAIMode.md) * [如何在 OpenPAI 上运行 Experiment?](PAIMode.md)
* [如何通过 Kubeflow 在 Kubernetes 上运行 Experiment?](KubeflowMode.md) * [如何通过 Kubeflow 在 Kubernetes 上运行 Experiment?](KubeflowMode.md)
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
### 改进 ### 改进
* [日志目录](https://github.com/Microsoft/nni/blob/v0.5.1/docs/en_US/ExperimentConfig.md)可配置。 * [日志目录](https://github.com/Microsoft/nni/blob/v0.5.1/docs/zh_CN/ExperimentConfig.md)可配置。
* 支持[不同级别的日志](https://github.com/Microsoft/nni/blob/v0.5.1/docs/en_US/ExperimentConfig.md),使其更易于调试。 * 支持[不同级别的日志](https://github.com/Microsoft/nni/blob/v0.5.1/docs/zh_CN/ExperimentConfig.md),使其更易于调试。
### 文档 ### 文档
......
# NNI 中的 BOHB Advisor
## 1. 介绍
BOHB 是由[此篇论文](https://arxiv.org/abs/1807.01774)提出的一种高效而稳定的调参算法。 BO 是贝叶斯优化(Bayesian Optimization)的缩写,HB 是 Hyperband 算法的缩写。
BOHB 依赖 HB(Hyperband)来决定每次跑多少组参数和每组参数分配多少资源(budget),**它的改进之处是将 Hyperband 在每个循环开始时随机选择参数的方法替换成了依赖之前的数据建立模型(贝叶斯优化)进行参数选择**。 一旦贝叶斯优化生成的参数达到迭代所需的配置数, 就会使用这些配置开始执行标准的连续减半过程(successive halving)。 观察这些参数在不同资源配置(budget)下的表现 g(x, b),用于在以后的迭代中用作我们贝叶斯优化模型选择参数的基准数据。
接下来分两部分来介绍 BOHB 过程涉及的原理:
### HB(Hyperband)
按照 Hyperband 的方式来选择每次跑的参数个数与分配多少资源(budget),并继续使用“连续减半(SuccessiveHalving)”策略,更多有关Hyperband算法的细节,请参考[NNI 中的 Hyperband](hyperbandAdvisor.md)[Hyperband 的参考论文](https://arxiv.org/abs/1603.06560)。 下面的伪代码描述了这个过程。
![](../img/bohb_1.png)
### BO(贝叶斯优化)
BOHB 的 BO 与 TPE 非常相似, 它们的主要区别是: BOHB 中使用一个多维的 KDE, 而不是 TPE 那样带有权重的一维 KDEs, 以便更好地处理搜索空间中超参之间的互相影响。
树形超参评估器 (TPE): 使用 KDE (核密度估计) 来对密度进行建模。
![](../img/bohb_2.png)
为了建模有效的核密度估计(KDE),设置了一个建立模型所需的最小观察点数(Nmin),在 Experiment 中它的默认值为 d+1(d是搜索空间的维度),其中 d 也是一个可以设置的超参数。 因为希望尽早地建立模型,所以当 Nb = |Db|,即当已经观察到的计算资源(budget)为 b 的点数满足 q · Nb ≥ Nmin 时,立即建立模型来指导之后参数的选择。所以,在使用了刚开始Nmin + 2 个随机选择的参数之后,会按照下式将观察到的点进行分类
![](../img/bohb_3.png)
按照公式将观察到的点分成好与坏两类点,来分别拟合两个不同的密度分布。
注意,为了鼓励更多的探索防止陷入局部极小,在建立模型之后仍然有**随机比例(random faction)**这样的参数是由随机选择生成的。
## 2. 流程
![](../img/bohb_6.jpg)
以上这张图展示了 BOHB 的工作流程。 将每次训练的最大资源配置(max_budget)设为 9,最小资源配置设为(min_budget)1,逐次减半比例(eta)设为 3,其他的超参数为默认值。 那么在这个例子中,s_max 计算的值为 2, 所以会持续地进行 {s=2, s=1, s=0, s=2, s=1, s=0, ...} 的循环。 在“逐次减半”(SuccessiveHalving)算法的每一个阶段,即图中橙色框,都将选取表现最好的前 1/eta 个参数,并在赋予更多计算资源(budget)的情况下运行。不断重复“逐次减半” (SuccessiveHalving)过程,直到这个循环结束。 同时,收集这些试验的超参数组合,使用了计算资源(budget)和其表现(metrics),使用这些数据来建立一个以使用了多少计算资源(budget)为维度的多维核密度估计(KDE)模型。 这个多维的核密度估计(KDE)模型将用于指导下一个循环的参数选择。
有关如何使用多维的KDE模型来指导参数选择的采样规程,用以下伪代码来描述。
![](../img/bohb_4.png)
## 3. 用法
BOHB advisor 的使用依赖 [ConfigSpace](https://github.com/automl/ConfigSpace) 包,在第一次使用 BOHB 的时候,在命令行运行以下的指令来安装要求的 ConfigSpace 包。
```bash
nnictl package install --name=SMAC
```
要使用 BOHB,需要在 Experiment 的 YAML 配置文件进行如下改动:
```yml
advisor:
builtinAdvisorName: BOHB
classArgs:
optimize_mode: maximize
min_budget: 1
max_budget: 27
eta: 3
min_points_in_model: 7
top_n_percent: 15
num_samples: 64
random_fraction: 0.33
bandwidth_factor: 3.0
min_bandwidth: 0.001
```
**需要的参数**
* **optimize_mode** (*maximize 或 minimize, 可选项, 默认值为 maximize*) - 如果为 'maximize',表示 Tuner 的目标是将指标最大化。 如果为 'minimize',表示 Tuner 的目标是将指标最小化。
* **min_budget** (*整数, 可选项, 默认值为 1*) - 运行一个试验给予的最低计算资源(budget),这里的计算资源通常使用mini-batches 或者 epochs。 该参数必须为正数。
* **max_budget** (*整数, 可选项, 默认值为 3*) - 运行一个试验给予的最大计算资源(budget),这里的计算资源通常使用 mini-batches 或者 epochs。 该参数必须大于“min_budget”。
* **eta** (*整数, 可选项, 默认值为3*) - 在每次迭代中,执行完整的“连续减半”算法。 在这里,当一个使用相同计算资源的子集结束后,选择表现前 1/eta 好的参数,给予更高的优先级,进入下一轮比较(会获得更多计算资源)。 该参数必须大于等于 2。
* **min_points_in_model**(*整数, 可选项, 默认值为None*): 建立核密度估计(KDE)要求的最小观察到的点。 默认值 None 表示 dim+1,当在该计算资源(budget)下试验过的参数已经大于等于`max{dim+1, min_points_in_model}` 时,BOHB 将会开始建立这个计算资源(budget)下对应的核密度估计(KDE)模型,然后用这个模型来指导参数的选取。 该参数必须为正数。(dim 指的是搜索空间中超参数的维度)
* **top_n_percent**(*整数, 可选项, 默认值为15*): 认为观察点为好点的百分数(在 1 到 99 之间,默认值为 15)。 区分表现好的点与坏的点是为了建立树形核密度估计模型。 比如,如果观察到了100个点的表现情况,同时把 top_n_percent 设置为 15,那么表现最好的 15个点将会用于创建表现好的点的分布 "l(x)",剩下的85个点将用于创建表现坏的点的分布 “g(x)”。
* **num_samples** (*整数, 可选项, 默认值为64*): 用于优化 EI 值的采样个数(默认值为64)。 在这个例子中,将根据 l(x) 的分布采样“num_samples”(默认值为64)个点。若优化的目标为最大化指标,则会返回其中 l(x)/g(x) 的值最大的点作为下一个试验的参数。 否则,使用值最小的点。
* **random_fraction**(*浮点数, 可选项, 默认值为0.33*): 使用模型的先验(通常是均匀)来随机采样的比例。
* **bandwidth_factor**(< 1>浮点数, 可选, 默认值为3.0 </em>): 为了鼓励多样性,把优化EI的点加宽,即把KDE中采样的点乘以这个因子,从而增加KDE中的带宽。 如果不熟悉 KDE,建议保留默认值。
* **min_bandwidth**(< 1>float, 可选, 默认值 = 0.001 </em>): 为了保持多样性, 即使所有好的样本对其中一个参数具有相同的值,使用最小带宽 (默认值: 1e-3) 而不是零。 如果不熟悉 KDE,建议保留默认值。
*请注意, 目前 NNI 的浮点类型仅支持十进制表示,必须使用0.333 来代替1/3,0.001来代替1e-3。*
## 4. 文件结构
Advisor 有大量的文件、函数和类。 文件内容的简单介绍:
* `bohb_advisor.py` BOHB类的定义, 包括与dispatcher进行交互的部分,以及控制新试验的生成,计算资源以及试验结果的处理。 基本包含了HB(Hyperband)的实现部分。
* `config_generator.py` 包含了BO(贝叶斯优化)算法的实验部分。 内置函数 *get_config* 使用基于贝叶斯优化生成一个新的参数组合, 内置函数 *new_result* 接受新的结果并使用这些结果来更新贝叶斯优化模型。
## 5. 实验
### BOHB 在 MNIST 数据集上的表现
源码地址: [examples/trials/mnist-advisor](https://github.com/Microsoft/nni/tree/master/examples/trials/)
使用BOHB这个调参算法,在CNN模型上跑MNIST数据集。 下面是实验结果:
![](../img/bohb_5.png)
更多的实验结果可以在 [参考论文](https://arxiv.org/abs/1807.01774)中看到,们可以发现BOHB很好的利用了之前的试验结果,且在开发与探索中得到了一个很好的平衡。
\ No newline at end of file
...@@ -14,4 +14,5 @@ ...@@ -14,4 +14,5 @@
Grid Search<gridsearchTuner> Grid Search<gridsearchTuner>
Hyperband<hyperbandAdvisor> Hyperband<hyperbandAdvisor>
Network Morphism<networkmorphismTuner> Network Morphism<networkmorphismTuner>
Metis Tuner<metisTuner> Metis Tuner<metisTuner>
\ No newline at end of file BOHB<bohbAdvisor>
\ No newline at end of file
...@@ -26,13 +26,13 @@ ...@@ -26,13 +26,13 @@
optimize_mode: maximize optimize_mode: maximize
注意,一旦使用了 Advisor,就不能在配置文件中添加 Tuner 和 Assessor。 使用 Hyperband 时,Trial 代码收到的超参(如键值对)中,除了用户定义的超参,会多一个 `STEPS`**使用 `STEPS`,Trial 能够控制其运行的时间。</p> 注意,一旦使用了 Advisor,就不能在配置文件中添加 Tuner 和 Assessor。 使用 Hyperband 时,Trial 代码收到的超参(如键值对)中,除了用户定义的超参,会多一个 `TRIAL_BUDGET`**使用 `TRIAL_BUDGET`,Trial 能够控制其运行的时间。</p>
对于 Trial 代码中 `report_intermediate_result(metric)``report_final_result(metric)`**`指标` 应该是数值,或者用一个 dict,并保证其中有键值为 default 的项目,其值也为数值型**。 这是需要进行最大化或者最小化优化的数值,如精度或者损失度。 对于 Trial 代码中 `report_intermediate_result(metric)``report_final_result(metric)`**`指标` 应该是数值,或者用一个 dict,并保证其中有键值为 default 的项目,其值也为数值型**。 这是需要进行最大化或者最小化优化的数值,如精度或者损失度。
`R``eta` 是 Hyperband 中可以改动的参数。 `R` 表示可以分配给配置的最大步数(STEPS)。 这里,STEPS 可以代表 epoch 或 批处理数量。 `STEPS` 应该被 Trial 代码用来控制运行的次数。 参考样例 `examples/trials/mnist-hyperband/` ,了解详细信息。 `R``eta` 是 Hyperband 中可以改动的参数。 `R` 表示可以分配给 Trial 的最大资源。 这里,资源可以代表 epoch 或 批处理数量。 `TRIAL_BUDGET` 应该被尝试代码用来控制运行的次数。 参考样例 `examples/trials/mnist-advisor/` ,了解详细信息。
`eta` 表示 `n` 个配置中的 `n/eta` 个配置会留存下来,并用更多的 STEPS 来运行。 `eta` 表示 `n` 个配置中的 `n/eta` 个配置会留存下来,并用更多的资源来运行。
下面是 `R=81``eta=3` 时的样例: 下面是 `R=81``eta=3` 时的样例:
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
| 3 | 3 27 | 1 81 | | | | | 3 | 3 27 | 1 81 | | | |
| 4 | 1 81 | | | | | | 4 | 1 81 | | | | |
`s` 表示分组, `n` 表示生成的配置数量,相应的 `r` 表示配置会运行多少 STEPS`i` 表示轮数,如分组 4 有 5 轮,分组 3 有 4 轮。 `s` 表示分组, `n` 表示生成的配置数量,相应的 `r` 表示配置使用多少资源来运行`i` 表示轮数,如分组 4 有 5 轮,分组 3 有 4 轮。
关于如何实现 Trial 代码,参考 `examples/trials/mnist-hyperband/` 中的说明。 关于如何实现 Trial 代码,参考 `examples/trials/mnist-hyperband/` 中的说明。
......
...@@ -18,4 +18,5 @@ Neural Network Intelligence(NNI)文档 ...@@ -18,4 +18,5 @@ Neural Network Intelligence(NNI)文档
参考<Reference> 参考<Reference>
常见问答<FAQ> 常见问答<FAQ>
贡献<Contribution> 贡献<Contribution>
版本日志<RELEASE> 版本日志<RELEASE>
\ No newline at end of file 博客<Blog/index>
## 创建多阶段 Experiment ## 多阶段 Experiment
通常情况下,每个 Trial 作业只从 Tuner 获得一组配置(超参),然后运行 Experiment。也就是说,通过这组超参来训练模型,并返回结果给 Tuner。 有时候,可能需要在一个 Trial 作业中训练多个模型,并在它们之间共享信息,或者通过创建更少的 Trial 任务来节省资源。例如: 通常,每个 Trial 任务只需要从 Tuner 获取一个配置(超参),然后使用这个配置执行并报告结果,然后退出有时一个 Trial 任务可能需要从 Tuner 请求多次配置。 这是一个非常有用的功能。 例如:
1. 在一个 Trial 作业中依次训练多个模型。这样,后面的模型可以利用先前模型的权重和其它信息,并可以使用不同的超参组合。 1. 在一些训练平台上,需要数十秒来启动一个任务。 如果一个配置只需要一分钟就能完成,那么每个 Trial 任务中只运行一个配置就会非常低效。 这种情况下,可以在同一个 Trial 任务中,完成一个配置后,再请求并完成另一个配置。 极端情况下,一个 Trial 任务可以运行无数个配置。 如果设置了并发(例如设为 6),那么就会有 6 个**长时间**运行的任务来不断尝试不同的配置。
2. 在有限的资源上训练大量的模型,将多个模型放到一个 Trial 作业中训练,能够节约系统创建 Trial 作业的时间。
3. 还有的情况,希望在一个 Trial 任务中训练多个需要不同超参的模型。注意,如果为一个 Trial 作业分配多个 GPU,并且会并发训练模型,需要在代码中正确分配 GPU 资源。
在上述情况中,可利用 NNI 的多阶段 Experiment 来在同一个 Trial 任务中训练具有不同超参的多个模型 2. 有些类型的模型需要进行多阶段的训练,而下一个阶段的配置依赖于前一个阶段的结果。 例如,为了找到模型最好的量化结果,训练过程通常为:自动量化算法(例如 NNI 中的 TunerJ)选择一个位宽(如 16 位), Trial 任务获得此配置,并训练数个 epoch,并返回结果(例如精度)。 算法收到结果后,决定是将 16 位改为 8 位,还是 32 位。 此过程会重复多次
多阶段 Experiment,是指 Trial 作业会从 Tuner 请求多次超参,并多次返回最终结果。 上述情况都可以通过多阶段执行的功能来支持。 为了支持这些情况,一个 Trial 任务需要能从 Tuner 请求多个配置。 Tuner 需要知道两次配置请求是否来自同一个 Trial 任务。 同时,多阶段中的 Trial 任务需要多次返回最终结果。
参考以下步骤来使用多阶段 Experiment: 注意, `nni.get_next_parameter()``nni.report_final_result()` 需要被依次调用:**先调用前者,然后调用后者,并按此顺序重复调用**。 如果 `nni.get_next_parameter()` 被连续多次调用,然后再调用 `nni.report_final_result()`,这会造成最终结果只会与 get_next_parameter 所返回的最后一个配置相关联。 因此,前面的 get_next_parameter 调用都没有关联的结果,这可能会造成一些多阶段算法出问题。
1. 实现 nni.multi_phase.MultiPhaseTuner。 如,[ENAS tuner](https://github.com/countif/enas_nni/blob/master/nni/examples/tuners/enas/nni_controller_ptb.py) 是实现了 nni.multi_phase.MultiPhaseTuner 的 Tuner。 在实现多阶段 Tuner 时,可能要用 generate_parameters 中的 trial_job_id 参数来为每个 Trial 作业生成超参。 ## 创建多阶段的 Experiment
2. 设置 `multiPhase` 的值为 `true`,并将第一步中实现的 Tuner 作为自定义 Tuner 进行配置,例如: ### 编写使用多阶段的 Trial 代码:
```yaml **1. 更新 Trial 代码**
...
multiPhase: true Trial 代码中使用多阶段非常容易,样例如下:
tuner:
codeDir: tuners/enas
classFileName: nni_controller_ptb.py
className: ENASTuner
classArgs:
say_hello: "hello"
...
```
3. 根据需要,在 Trial 代码中可多次调用 nni.get_next_parameter() API,例如:
```python ```python
# ...
for i in range(5): for i in range(5):
# 从 Tuner 中获得参数 # 从 Tuner 中获得参数
tuner_param = nni.get_next_parameter() tuner_param = nni.get_next_parameter()
...@@ -40,4 +29,18 @@ ...@@ -40,4 +29,18 @@
# 为上面获取的参数返回最终结果 # 为上面获取的参数返回最终结果
nni.report_final_result() nni.report_final_result()
# ... # ...
``` # ...
\ No newline at end of file ```
**2. 修改 Experiment 配置**
要启用多阶段,需要在 Experiment 的 YAML 配置文件中增加 `multiPhase: true`。 如果不添加此参数,`nni.get_next_parameter()` 会一直返回同样的配置。 对于所有内置的 Tuner 和 Advisor,不需要修改任何代码,就直接支持多阶段请求配置。
### 编写使用多阶段的 Tuner:
强烈建议首先阅读[自定义 Tuner](https://nni.readthedocs.io/en/latest/Customize_Tuner.html),再开始编写多阶段 Tuner。 与普通 Tuner 不同的是,必须继承于 `MultiPhaseTuner`(在 nni.multi_phase_tuner 中)。 `Tuner``MultiPhaseTuner` 之间最大的不同是,MultiPhaseTuner 多了一些信息,即 `trial_job_id`。 有了这个信息, Tuner 能够知道哪个 Trial 在请求配置信息, 返回的结果是哪个 Trial 的。 通过此信息,Tuner 能够灵活的为不同的 Trial 及其阶段实现功能。 例如,可在 generate_parameters 方法中使用 trial_job_id 来为特定的 Trial 任务生成超参。
当然,要使用自定义的多阶段 Tuner ,也需要**在 Experiment 的 YAML 配置文件中增加`multiPhase: true`**
[ENAS Tuner](https://github.com/countif/enas_nni/blob/master/nni/examples/tuners/enas/nni_controller_ptb.py) 是多阶段 Tuner 的样例。
\ No newline at end of file
...@@ -49,4 +49,7 @@ Assessor(评估器) ...@@ -49,4 +49,7 @@ Assessor(评估器)
Advisor Advisor
------------------------ ------------------------
.. autoclass:: nni.hyperband_advisor.hyperband_advisor.Hyperband .. autoclass:: nni.hyperband_advisor.hyperband_advisor.Hyperband
:members:
.. autoclass:: nni.bohb_advisor.bohb_advisor.BOHB
:members: :members:
\ No newline at end of file
...@@ -2,7 +2,7 @@ NNI 支持的训练平台介绍 ...@@ -2,7 +2,7 @@ NNI 支持的训练平台介绍
===================================== =====================================
.. toctree:: .. toctree::
本机<tutorial_1_CR_exp_local_api> 本机<LocalMode>
远程<RemoteMachineMode> 远程<RemoteMachineMode>
OpenPAI<PAIMode> OpenPAI<PAIMode>
Kubeflow<KubeflowMode> Kubeflow<KubeflowMode>
......
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