Unverified Commit 91d9a797 authored by Yuge Zhang's avatar Yuge Zhang Committed by GitHub
Browse files

Adopt symbolic links in Chinese documentation (#4345)


Co-authored-by: default avatarjiahangxu <jiahangxu@microsoft.com>
parent 0e0ee86d
../../en_US/TrainingService/RemoteMachineMode.rst
\ No newline at end of file
CIFAR-10 示例
=================
概述
--------
`CIFAR-10 <https://www.cs.toronto.edu/~kriz/cifar.html>`__ 分类是机器学习中常用的基准问题。 CIFAR-10 数据集是图像的集合。 它也是机器学习领域最常用的数据集之一,包含 60000 万张 32x32 的图像,共有 10 个分类。 因此以 CIFAR-10 分类为例来介绍 NNI 的用法。
**目标**
^^^^^^^^^^^^^
总所周知,模型 optimizer (优化器)的选择直接影响了最终指标的性能。 本教程的目标是 **调优出性能更好的优化器**,从而为图像识别训练出一个相对较小的卷积网络(CNN)。
本例中,选择了以下常见的深度学习优化器:
.. code-block:: bash
"SGD", "Adadelta", "Adagrad", "Adam", "Adamax"
实验
^^^^^^^^^^^^^^^^^^^^
准备
^^^^^^^^^^^^
此示例需要安装 PyTorch。 PyTorch 安装包需要选择所基于的 Python 和 CUDA 版本。
这是环境 python==3.5 且 cuda == 8.0 的样例,然后用下列命令来安装 `PyTorch <https://pytorch.org/>`__\ :
.. code-block:: bash
python3 -m pip install http://download.pytorch.org/whl/cu80/torch-0.4.1-cp35-cp35m-linux_x86_64.whl
python3 -m pip install torchvision
NNI 与 CIFAR-10
^^^^^^^^^^^^^^^^^
**搜索空间**
正如本文目标,要为 CIFAR-10 找到最好的 ``优化器``。 使用不同的优化器时,还要相应的调整 ``学习率`` 和 ``网络架构``。 因此,选择这三个参数作为超参,并创建如下的搜索空间。
.. code-block:: json
{
"lr":{"_type":"choice", "_value":[0.1, 0.01, 0.001, 0.0001]},
"optimizer":{"_type":"choice", "_value":["SGD", "Adadelta", "Adagrad", "Adam", "Adamax"]},
"model":{"_type":"choice", "_value":["vgg", "resnet18", "googlenet", "densenet121", "mobilenet", "dpn92", "senet18"]}
}
代码示例: :githublink:`search_space.json <examples/trials/cifar10_pytorch/search_space.json>`
**Trial**
这是超参集合的训练代码,关注以下几点:
* 使用 ``nni.get_next_parameter()`` 来获取下一组训练的超参组合。
* 使用 ``nni.report_intermediate_result(acc)`` 在每个 epoch 结束时返回中间结果。
* 使用 ``nni.report_final_result(acc)`` 在每个 Trial 结束时返回最终结果。
代码示例: :githublink:`main.py <examples/trials/cifar10_pytorch/main.py>`
还可直接修改现有的代码来支持 Nni,参考:`如何实现 Trial <Trials.rst>`__。
**配置**
这是在本机运行 Experiment 的示例(多GPU):
代码 :githublink:`examples/trials/cifar10_pytorch/config.yml <examples/trials/cifar10_pytorch/config.yml>`
这是在 OpenPAI 上运行 Experiment 的示例:
代码: :githublink:`examples/trials/cifar10_pytorch/config_pai.yml <examples/trials/cifar10_pytorch/config_pai.yml>`
完整示例: :githublink:`examples/trials/cifar10_pytorch/ <examples/trials/cifar10_pytorch>`
运行 Experiment
^^^^^^^^^^^^^^^^^^^^^
以上即为 Experiment 的代码介绍,**从命令行运行 config.yml 文件来开始 Experiment**。
.. code-block:: bash
nnictl create --config nni/examples/trials/cifar10_pytorch/config.yml
../../en_US/TrialExample/Cifar10Examples.rst
\ No newline at end of file
EfficientNet
============
`EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks <https://arxiv.org/abs/1905.11946>`__
如论文中 3.3 所述,使用遍历搜索来找到 EfficientNet-B1 的 alpha, beta 和 gamma 的最好组合。 搜索空间,Tuner,配置示例如下。
说明
------------
:githublink:`示例代码 <examples/trials/efficientnet>`
#. 将示例代码目录设为当前工作目录。
#. 运行 ``git clone https://github.com/ultmaster/EfficientNet-PyTorch`` 来克隆 `ultmaster 修改过的版本 <https://github.com/ultmaster/EfficientNet-PyTorch>`__ 。 修改尽可能接近原始的 `Tensorflow 版本 <https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet>`__ (包括 EMA,标记平滑度等等。);另外添加了代码从 Tuner 获取参数并回调中间和最终结果。 将其 clone 至 ``EfficientNet-PyTorch``;``main.py``,``train_imagenet.sh`` 等文件会在配置文件中指定的路径。
#. 运行 ``nnictl create --config config_local.yml``(OpenPAI 可使用 ``config_pai.yml``)来找到最好的 EfficientNet-B1。 根据环境来调整训练平台(OpenPAI、本机、远程),batch size。
在 ImageNet 上的训练,可阅读 ``EfficientNet-PyTorch/train_imagenet.sh``。 下载 ImageNet,并参考 `PyTorch 格式 <https://pytorch.org/docs/stable/torchvision/datasets.html#imagenet>`__ 来解压,然后将 ``/mnt/data/imagenet`` 替换为 ImageNet 的路径。 此文件也是如何将 ImageNet 挂载到 OpenPAI 容器的示例。
结果
-------
下图展示了 acc@1 和 alpha、beta、gamma 之间的关系。
.. image:: ../../img/efficientnet_search_result.png
:target: ../../img/efficientnet_search_result.png
:alt:
../../en_US/TrialExample/EfficientNet.rst
\ No newline at end of file
GBDT
===========
梯度提升是机器学习中回归和分类问题的一种方法。它由一组弱分类模型所组成,决策树是其中的典型。 像其它提升方法一样,它也分步来构建模型,并使用可微分的损失函数来优化。
梯度决策树(gradient boosting decision tree,GBDT)有很多流行的实现,如:`lightgbm <https://github.com/Microsoft/LightGBM>`__\ , `xgboost <https://github.com/dmlc/xgboost>`__\ , and `catboost <https://github.com/catboost/catboost>`__,等等。 GBDT 是解决经典机器学习问题的重要工具。 GBDT 也是一种鲁棒的算法,可以使用在很多领域。 GBDT 的超参越好,就能获得越好的性能。
NNI 是用来调优超参的平台,可以在 NNI 中尝试各种内置的搜索算法,并行运行多个 Trial。
1. GBDT 的搜索空间
-----------------------
GBDT 有很多超参,但哪些才会影响性能或计算速度呢? 基于实践经验,建议如下(以 lightgbm 为例):
..
* 获得更好的精度
* ``learning_rate``. ``学习率`` 的范围应该是 [0.001, 0.9]。
*
``num_leaves``. ``num_leaves`` 与 ``max_depth`` 有关,不必两个值同时调整。
*
``bagging_freq``. ``bagging_freq`` 可以是 [1, 2, 4, 8, 10]。
*
``num_iterations``. 如果达到期望的拟合精度,可以调整得大一些。
..
* 加速
* ``bagging_fraction``. ``bagging_fraction`` 的范围应该是 [0.7, 1.0]。
*
``feature_fraction``. ``feature_fraction`` 的范围应该是 [0.6, 1.0]。
*
``max_bin``.
..
* 避免过拟合
* ``min_data_in_leaf``. 取决于数据集。
*
``min_sum_hessian_in_leaf``. 取决于数据集。
*
``lambda_l1`` 和 ``lambda_l2``.
*
``min_gain_to_split``.
*
``num_leaves``.
参考链接:
`lightgbm <https://lightgbm.readthedocs.io/en/latest/Parameters-Tuning.html>`__ 和 `autoxgoboost <https://github.com/ja-thomas/autoxgboost/blob/master/poster_2018.pdf>`__
2. 任务描述
-------------------
"auto-gbdt" 基于 LightGBM 和 NNI。 数据集有 :githublink:`训练数据 <examples/trials/auto-gbdt/data/regression.train>` and :githublink:`测试数据 <examples/trials/auto-gbdt/data/regression.train>`。
根据数据中的特征和标签,训练一个 GBDT 回归模型,用来做预测。
3. 如何在 NNI 中运行
--------------------
3.1 安装所有要求的包
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: bash
pip install lightgbm
pip install pandas
3.2 准备 Trial 代码
^^^^^^^^^^^^^^^^^^^^^^^^^^^
基础代码如下:
.. code-block:: python
...
def get_default_parameters():
...
return params
def load_data(train_path='./data/regression.train', test_path='./data/regression.test'):
'''
准备数据集
'''
...
return lgb_train, lgb_eval, X_test, y_test
def run(lgb_train, lgb_eval, params, X_test, y_test):
# 训练
gbm = lgb.train(params,
lgb_train,
num_boost_round=20,
valid_sets=lgb_eval,
early_stopping_rounds=5)
# 预测
y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration)
# 评估
rmse = mean_squared_error(y_test, y_pred) ** 0.5
print('The rmse of prediction is:', rmse)
if __name__ == '__main__':
lgb_train, lgb_eval, X_test, y_test = load_data()
PARAMS = get_default_parameters()
# 训练
run(lgb_train, lgb_eval, PARAMS, X_test, y_test)
3.3 准备搜索空间
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
如果要调优 ``num_leaves``\ , ``learning_rate``\ , ``bagging_fraction`` 和 ``bagging_freq``,可创建一个 :githublink:`search_space.json <examples/trials/auto-gbdt/search_space.json>` 文件:
.. code-block:: json
{
"num_leaves":{"_type":"choice","_value":[31, 28, 24, 20]},
"learning_rate":{"_type":"choice","_value":[0.01, 0.05, 0.1, 0.2]},
"bagging_fraction":{"_type":"uniform","_value":[0.7, 1.0]},
"bagging_freq":{"_type":"choice","_value":[1, 2, 4, 8, 10]}
}
参考 `这里 <../Tutorial/SearchSpaceSpec.rst>`__,了解更多变量类型。
3.4 在代码中使用 NNI SDK
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: diff
+import nni
...
def get_default_parameters():
...
return params
def load_data(train_path='./data/regression.train', test_path='./data/regression.test'):
'''
准备数据集
'''
...
return lgb_train, lgb_eval, X_test, y_test
def run(lgb_train, lgb_eval, params, X_test, y_test):
# 训练
gbm = lgb.train(params,
lgb_train,
num_boost_round=20,
valid_sets=lgb_eval,
early_stopping_rounds=5)
# 预测
y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration)
# 评估
rmse = mean_squared_error(y_test, y_pred) ** 0.5
print('The rmse of prediction is:', rmse)
+ nni.report_final_result(rmse)
if __name__ == '__main__':
lgb_train, lgb_eval, X_test, y_test = load_data()
+ RECEIVED_PARAMS = nni.get_next_parameter()
PARAMS = get_default_parameters()
+ PARAMS.update(RECEIVED_PARAMS)
# 训练
run(lgb_train, lgb_eval, PARAMS, X_test, y_test)
3.5 实现配置文件并运行
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
在配置文件中,可以设置如下内容:
* Experiment 设置: ``trialConcurrency``\ , ``maxExecDuration``\ , ``maxTrialNum``\ , ``trial gpuNum``\ 等。
* 平台设置: ``trainingServicePlatform``\ 等。
* 路径设置: ``searchSpacePath``\ , ``trial codeDir``\ 等。
* 算法设置:选择 ``Tuner`` 算法,``优化方向``,等等。
config.yml 示例:
.. code-block:: yaml
authorName: default
experimentName: example_auto-gbdt
trialConcurrency: 1
maxExecDuration: 10h
maxTrialNum: 10
# 选择平台: local, remote, pai
trainingServicePlatform: local
searchSpacePath: search_space.json
# 选择:true, false
useAnnotation: false
tuner:
# 选择:TPE, Random, Anneal, Evolution, BatchTuner
# SMAC (SMAC 应该通过 nnictl 安装)
builtinTunerName: TPE
classArgs:
# 选择:maximize, minimize
optimize_mode: minimize
trial:
command: python3 main.py
codeDir: .
gpuNum: 0
使用下面的命令启动 Experiment:
.. code-block:: bash
nnictl create --config ./config.yml
../../en_US/TrialExample/GbdtExample.rst
\ No newline at end of file
NNI 上的知识蒸馏
=============================
知识蒸馏 (Knowledge Distillation)
---------------------------------------
在 `Distilling the Knowledge in a Neural Network <https://arxiv.org/abs/1503.02531>`__\ 中提出了知识蒸馏(KD)的概念, 压缩后的模型被训练去模仿预训练的、较大的模型。这种训练设置也称为"师生(teacher-student)"方式,其中大模型是教师,小模型是学生。KD 通常用于微调剪枝后的模型。
.. image:: ../../img/distill.png
:target: ../../img/distill.png
:alt:
用法
^^^^^
PyTorch 代码
.. code-block:: python
for batch_idx, (data, target) in enumerate(train_loader):
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
y_s = model_s(data)
y_t = model_t(data)
loss_cri = F.cross_entropy(y_s, target)
# kd 损失值
p_s = F.log_softmax(y_s/kd_T, dim=1)
p_t = F.softmax(y_t/kd_T, dim=1)
loss_kd = F.kl_div(p_s, p_t, size_average=False) * (self.T**2) / y_s.shape[0]
# 总损失
loss = loss_cir + loss_kd
loss.backward()
微调剪枝模型的完整代码在 :githublink:`这里 <examples/model_compress/pruning/finetune_kd_torch.py>`
.. code-block:: python
python finetune_kd_torch.py --model [model name] --teacher-model-dir [pretrained checkpoint path] --student-model-dir [pruned checkpoint path] --mask-path [mask file path]
请注意:要微调剪枝后的模型,请先运行 :githublink:`basic_pruners_torch.py <examples/model_compress/pruning/basic_pruners_torch.py>` 来获取掩码文件,然后将掩码路径作为参数传递给脚本。
../../en_US/TrialExample/KDExample.rst
\ No newline at end of file
.. role:: raw-html(raw)
:format: html
MNIST 示例
==============
在深度学习中,用 CNN 来分类 MNIST 数据,就像介绍编程语言中的 ``hello world`` 示例。 因此,NNI 将 MNIST 作为示例来介绍功能。 示例如下:
* `MNIST 中使用 NNI API (PyTorch) <#mnist-pytorch>`__
* `MNIST 中使用 NNI API (TensorFlow v2.x) <#mnist-tfv2>`__
* `MNIST 中使用 NNI API (TensorFlow v1.x) <#mnist-tfv1>`__
* `MNIST 中使用 NNI 标记(annotation) <#mnist-annotation>`__
* `在 keras 中使用 MNIST <#mnist-keras>`__
* `MNIST -- 用批处理 tuner 来调优 <#mnist-batch>`__
* `MNIST -- 用 hyperband 来调优 <#mnist-hyperband>`__
* `MNIST -- 用嵌套搜索空间来调优 <#mnist-nested>`__
* `用 Kubeflow 运行分布式的 MNIST(TensorFlow) <#mnist-kubeflow-tf>`__
* `用 Kubeflow 运行分布式的 MNIST(PyTorch) <#mnist-kubeflow-pytorch>`__
:raw-html:`<a name="mnist-pytorch"></a>`
**MNIST 中使用 NNI API (PyTorch)**
这是个简单的卷积网络,有两个卷积层,两个池化层和一个全连接层。
调优的超参包括 dropout 比率,卷积层大小,隐藏层(全连接层)大小等等。
它能用 NNI 中大部分内置的 Tuner 来调优,如 TPE,SMAC,Random。
示例的 YAML 文件也启用了评估器来提前终止一些中间结果不好的尝试。
代码示例: :githublink:`mnist-pytorch/ <examples/trials/mnist-pytorch/>`
:raw-html:`<a name="mnist-tfv2"></a>`
**MNIST 中使用 NNI API (TensorFlow v2.x)**
与上述示例的网络相同,但使用了 TensorFlow。
代码示例: :githublink:`mnist-tfv2/ <examples/trials/mnist-tfv2/>`
:raw-html:`<a name="mnist-tfv1"></a>`
**MNIST 中使用 NNI API (TensorFlow v1.x)**
与上述示例的网络相同,但使用了 TensorFlow v1.x Keras API。
代码示例: :githublink:`mnist-tfv1/ <examples/trials/mnist-tfv1/>`
:raw-html:`<a name="mnist-annotation"></a>`
**MNIST 中使用 NNI 标记(annotation)**
此样例与上例类似,上例使用的是 NNI API 来指定搜索空间并返回结果,而此例使用的是 NNI 标记。
代码示例: :githublink:`mnist-annotation/ <examples/trials/mnist-annotation/>`
:raw-html:`<a name="mnist-batch"></a>`
**MNIST -- 用批处理 Tuner 来调优**
此样例演示了如何使用批处理 Tuner。 只需要在搜索空间文件中列出所有要尝试的配置, NNI 会逐个尝试。
代码示例: :githublink:`mnist-batch-tune-keras/ <examples/trials/mnist-batch-tune-keras/>`
:raw-html:`<a name="mnist-hyperband"></a>`
**MNIST -- 用 hyperband 调优**
此样例演示了如何使用 hyperband 来调优模型。 在尝试收到的配置中,有个主键叫做 ``STEPS``,尝试要用它来控制运行多长时间(例如,控制迭代的次数)。
.. cannot find :githublink:`mnist-hyperband/ <examples/trials/mnist-hyperband/>`
代码示例: :githublink:`mnist-hyperband/ <examples/trials/mnist-hyperband/>`
:raw-html:`<a name="mnist-nested"></a>`
**MNIST -- 用嵌套搜索空间调优**
此样例演示了 NNI 如何支持嵌套的搜索空间。 搜索空间文件示了如何定义嵌套的搜索空间。
代码示例: :githublink:`mnist-distributed/ <examples/trials/mnist-distributed/>`
:raw-html:`<a name="mnist-kubeflow-tf"></a>`
**用 Kubeflow 运行分布式的 MNIST (tensorflow)**
此样例展示了如何通过 NNI 来在 Kubeflow 上运行分布式训练。 只需要简单的提供分布式训练代码,并在配置文件中指定 kubeflow 模式。 例如,运行 ps 和 worker 的命令行,以及各自需要的资源。 此样例使用了 Tensorflow 来实现,因而,需要使用 Kubeflow 的 tf-operator。
代码示例: :githublink:`mnist-distributed-pytorch/ <examples/trials/mnist-distributed-pytorch/>`
:raw-html:`<a name="mnist-kubeflow-pytorch"></a>`
**用 Kubeflow 运行分布式的 MNIST (PyTorch)**
与前面的样例类似,不同之处是此样例是 Pytorch 实现的,因而需要使用 Kubeflow 的 pytorch-operator。
代码示例: :githublink:`mnist-distributed-pytorch/ <examples/trials/mnist-distributed-pytorch/>`
../../en_US/TrialExample/MnistExamples.rst
\ No newline at end of file
.. role:: raw-html(raw)
:format: html
NNI 上调优张量算子
==============================
概述
--------
深度神经网络(DNN)的大量应用,催生了对从云服务器到嵌入式设备等不同硬件平台上的训练和推理的需求。 此外,还有深度神经网络上的计算图优化问题,如张量算子融合会引入新的张量算子。 然而,人工通过特定硬件库来优化张量算子,不能很好的支持新硬件平台和新算子,存在一定的局限性。因此,在大规模部署和深度学习技术的实际场景中,不同平台上的自动化的张量算子优化变得非常重要。
张量算子优化的本质,是一个组合优化问题。 目标函数是张量算子在某个硬件平台上的性能,通过调整超参(如,如何切片矩阵,展开循环)实现该平台上的最佳性能。 与许多典型的此类问题(如旅行推销员问题)不同,张量算子优化的目标函数是黑盒,采样成本较高。 必须用特定的配置编译设备代码,并在真实的硬件上运行,以获得相应的性能指标。 因此,理想的张量算子优化方法应该在尽可能少的样本下找到最佳的配置。
代价昂贵的目标函数使得用传统的组合优化方法,如模拟退火和进化算法求解张量算子优化问题几乎不可能。 尽管这些算法本质上支持组合搜索空间,但它们并未考虑采样效率,
因此通常需要成千上万甚至更多的样本,这在生产环境中调整张量算子时是不可接受的。 另一方面,事实证明,基于序列模型的优化(SMBO)方法可有效地优化具有连续搜索空间的黑盒函数。 然而,在使用组合搜索空间进行优化时,SMBO 方法的采样效率不及连续搜索方法,这是因为缺少关于目标函数的先验假设,例如连续搜索空间的连续性和可微性。 例如,如果可以假设具有连续搜索空间的目标函数是无限可微的,则可以使用具有径向基函数(RBF)核的高斯过程对目标函数进行建模。 这样,一个样本不仅提供了一个点上的单一值,而且还提供了目标函数在其邻域上的局部性质,甚至是全局性质,
从而获得了较高的采样效率。 相比之下,用于组合优化的SMBO方法由于缺乏适当的先验假设和可以利用它们的替代模型而导致采样效率低下。
最近提出的 OpEvo 就是为了解决这个具有挑战性的问题。 它通过引入基于 q-随机游走分布的拓扑感知突变操作来利用搜索空间上的拓扑结构,有效地探索了张量算子的搜索空间。 在本例中,可以使用OpEvo调优从两个流行的神经网络(BERT和AlexNet)中选择的三种代表性张量算子。 还提供了三个比较基线:AutoTVM,G-BFS和N-A2C。 请参考 `OpEvo: An Evolutionary Method for Tensor Operator Optimization <https://arxiv.org/abs/2006.05664>`__ 获取算法的更多细节。
配置环境
-----------------
此示例准备了 Dockerfile 作为 Experiment 的环境。 开始前,确保 Docker 守护进程已启动,GPU 加速驱动已正确安装。 进入示例目录 ``examples/trials/systems/opevo`` 并运行下列命令,从 Dockerfile 构建并实例化 Docker 映像。
.. code-block:: bash
# 如果使用 NVIDIA GPU
make cuda-env
# 如果使用 AMD GPU
make rocm-env
运行 Experiment
----------------
这里从 BERT 和 AlexNet 中选择了三种有代表性的张量算子:**矩阵乘法**、**批处理的矩阵乘法**,以及 **二维卷积**,并使用 NNI 进行调优。 所有张量算子的 ``Trial`` 代码都是 ``/root/compiler_auto_tune_stable.py``,每个调优算法的 ``搜索空间`` 和 ``配置`` 文件都在按张量算子分类的 ``/root/experiments/`` 目录中。 这里的 ``/root`` 表示容器中的 root 目录。
在 ``/root`` 中运行以下命令来调优矩阵乘法:
.. code-block:: bash
# (N, K) x (K, M) 表示形状为 (N, K) 的矩阵乘以形状为 (K, M) 的矩阵
# (512, 1024) x (1024, 1024)
# 用 OpEvo 调优
nnictl create --config experiments/mm/N512K1024M1024/config_opevo.yml
# 用 G-BFS 调优
nnictl create --config experiments/mm/N512K1024M1024/config_gbfs.yml
# 用 N-A2C 调优
nnictl create --config experiments/mm/N512K1024M1024/config_na2c.yml
# 用 AutoTVM 调优
OP=matmul STEP=512 N=512 M=1024 K=1024 P=NN ./run.s
# (512, 1024) x (1024, 4096)
# 用 OpEvo 调优
nnictl create --config experiments/mm/N512K1024M4096/config_opevo.yml
# 用 G-BFS 调优
nnictl create --config experiments/mm/N512K1024M4096/config_gbfs.yml
# 用 N-A2C 调优
nnictl create --config experiments/mm/N512K1024M4096/config_na2c.yml
# 用 AutoTVM 调优
OP=matmul STEP=512 N=512 M=1024 K=4096 P=NN ./run.sh
# (512, 4096) x (4096, 1024)
# 用 OpEvo 调优
nnictl create --config experiments/mm/N512K4096M1024/config_opevo.yml
# 用 G-BFS 调优
nnictl create --config experiments/mm/N512K4096M1024/config_gbfs.yml
# 用 N-A2C 调优
nnictl create --config experiments/mm/N512K4096M1024/config_na2c.yml
# 用 AutoTVM 调优
OP=matmul STEP=512 N=512 M=4096 K=1024 P=NN ./run.sh
在 ``/root`` 中运行以下命令来调优矩阵乘法:
.. code-block:: bash
# 批处理大小为 960,形状为 (128, 128) 的矩阵,乘以批处理大小为 960,形状为 (128, 64) 的矩阵
# 用 OpEvo 调优
nnictl create --config experiments/bmm/B960N128K128M64PNN/config_opevo.yml
# 用 AutoTVM 调优
OP=batch_matmul STEP=512 B=960 N=128 K=128 M=64 P=NN ./run.sh
# 批处理大小为 960,形状为 (128, 128) 的矩阵,先转置,然后乘以批处理大小为 960,形状为 (128, 64)
# 用 OpEvo 调优
nnictl create --config experiments/bmm/B960N128K128M64PTN/config_opevo.yml
# 用 AutoTVM 调优
OP=batch_matmul STEP=512 B=960 N=128 K=128 M=64 P=TN ./run.sh
# 批处理大小为 960,形状为 (128, 128) 的矩阵,先转置,然后右乘批处理大小为 960,形状为 (128, 64)
# 用 OpEvo 调优
nnictl create --config experiments/bmm/B960N128K64M128PNT/config_opevo.yml
# 用 AutoTVM 调优
OP=batch_matmul STEP=512 B=960 N=128 K=64 M=128 P=NT ./run.sh
在 ``/root`` 中运行以下命令来调优二维卷积:
.. code-block:: bash
# 形状为(512,3,227,227)的图像张量与形状为(64,3,11,11)的内核张量以步幅 4 和填充 0 卷积
# 用 OpEvo 调优
nnictl create --config experiments/conv/N512C3HW227F64K11ST4PD0/config_opevo.yml
# 用 AutoTVM 调优
OP=convfwd_direct STEP=512 N=512 C=3 H=227 W=227 F=64 K=11 ST=4 PD=0 ./run.sh
# 形状为(512,64,27,27)的图像张量和形状为(192,64,5,5)的内核张量以步幅 1 和填充 2 卷积
# 用 OpEvo 调优
nnictl create --config experiments/conv/N512C64HW27F192K5ST1PD2/config_opevo.yml
# 用 AutoTVM 调优
OP=convfwd_direct STEP=512 N=512 C=64 H=27 W=27 F=192 K=5 ST=1 PD=2 ./run.sh
请注意,G-BFS 和 N-A2C 这两种方法是专为优化行和列为2的幂的矩阵相乘的平铺(tiling)策略而设计的,所以他们不能够兼容其他类型的搜索空间,因此不能够用来优化批量矩阵乘和2维卷积这两种张量算子。 这里,AutoTVM是由作者在 TVM 项目中实现的,因此调优结果打印在屏幕上,而不是报告给 NNI 管理器。 容器的端口 8080 绑定到主机的同一端口,因此可以通过 ``host_ip_addr:8080`` 访问 NNI Web 界面,并监视调优过程,如下面的屏幕截图所示。
.. image:: ../../img/opevo.png
引用 OpEvo
------------
如果认为 OpEvo 有帮助,请考虑如下引用论文:
.. code-block:: bash
@misc{gao2020opevo,
title={OpEvo: An Evolutionary Method for Tensor Operator Optimization},
author={Xiaotian Gao and Cui Wei and Lintao Zhang and Mao Yang},
year={2020},
eprint={2006.05664},
archivePrefix={arXiv},
primaryClass={cs.LG}
}
../../en_US/TrialExample/OpEvoExamples.rst
\ No newline at end of file
../../en_US/TrialExample/Pix2pixExample.rst
\ No newline at end of file
在 NNI 上调优 RocksDB
=====================
概述
--------
`RocksDB <https://github.com/facebook/rocksdb>`__ 是流行的高性能、嵌入式的生产级别的键值数据库,它在 Facebook,Yahoo!,和 LinkedIn 等各种规模的网站上使用。 这是 Facebook 的 `LevelDB <https://github.com/google/leveldb>`__ 分支,为多 CPU,快速存储(如 SSD)的输入输出进行了优化。
RocksDB 的性能表现非常依赖于调优操作。 但由于其底层技术较复杂,可配置参数非常多,很难获得较好的配置。 NNI 可帮助解决此问题。 NNI 支持多种调优算法来为 RocksDB 搜索最好的配置,并支持本机、远程服务器和云服务等多种环境。
本示例展示了如何使用 NNI,通过评测工具 ``db_bench`` 来找到 ``fillrandom`` 基准的最佳配置,此工具是 RocksDB 官方提供的评测工具。 在运行示例前,需要检查 NNI 已安装, `db_bench <https://github.com/facebook/rocksdb/wiki/Benchmarking-tools>`__ 已经加入到了 ``PATH`` 中。 此简单脚本 :githublink:`db_bench_installation.sh <examples/trials/systems_auto_tuning/rocksdb-fillrandom/db_bench_installation.sh>` 可帮助编译并在 Ubuntu 上安装 ``db_bench`` 及其依赖包。 可遵循相同的过程在其它系统中安装 RocksDB。
:githublink:`代码文件 <examples/trials/systems_auto_tuning/rocksdb-fillrandom>` 可遵循相同的过程在其它系统中安装 RocksDB。
:githublink:`代码文件 <examples/trials/systems_auto_tuning/rocksdb-fillrandom/main.py>`
Experiment 设置
----------------
在 NNI 上配置调优的 Experiment 主要有三个步骤。 使用 ``json`` 文件定义搜索空间,编写评测代码,将配置传入 NNI 管理器来启动 Experiment。
搜索空间
^^^^^^^^^^^^
为简单起见,此示例仅调优三个参数,``write_buffer_size``,``min_write_buffer_num`` 以及 ``level0_file_num_compaction_trigger``,场景为测试随机写入 16M 数据的每秒写操作数(OPS),其 Key 为 20 字节,值为 100 字节。 ``write_buffer_size`` 设置单个内存表的大小。 一旦内存表超过此大小,会被标记为不可变,并创建新内存表。 ``min_write_buffer_num`` 是要合并写入存储的最小内存表数量。 一旦 Level 0 的文件数量达到了 ``level0_file_num_compaction_trigger``,就会触发 Level 0 到 Level 1 的压缩。
此示例中,下列 ``search_space.json`` 文件指定了搜索空间。 搜索空间的详细说明参考 `这里 <../Tutorial/SearchSpaceSpec.rst>`__.。
.. code-block:: json
{
"write_buffer_size": {
"_type": "quniform",
"_value": [2097152, 16777216, 1048576]
},
"min_write_buffer_number_to_merge": {
"_type": "quniform",
"_value": [2, 16, 1]
},
"level0_file_num_compaction_trigger": {
"_type": "quniform",
"_value": [2, 16, 1]
}
}
:githublink:`代码文件 <examples/trials/systems_auto_tuning/rocksdb-fillrandom/search_space.json>`
基准测试
^^^^^^^^^^^^^^
评测代码从 NNI 管理器接收配置,并返回相应的基准测试结果。 下列 NNI API 用于相应的操作。 此示例中,每秒写操作数(OPS)作为了性能指标。 参考 `这里 <Trials.rst>`__,了解详情。
* 使用 ``nni.get_next_parameter()`` 来获取下一个系统配置。
* 使用 ``nni.report_final_result(metric)`` 来返回测试结果。
:githublink:`代码文件 <examples/trials/systems_auto_tuning/rocksdb-fillrandom/config_tpe.yml>`
配置文件
^^^^^^^^^^^
用于启动 NNI Experiment 的配置文件。 此配置文件是 ``YAML`` 格式,通常包括了 Experiment 设置 (\ ``trialConcurrency``\ , ``maxExecDuration``\ , ``maxTrialNum``\ , ``trial gpuNum``\ 等),平台设置 (\ ``trainingServicePlatform``\ 等),路径设置 (\ ``searchSpacePath``\ , ``trial codeDir``\ 等) 以及 Tuner 设置 (\ ``tuner``\ , ``tuner optimize_mode``\ 等)。 参考 `这里 <../Tutorial/QuickStart.rst>`__ 了解详情。
这是使用 SMAC 算法调优 RocksDB 的示例:
:githublink:`代码文件 <examples/trials/systems_auto_tuning/rocksdb-fillrandom/config_smac.yml>`
这是使用 TPE 算法调优 RocksDB 的示例:
:githublink:`代码文件 <examples/trials/systems_auto_tuning/rocksdb-fillrandom/config_tpe.yml>`
其它 Tuner 算法可以通过相同的方式来使用。 参考 `这里 <../Tuner/BuiltinTuner.rst>`__ 了解详情。
最后,进入示例目录,并通过下列命令启动 Experiment:
.. code-block:: bash
# 在 NNI 上调优 RocksDB
nnictl create --config ./config_smac.yml
# 在 NNI 上使用 TPE Tuner 调优 RocksDB
nnictl create --config ./config_tpe.yml
Experiment 结果
------------------
在同一台计算机上运行这两个示例的详细信息:
* 16 * Intel(R) Xeon(R) CPU E5-2650 v2 @ 2.60GHz
* 465 GB 磁盘,安装 ext4 操作系统
* 128 GB 内存
* 内核版本: 4.15.0-58-generic
* NNI 版本: v1.0-37-g1bd24577
* RocksDB 版本: 6.4
* RocksDB DEBUG_LEVEL: 0
详细的实验结果如下图所示。 水平轴是 Trial 的顺序。 垂直轴是指标,此例中为写入的 OPS。 蓝点表示使用的是 SMAC Tuner,橙色表示使用的是 TPE Tuner。
.. image:: ../../img/rocksdb-fillrandom-plot.png
:target: ../../img/rocksdb-fillrandom-plot.png
:alt: image
下表列出了两个 Tuner 获得的最佳 Trial 以及相应的参数和指标。 不出所料,两个 Tuner 都为 ``fillrandom`` 测试找到了一样的最佳配置。
.. list-table::
:header-rows: 1
:widths: auto
* - 概述
- 最佳 Trial
- 最佳 OPS
- write_buffer_size
- min_write_buffer_number_to_merge
- level0_file_num_compaction_trigger
* - SMAC
- 255
- 779289
- 2097152
- 7.0
- 7.0
* - TPE
- 169
- 761456
- 2097152
- 7.0
- 7.0
../../en_US/TrialExample/RocksdbExamples.rst
\ No newline at end of file
NNI 中使用 scikit-learn
======================================
`Scikit-learn <https://github.com/scikit-learn/scikit-learn>`__ (sklearn) 是流行的数据挖掘和分析工具。 它支持多种机器学习模型,如线性回归,逻辑回归,决策树,支持向量机等。 如何更高效的使用 scikit-learn,是一个很有价值的话题。
NNI 支持多种调优算法来为 scikit-learn 搜索最好的模型和超参,并支持本机、远程服务器和云服务等多种环境。
1. 如何运行此示例
-------------------------
安装 NNI 包,并使用命令行工具 ``nnictl`` 来启动 Experiment。 有关安装和环境准备的内容,参考 `这里 <../Tutorial/QuickStart.rst>`__。
安装完 NNI 后,进入相应的目录,输入下列命令即可启动 Experiment:
.. code-block:: bash
nnictl create --config ./config.yml
2. 示例概述
-----------------------------
2.1 分类
^^^^^^^^^^^^^^^^^^
示例使用了数字数据集,它是由 1797 个 8x8 的图片组成,每个图片都是一个手写数字,目标是将图片分为 10 类。
在这个示例中,使用 SVC 作为模型,并为此模型选择一些参数,包括 ``"C", "kernel", "degree", "gamma" 和 "coef0"``。 关于这些参数的更多信息,可参考 `这里 <https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html>`__。
2.2 回归
^^^^^^^^^^^^^^
此示例使用了波士顿房价数据,数据集由波士顿各地区房价所组成,还包括了房屋的周边信息,例如:犯罪率 (CRIM),非零售业务的面积 (INDUS),房主年龄 (AGE) 等等。这些信息可用来预测波士顿的房价。
本例中,尝试了不同的回归模型,包括 ``"LinearRegression", "SVR", "KNeighborsRegressor", "DecisionTreeRegressor"</code> 和一些参数,如 <code>"svr_kernel", "knr_weights"``。 关于这些模型算法和参数的更多信息,可参考 `这里 <https://scikit-learn.org/stable/supervised_learning.html#supervised-learning>`__ 。
3. 如何在 NNI 中使用 scikit-learn
-------------------------------------------
只需要如下几步,即可在 scikit-learn 代码中使用 NNI。
*
**第一步**
准备 search_space.json 文件来存储选择的搜索空间。
例如,如果要在不同的模型中选择:
.. code-block:: json
{
"model_name":{"_type":"choice","_value":["LinearRegression", "SVR", "KNeighborsRegressor", "DecisionTreeRegressor"]}
}
如果要选择不同的模型和参数,可以将它们放到同一个 search_space.json 文件中。
.. code-block:: json
{
"model_name":{"_type":"choice","_value":["LinearRegression", "SVR", "KNeighborsRegressor", "DecisionTreeRegressor"]},
"svr_kernel": {"_type":"choice","_value":["linear", "poly", "rbf"]},
"knr_weights": {"_type":"choice","_value":["uniform", "distance"]}
}
在 Python 代码中,可以将这些值作为一个 dict,读取到 Python 代码中。
*
**第二步**
在代码最前面,加上 ``import nni`` 来导入 NNI 包。
首先,要使用 ``nni.get_next_parameter()`` 函数从 NNI 中获取参数。 然后在代码中使用这些参数。
例如,如果定义了如下的 search_space.json:
.. code-block:: json
{
"C": {"_type":"uniform","_value":[0.1, 1]},
"kernel": {"_type":"choice","_value":["linear", "rbf", "poly", "sigmoid"]},
"degree": {"_type":"choice","_value":[1, 2, 3, 4]},
"gamma": {"_type":"uniform","_value":[0.01, 0.1]},
"coef0": {"_type":"uniform","_value":[0.01, 0.1]}
}
就会获得像下面一样的 dict:
.. code-block:: python
params = {
'C': 1.0,
'kernel': 'linear',
'degree': 3,
'gamma': 0.01,
'coef0': 0.01
}
就可以使用这些变量来编写 scikit-learn 的代码。
*
**第三步**
完成训练后,可以得到模型分数,如:精度,召回率,均方差等等。 NNI 需要将分数传入 Tuner 算法,并生成下一组参数,将结果回传给 NNI,并开始下一个 Trial 任务。
在运行完 scikit-learn 代码后,只需要使用 ``nni.report_final_result(score)`` 来与 NNI 通信即可。 或者在每一步中都有多个分值,可使用 ``nni.report_intemediate_result(score)`` 来将它们回传给 NNI。 注意, 可以不返回中间分数,但必须返回最终的分数。
../../en_US/TrialExample/SklearnExamples.rst
\ No newline at end of file
在阅读理解上使用自动模型架构搜索
=============================================================
该示例展示了如何使用遗传算法为阅读理解任务找到好的模型架构。
1. Search Space
---------------
在阅读理解领域,注意力(Attention)和循环神经网络都已被证明是非常有效的方法,因此搜索空间定义如下:
#. IDENTITY (Effectively 表示继续训练)。
#. INSERT-RNN-LAYER (插入 LSTM。 在 Experiment 中比较了 GRU 和 LSTM 的性能后,我们决定在这里采用 LSTM。)
#. REMOVE-RNN-LAYER
#. INSERT-ATTENTION-LAYER (插入注意力层。)
#. REMOVE-ATTENTION-LAYER
#. ADD-SKIP (在随机层之间一致).
#. REMOVE-SKIP (移除随机跳过).
.. image:: ../../../examples/trials/ga_squad/ga_squad.png
:target: ../../../examples/trials/ga_squad/ga_squad.png
:alt:
新版本
^^^^^^^^^^^
另一个时间更快,性能更好的版本正在开发中。 很快将发布。
2. 如何在本机运行此示例?
------------------------------------
2.1 使用下载脚本来下载数据
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
执行下列命令来下载
所需要的数据:
.. code-block:: bash
chmod +x ./download.sh
./download.sh
或手动下载
#. 在 `这里 <https://rajpurkar.github.io/SQuAD-explorer/>`__ 下载 ``dev-v1.1.json`` 和 ``train-v1.1.json``
.. code-block:: bash
wget https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v1.1.json
wget https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v1.1.json
#. 在 `这里 <https://nlp.stanford.edu/projects/glove/>`__ 下载 ``glove.840B.300d.txt``
.. code-block:: bash
wget http://nlp.stanford.edu/data/glove.840B.300d.zip
unzip glove.840B.300d.zip
2.2 更新配置
^^^^^^^^^^^^^^^^^^^^^^^^
修改 ``nni/examples/trials/ga_squad/config.yml``,以下是默认配置:
.. code-block:: yaml
authorName: default
experimentName: example_ga_squad
trialConcurrency: 1
maxExecDuration: 1h
maxTrialNum: 1
#choice: local, remote
trainingServicePlatform: local
# 选择:true, false
useAnnotation: false
tuner:
codeDir: ~/nni/examples/tuners/ga_customer_tuner
classFileName: customer_tuner.py
className: CustomerTuner
classArgs:
optimize_mode: maximize
trial:
command: python3 trial.py
codeDir: ~/nni/examples/trials/ga_squad
gpuNum: 0
在 "Trial" 部分中,如果需要使用 GPU 来进行架构搜索,可将 ``gpuNum`` 从 ``0`` 改为 ``1``。 根据训练时长,可以增加 ``maxTrialNum`` 和 ``maxExecDuration``。
2.3 提交任务
^^^^^^^^^^^^^^^^^^^
.. code-block:: bash
nnictl create --config ~/nni/examples/trials/ga_squad/config.yml
3 在 OpenPAI 上运行此示例
-----------------------------
根据上传大小的限制,仅上传源代码,并在训练过程中下载数据。 本 Experiment 需要的内存 ``memoryMB >= 32G``,训练过程可能需要数小时。
3.1 更新配置
^^^^^^^^^^^^^^^^^^^^^^^^
修改 ``nni/examples/trials/ga_squad/config_pai.yml``,以下是默认配置:
.. code-block:: yaml
authorName: default
experimentName: example_ga_squad
trialConcurrency: 1
maxExecDuration: 1h
maxTrialNum: 10
#choice: local, remote, pai
trainingServicePlatform: pai
#choice: true, false
useAnnotation: false
# 你的 nni_manager ip 地址
nniManagerIp: 10.10.10.10
tuner:
codeDir: https://github.com/Microsoft/nni/tree/v2.0/examples/tuners/ga_customer_tuner
classFileName: customer_tuner.py
className: CustomerTuner
classArgs:
optimize_mode: maximize
trial:
command: chmod +x ./download.sh && ./download.sh && python3 trial.py
codeDir: .
gpuNum: 0
cpuNum: 1
memoryMB: 32869
# 在 OpenPAI 上运行 NNI 的 Docker 映像
image: msranni/nni:latest
paiConfig:
# 登录 OpenPAI 的用户名
userName: username
# 登录 OpenPAI 的密码
passWord: password
# OpenPAI 的 RestFUL 服务器地址
host: 10.10.10.10
将默认值改为个人账户和服务器信息。 包括 ``nniManagerIp``\ , ``userName``\ , ``passWord`` 和 ``host``。
在 "Trial" 部分中,如果需要使用 GPU 来进行架构搜索,可将 ``gpuNum`` 从 ``0`` 改为 ``1``。 根据训练时长,可以增加 ``maxTrialNum`` 和 ``maxExecDuration``。
``trialConcurrency`` 是并发运行的 Trial 的数量。如果将 ``gpuNum`` 设置为 1,则需要与 GPU 数量一致。
3.2 提交任务
^^^^^^^^^^^^^^^^^^^
.. code-block:: bash
nnictl create --config ~/nni/examples/trials/ga_squad/config_pai.yml
4. 代码实现
------------------------------------
4.1 实现方法
^^^^^^^^^^^^^^^^^^^^^
基于进化算法架构的问答和其它示例一样,有两个部分:Trial 和 Tuner。
4.2 Trial
^^^^^^^^^^^^^
Trial 有大量的文件、函数和类。 这里只简单介绍最重要的文件:
* ``attention.py`` 包含了 Tensorflow 注意力算法的实现。
* ``data.py`` 包含了数据处理函数。
* ``evaluate.py`` 包含了评估脚本。
* ``graph.py`` 包含了计算图的定义。
* ``rnn.py`` 包含了 TensorFlow 的 GRU 实现。
* ``train_model.py`` 是整个文档模型的封装。
这些文件中,``trial.py`` 和 ``graph_to_tf.py`` 非常特别。
``graph_to_tf.py`` 有一个叫做 ``graph_to_network`` 的函数,其框架代码如下:
.. code-block:: python
def graph_to_network(input1,
input2,
input1_lengths,
input2_lengths,
graph,
dropout_rate,
is_training,
num_heads=1,
rnn_units=256):
topology = graph.is_topology()
layers = dict()
layers_sequence_lengths = dict()
num_units = input1.get_shape().as_list()[-1]
layers[0] = input1*tf.sqrt(tf.cast(num_units, tf.float32)) + \
positional_encoding(input1, scale=False, zero_pad=False)
layers[1] = input2*tf.sqrt(tf.cast(num_units, tf.float32))
layers[0] = dropout(layers[0], dropout_rate, is_training)
layers[1] = dropout(layers[1], dropout_rate, is_training)
layers_sequence_lengths[0] = input1_lengths
layers_sequence_lengths[1] = input2_lengths
for _, topo_i in enumerate(topology):
if topo_i == '|':
continue
if graph.layers[topo_i].graph_type == LayerType.input.value:
# ......
elif graph.layers[topo_i].graph_type == LayerType.attention.value:
# ......
# 处理更多层
正如我们看到的,这个函数实际上是个编译器。它将内部模型的 DAG 配置 ``图``(在 ``模型配置格式`` 章节介绍)转换为 Tensorflow 的计算图。
.. code-block:: python
topology = graph.is_topology()
将内部图表示进行拓扑排序,代码在下列循环中:
.. code-block:: python
for _, topo_i in enumerate(topology):
执行实际转换,将每层映射为 TensorFlow 计算图中的一部分。
4.3 Tuner
^^^^^^^^^^^^^
Tuner 比 Trial 代码简单很多。 它们共用了同样的 ``graph.py``。 此外,Tuner 有 ``customer_tuner.py``,其中最重要的类是 ``CustomerTuner``:
.. code-block:: python
class CustomerTuner(Tuner):
# ......
def generate_parameters(self, parameter_id):
"""以可序列化对象的形式返回一组 Trial (超)参数
parameter_id : int
"""
if len(self.population) <= 0:
logger.debug("the len of poplution lower than zero.")
raise Exception('The population is empty')
pos = -1
for i in range(len(self.population)):
if self.population[i].result == None:
pos = i
break
if pos != -1:
indiv = copy.deepcopy(self.population[pos])
self.population.pop(pos)
temp = json.loads(graph_dumps(indiv.config))
else:
random.shuffle(self.population)
if self.population[0].result > self.population[1].result:
self.population[0] = self.population[1]
indiv = copy.deepcopy(self.population[0])
self.population.pop(1)
indiv.mutation()
graph = indiv.config
temp = json.loads(graph_dumps(graph))
# ......
重载函数 ``generate_parameters`` 实现了简单的变异算法。 代码如下:
.. code-block:: python
if self.population[0].result > self.population[1].result:
self.population[0] = self.population[1]
indiv = copy.deepcopy(self.population[0])
控制突变过程。 它会在种群中随机取出两个个体,对更好结果的一个保留数据,并突变另一个。
4.4 模型配置格式
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
这是模型配置的示例,在架构搜索过程中,从 Tuner 传入 Trial 的代码。
.. code-block:: json
{
"max_layer_num": 50,
"layers": [
{
"input_size": 0,
"type": 3,
"output_size": 1,
"input": [],
"size": "x",
"output": [4, 5],
"is_delete": false
},
{
"input_size": 0,
"type": 3,
"output_size": 1,
"input": [],
"size": "y",
"output": [4, 5],
"is_delete": false
},
{
"input_size": 1,
"type": 4,
"output_size": 0,
"input": [6],
"size": "x",
"output": [],
"is_delete": false
},
{
"input_size": 1,
"type": 4,
"output_size": 0,
"input": [5],
"size": "y",
"output": [],
"is_delete": false
},
{"Comment": "More layers will be here for actual graphs."}
]
}
每个模型配置都有一个 "layers" 部分,这是层定义的 JSON 列表。 每层的定义也是一个 JSON 对象:
* ``type`` 是层的类型。 0, 1, 2, 3, 4 对应注意力、自注意力、RNN、输入和输出层。
* ``type`` 是输出的长度。 "x", "y" 对应文档长度和问题长度。
* ``type`` 是该层的输入数量。
* ``type`` 表示输入层的索引。
* ``type`` 是输出层的索引,该层会作为这些层的输入。
* ``type`` 表示此层是否可用。
../../en_US/TrialExample/SquadEvolutionExamples.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