Commit 1011377c authored by qianyj's avatar qianyj
Browse files

the source code of NNI for DCU

parent abc22158
../../en_US/NAS/OneshotTrainer.rst
\ No newline at end of file
../../en_US/NAS/Overview.rst
\ No newline at end of file
../../en_US/NAS/Proxylessnas.rst
\ No newline at end of file
.. 2cbe7334076be1841320c31208c338ff
快速入门 Retiarii
==============================
.. contents::
在快速入门教程中,我们以 multi-trial NAS 为例来展示如何构建和探索模型空间。 神经网络架构搜索任务主要有三个关键组件,即:
* 模型搜索空间(Model search space),定义了要探索的模型集合。
* 一个适当的策略(strategy),作为探索这个搜索空间的方法。
* 一个模型评估器(model evaluator),报告一个给定模型的性能。
One-shot NAS 教程在 `这里 <./OneshotTrainer.rst>`__
.. note:: 目前,PyTorch Retiarii 唯一支持的框架,我们只用 **PyTorch 1.7 1.10** 进行了测试。 本文档基于 PyTorch 的背景,但它也应该适用于其他框架,这在我们未来的计划中。
定义模型空间
-----------------------
模型空间是由用户定义的,用来表达用户想要探索、认为包含性能良好模型的一组模型。 模型空间是由用户定义的,用来表达用户想要探索、认为包含性能良好模型的一组模型。 在这个框架中,模型空间由两部分组成:基本模型和基本模型上可能的突变。
定义基本模型
^^^^^^^^^^^^^^^^^
定义基本模型与定义 PyTorch(或 TensorFlow)模型几乎相同, 只有两个小区别。 对于 PyTorch 模块(例如 ``nn.Conv2d``, ``nn.ReLU``),将代码 ``import torch.nn as nn`` 替换为 ``import nni.retiarii.nn.pytorch as nn``
下面是定义基本模型的一个简单的示例,它与定义 PyTorch 模型几乎相同。
.. code-block:: python
import torch
import torch.nn.functional as F
import nni.retiarii.nn.pytorch as nn
from nni.retiarii import model_wrapper
@model_wrapper # this decorator should be put on the out most
class Net(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 32, 3, 1)
self.conv2 = nn.Conv2d(32, 64, 3, 1)
self.dropout1 = nn.Dropout(0.25)
self.dropout2 = nn.Dropout(0.5)
self.fc1 = nn.Linear(9216, 128)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
x = F.relu(self.conv1(x))
x = F.max_pool2d(self.conv2(x), 2)
x = torch.flatten(self.dropout1(x), 1)
x = self.fc2(self.dropout2(F.relu(self.fc1(x))))
output = F.log_softmax(x, dim=1)
return output
.. tip:: 记得使用 ``import nni.retiarii.nn.pytorch as nn`` :meth:`nni.retiarii.model_wrapper`. 许多错误都源于忘记使用它们。同时,对于 ``nn`` 的子模块(例如 ``nn.init``)请使用 ``torch.nn``,比如,``torch.nn.init`` 而不是 ``nn.init``
定义模型突变
^^^^^^^^^^^^^^^^^^^^^^
基本模型只是一个具体模型,而不是模型空间。 我们为用户提供 `API 和原语 <./MutationPrimitives.rst>`__,用于把基本模型变形成包含多个模型的模型空间。
基于上面定义的基本模型,我们可以这样定义一个模型空间:
.. code-block:: diff
import torch
import torch.nn.functional as F
import nni.retiarii.nn.pytorch as nn
from nni.retiarii import model_wrapper
@model_wrapper
class Net(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 32, 3, 1)
- self.conv2 = nn.Conv2d(32, 64, 3, 1)
+ self.conv2 = nn.LayerChoice([
+ nn.Conv2d(32, 64, 3, 1),
+ DepthwiseSeparableConv(32, 64)
+ ])
- self.dropout1 = nn.Dropout(0.25)
+ self.dropout1 = nn.Dropout(nn.ValueChoice([0.25, 0.5, 0.75]))
self.dropout2 = nn.Dropout(0.5)
- self.fc1 = nn.Linear(9216, 128)
- self.fc2 = nn.Linear(128, 10)
+ feature = nn.ValueChoice([64, 128, 256])
+ self.fc1 = nn.Linear(9216, feature)
+ self.fc2 = nn.Linear(feature, 10)
def forward(self, x):
x = F.relu(self.conv1(x))
x = F.max_pool2d(self.conv2(x), 2)
x = torch.flatten(self.dropout1(x), 1)
x = self.fc2(self.dropout2(F.relu(self.fc1(x))))
output = F.log_softmax(x, dim=1)
return output
在这个例子中我们使用了两个突变 API ``nn.LayerChoice`` ``nn.ValueChoice`` ``nn.LayerChoice`` 的输入参数是一个候选模块的列表(在这个例子中是两个),每个采样到的模型会选择其中的一个,然后它就可以像一般的 PyTorch 模块一样被使用。 ``nn.ValueChoice`` 输入一系列候选的值,然后对于每个采样到的模型,其中的一个值会生效。
更多的 API 描述和用法可以请阅读 `这里 <./construct_space.rst>`__
.. note:: 我们正在积极的丰富突变 API,以简化模型空间的构建。如果我们提供的 API 不能满足您表达模型空间的需求,请阅读 `这个文档 <./Mutators.rst>`__ 以获得更多定制突变的资讯。
探索定义的模型空间
-------------------------------
简单来说,探索模型空间有两种方法:(1) 通过独立评估每个采样模型进行搜索;(2) 基于 One-Shot 的权重共享式搜索。 我们在本教程中演示了下面的第一种方法。 第二种方法可以参考 `这里 <./OneshotTrainer.rst>`__
首先,用户需要选择合适的探索策略来探索模型空间。然后,用户需要选择或自定义模型评估器来评估每个采样模型的性能。
选择搜索策略
^^^^^^^^^^^^^^^^^^^^^^^^
Retiarii 支持许多 `探索策略(exploration strategies <./ExplorationStrategies.rst>`__
简单地选择(即实例化)一个探索策略:
.. code-block:: python
import nni.retiarii.strategy as strategy
search_strategy = strategy.Random(dedup=True) # dedup=False 如果不希望有重复数据删除
选择或编写模型评估器
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
NAS 过程中,探索策略反复生成新模型。 模型评估器用于训练和验证每个生成的模型。 生成的模型所获得的性能被收集起来,并送至探索策略以生成更好的模型。
Retiarii 提供了诸多的 `内置模型评估器 <./ModelEvaluators.rst>`__,但是作为第一步,我们还是推荐使用 ``FunctionalEvaluator``,也就是说,将您自己的训练和测试代码用一个函数包起来。这个函数的输入参数是一个模型的类,然后使用 ``nni.report_final_result`` 来汇报模型的效果。
这里的一个例子创建了一个简单的评估器,它在 MNIST 数据集上运行,训练 2 Epoch,并报告其在验证集上的准确率。
.. code-block:: python
def evaluate_model(model_cls):
# "model_cls" 是一个类,需要初始化
model = model_cls()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
transf = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
train_loader = DataLoader(MNIST('data/mnist', download=True, transform=transf), batch_size=64, shuffle=True)
test_loader = DataLoader(MNIST('data/mnist', download=True, train=False, transform=transf), batch_size=64)
device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
for epoch in range(3):
# 训练模型,1 epoch
train_epoch(model, device, train_loader, optimizer, epoch)
# 测试模型,1 epoch
accuracy = test_epoch(model, device, test_loader)
# 汇报中间结果,可以是 float 或者 dict 类型
nni.report_intermediate_result(accuracy)
# 汇报最终结果
nni.report_final_result(accuracy)
# 创建模型评估器
evaluator = nni.retiarii.evaluator.FunctionalEvaluator(evaluate_model)
在这里 ``train_epoch`` ``test_epoch`` 可以是任意自定义的函数,用户可以写自己的训练流程。完整的样例可以参见 :githublink:`examples/nas/multi-trial/mnist/search.py`
我们建议 ``evaluate_model`` 不接受 ``model_cls`` 以外的其他参数。但是,我们在 `高级教程 <./ModelEvaluators.rst>`__ 中展示了其他参数的用法,如果您真的需要的话。另外,我们会在未来支持这些参数的突变(这通常会成为 "超参调优")。
发起 Experiment
--------------------
一切准备就绪,就可以发起 Experiment 以进行模型搜索了。 样例如下:
.. code-block:: python
exp = RetiariiExperiment(base_model, evaluator, [], search_strategy)
exp_config = RetiariiExeConfig('local')
exp_config.experiment_name = 'mnist_search'
exp_config.trial_concurrency = 2
exp_config.max_trial_number = 20
exp_config.training_service.use_active_gpu = False
exp.run(exp_config, 8081)
一个简单 MNIST 示例的完整代码在 :githublink:`这里 <examples/nas/multi-trial/mnist/search.py>` 除了本地训练平台,用户还可以在除了本地机器以外的 `不同的训练平台 <../training_services.rst>`__ 上运行 Retiarii 的实验。
可视化 Experiment
------------------------
用户可以像可视化普通的超参数调优 Experiment 一样可视化他们的 Experiment 例如,在浏览器里打开 ``localhost::8081``8081 是在 ``exp.run`` 里设置的端口。 参考 `这里 <../Tutorial/WebUI.rst>`__ 了解更多细节。
我们支持使用第三方工具(例如 `Netron <https://netron.app/>`__)可视化搜索过程中采样到的模型。您可以点击每个 trial 面板下的 ``Visualization``。注意,目前的可视化是基于导出成 `onnx <https://onnx.ai/>`__ 格式的模型实现的,所以如果模型无法导出成 onnx,那么可视化就无法进行。内置的模型评估器(比如 Classification)已经自动将模型导出成了一个文件。如果您自定义了模型,您需要将模型导出到 ``$NNI_OUTPUT_DIR/model.onnx``
导出最佳模型
-----------------
探索完成后,用户可以使用 ``export_top_models`` 导出最佳模型。
.. code-block:: python
for model_code in exp.export_top_models(formatter='dict'):
print(model_code)
../../en_US/NAS/SPOS.rst
\ No newline at end of file
../../en_US/NAS/Serialization.rst
\ No newline at end of file
../../en_US/NAS/WriteOneshot.rst
\ No newline at end of file
.. bb39a6ac0ae1f5554bc38604c77fb616
#####################
构建模型空间
#####################
NNI为用户提供了强大的API,以方便表达模型空间(或搜索空间)。 首先,用户可以使用 mutation 原语(如 ValueChoice、LayerChoice)在他们的模型中内联一个空间。 其次,NNI为用户提供了简单的接口,可以定制新的 mutators 来表达更复杂的模型空间。 在大多数情况下,mutation 原语足以表达用户的模型空间。
.. toctree::
:maxdepth: 1
mutation 原语 <MutationPrimitives>
定制 mutator <Mutators>
Hypermodule Lib <Hypermodules>
\ No newline at end of file
.. 51734c9945d4eca0f9b5633929d8fadf
Multi-trial NAS
===============
在 multi-trial NAS 中,用户需要模型评估器来评估每个采样模型的性能,并且需要一个探索策略来从定义的模型空间中采样模型。 在这里,用户可以使用 NNI 提供的模型评估器或编写自己的模型评估器。 他们可以简单地选择一种探索策略。 高级用户还可以自定义新的探索策略。 关于如何运行 multi-trial NAS 实验的简单例子,请参考 `快速入门 <./QuickStart.rst>`__。
.. toctree::
:maxdepth: 1
模型评估器 <ModelEvaluators>
探索策略 <ExplorationStrategies>
执行引擎 <ExecutionEngines>
序列化 <Serialization>
.. c9ab8a1f91c587ad72d66b6c43e06528
One-shot NAS
============
One-Shot NAS 算法利用了搜索空间中模型间的权重共享来训练超网络,并使用超网络来指导选择出更好的模型。 与从头训练每个模型(我们称之为 "Multi-trial NAS")算法相比,此类算法大大减少了使用的计算资源。 NNI 支持下列流行的 One-Shot NAS 算法。
.. toctree::
:maxdepth: 1
运行 One-shot NAS <OneshotTrainer>
ENAS <ENAS>
DARTS <DARTS>
SPOS <SPOS>
ProxylessNAS <Proxylessnas>
FBNet <FBNet>
自定义 One-shot NAS <WriteOneshot>
\ No newline at end of file
.. 6e45ee0ddd5d0315e5c946149d4f9c31
概述
========
NNI (Neural Network Intelligence) 是一个工具包,可有效的帮助用户设计并调优机器学习模型的神经网络架构,复杂系统的参数(如超参)等。 NNI 的特性包括:易于使用,可扩展,灵活,高效。
* **易于使用**:NNI 可通过 pip 安装。 只需要在代码中添加几行,就可以利用 NNI 来调优参数。 可使用命令行工具或 Web 界面来查看 Experiment。
* **可扩展**:调优超参或网络结构通常需要大量的计算资源。NNI 在设计时就支持了多种不同的计算资源,如远程服务器组,训练平台(如:OpenPAI,Kubernetes),等等。 根据您配置的培训平台的能力,可以并行运行数百个 Trial 。
* **灵活**:除了内置的算法,NNI 中还可以轻松集成自定义的超参调优算法,神经网络架构搜索算法,提前终止算法等等。 还可以将 NNI 连接到更多的训练平台上,如云中的虚拟机集群,Kubernetes 服务等等。 此外,NNI 还可以连接到外部环境中的特殊应用和模型上。
* **高效**:NNI 在系统及算法级别上不断地进行优化。 例如:通过早期的反馈来加速调优过程。
下图显示了 NNI 的体系结构。
.. raw:: html
<p align="center">
<img src="https://user-images.githubusercontent.com/16907603/92089316-94147200-ee00-11ea-9944-bf3c4544257f.png" alt="drawing" width="700"/>
</p>
主要概念
------------
*
*Experiment(实验)*: 表示一次任务,例如,寻找模型的最佳超参组合,或最好的神经网络架构等。 它由 Trial 和自动机器学习算法所组成。
*
*搜索空间*:是模型调优的范围。 例如,超参的取值范围。
*
*Configuration(配置)*:配置是来自搜索空间的实例,每个超参都会有特定的值。
*
*Trial*:是一次独立的尝试,它会使用某组配置(例如,一组超参值,或者特定的神经网络架构)。 Trial 会基于提供的配置来运行。
*
*Tuner(调优器)*:一种自动机器学习算法,会为下一个 Trial 生成新的配置。 新的 Trial 会使用这组配置来运行。
*
*Assessor(评估器)*:分析 Trial 的中间结果(例如,定期评估数据集上的精度),来确定 Trial 是否应该被提前终止。
*
*训练平台*:是 Trial 的执行环境。 根据 Experiment 的配置,可以是本机,远程服务器组,或其它大规模训练平台(如,OpenPAI,Kubernetes)。
Experiment 的运行过程为:Tuner 接收搜索空间并生成配置。 这些配置将被提交到训练平台,如本机,远程服务器组或训练集群。 执行的性能结果会被返回给 Tuner。 然后,再生成并提交新的配置。
每次 Experiment 执行时,用户只需要定义搜索空间,改动几行代码,就能利用 NNI 内置的 Tuner/Assessor 和训练平台来搜索最好的超参组合以及神经网络结构。 基本上分为三步:
..
步骤一:`定义搜索空间 <Tutorial/SearchSpaceSpec.rst>`__
步骤二:`改动模型代码 <TrialExample/Trials.rst>`__
步骤三:`定义实验配置 <Tutorial/ExperimentConfig.rst>`__
.. raw:: html
<p align="center">
<img src="https://user-images.githubusercontent.com/23273522/51816627-5d13db80-2302-11e9-8f3e-627e260203d5.jpg" alt="drawing"/>
</p>
可查看 `快速入门 <Tutorial/QuickStart.rst>`__ 来调优你的模型或系统。
核心功能
-------------
NNI 提供了并行运行多个实例以查找最佳参数组合的能力。 此功能可用于各种领域,例如,为深度学习模型查找最佳超参数,或查找具有真实数据的数据库和其他复杂系统的最佳配置。
NNI 还希望提供用于机器学习和深度学习的算法工具包,尤其是神经体系结构搜索(NAS)算法,模型压缩算法和特征工程算法。
超参调优
^^^^^^^^^^^^^^^^^^^^^
这是 NNI 最核心、基本的功能,其中提供了许多流行的 `自动调优算法 <Tuner/BuiltinTuner.rst>`__ (即 Tuner) 以及 `提前终止算法 <Assessor/BuiltinAssessor.rst>`__ (即 Assessor)。 可查看 `快速入门 <Tutorial/QuickStart.rst>`__ 来调优你的模型或系统。 基本上通过以上三步,就能开始 NNI Experiment。
通用 NAS 框架
^^^^^^^^^^^^^^^^^^^^^
此 NAS 框架可供用户轻松指定候选的神经体系结构,例如,可以为单个层指定多个候选操作(例如,可分离的 conv、扩张 conv),并指定可能的跳过连接。 NNI 将自动找到最佳候选。 另一方面,NAS 框架为其他类型的用户(如,NAS 算法研究人员)提供了简单的接口,以实现新的 NAS 算法。 NAS 详情及用法参考 `这里 <NAS/Overview.rst>`__。
NNI 通过 Trial SDK 支持多种 one-shot(一次性) NAS 算法,如:ENAS、DARTS。 使用这些算法时,不需启动 NNI Experiment。 在 Trial 代码中加入算法,直接运行即可。 如果要调整算法中的超参数,或运行多个实例,可以使用 Tuner 并启动 NNI Experiment。
除了 one-shot NAS 外,NAS 还能以 NNI 模式运行,其中每个候选的网络结构都作为独立 Trial 任务运行。 在此模式下,与超参调优类似,必须启动 NNI Experiment 并为 NAS 选择 Tuner。
模型压缩
^^^^^^^^^^^^^^^^^
NNI 提供了一个易于使用的模型压缩框架来压缩深度神经网络,压缩后的网络通常具有更小的模型尺寸和更快的推理速度,
模型性能也不会有明显的下降。 NNI 上的模型压缩包括剪枝和量化算法。 这些算法通过 NNI Trial SDK 提供
。 可以直接在 Trial 代码中使用,并在不启动 NNI Experiment 的情况下运行 Trial 代码。 用户还可以使用 NNI 模型压缩框架集成自定义的剪枝和量化算法。
模型压缩的详细说明和算法可在 `这里 <Compression/Overview.rst>`__ 找到。
自动特征工程
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
自动特征工程,可以为下游任务找到最有效的特征。 自动特征工程及其用法的详细说明可在 `这里 <FeatureEngineering/Overview.rst>`__ 找到。 通过 NNI Trial SDK 支持,不必创建 NNI Experiment, 只需在 Trial 代码中加入内置的自动特征工程算法,然后直接运行 Trial 代码。
自动特征工程算法通常有一些超参。 如果要自动调整这些超参,可以利用 NNI 的超参数调优,即选择调优算法(即 Tuner)并启动 NNI Experiment。
了解更多信息
--------------------
* `入门 <Tutorial/QuickStart.rst>`__
* `如何为 NNI 调整代码? <TrialExample/Trials.rst>`__
* `NNI 支持哪些 Tuner? <Tuner/BuiltinTuner.rst>`__
* `如何自定义 Tuner? <Tuner/CustomizeTuner.rst>`__
* `NNI 支持哪些 Assessor? <Assessor/BuiltinAssessor.rst>`__
* `如何自定义 Assessor? <Assessor/CustomizeAssessor.rst>`__
* `如何在本机上运行 Experiment? <TrainingService/LocalMode.rst>`__
* `如何在多机上运行 Experiment? <TrainingService/RemoteMachineMode.rst>`__
* `如何在 OpenPAI 上运行 Experiment? <TrainingService/PaiMode.rst>`__
* `示例 <TrialExample/MnistExamples.rst>`__
* `NNI 上的神经网络架构搜索 <NAS/Overview.rst>`__
* `NNI 上的自动模型压缩 <Compression/Overview.rst>`__
* `NNI 上的自动特征工程 <FeatureEngineering/Overview.rst>`__
../en_US/Release.rst
\ No newline at end of file
../en_US/Release_v1.0.md
\ No newline at end of file
../en_US/ResearchPublications.rst
\ No newline at end of file
../en_US/SupportedFramework_Library.rst
\ No newline at end of file
../../en_US/TrainingService/AMLMode.rst
\ No newline at end of file
../../en_US/TrainingService/AdaptDLMode.rst
\ No newline at end of file
../../en_US/TrainingService/DLCMode.rst
\ No newline at end of file
../../en_US/TrainingService/DLTSMode.rst
\ No newline at end of file
../../en_US/TrainingService/FrameworkControllerMode.rst
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment