使用NNI的scikit-learn以及Tensorflow分析

1、NNI简介

在这里插入图片描述
NNI (Neural Network Intelligence) 是自动机器学习(AutoML)的工具包。 它经过多种调优的算法来搜索最好的神经网络结构和(或)超参,并支持单机、本地多机、云等不一样的运行环境。
在这里插入图片描述javascript

Supported Frameworks Tuning Algorithms Training Services
PyTorch TPE Local Machine
TensorFlow Random Search Remote Servers
Keras Anneal OpenPAI
MXNet Naive Evolution Kubeflow
Caffe2 SMAC FrameworkController on K8S (AKS etc.)
CNTK Batch
KerasChainer Grid Search
Theano Hyperband
Network Morphism
ENAS
Metis Tuner

使用场景html

  • 在本地 Trial 不一样的自动机器学习算法来训练模型。
  • 在分布式环境中加速自动机器学习(如:远程 GPU 工做站和云服务器)。
  • 定制自动机器学习算法,或比较不一样的自动机器学习算法。
  • 在本身的机器学习平台中支持自动机器学习。

具体安装以及应用请参照官网java

2、使用NNI对scikit-learn进行调参

scikit-learn (sklearn) 是数据挖掘和分析的流行工具。 它支持多种机器学习模型,如线性回归,逻辑回归,决策树,支持向量机等。 提升 scikit-learn 的效率是很是有价值的课题。
NNI 支持多种调优算法,能够为 scikit-learn 搜索最佳的模型和超参,并支持本机、远程服务器组、云等各类环境。python

  1. 样例概述

样例使用了数字数据集,由 1797 张 8x8 的图片组成,每张图片都是一个手写数字。目标是将这些图片分到 10 个类别中。在此样例中,使用了 SVC 做为模型,并选择了一些参数,包括 "C", "keral", "degree", "gamma" 和 "coef0"。 关于这些参数的更多信息,可参考这里git

  1. 如何在 NNI 中使用 sklearn

只须要以下几步,便可在 sklearn 代码中使用 NNI。github

  • 第一步,定义搜索空间

准备 search_space.json 文件来存储选择的搜索空间。 例如,不一样的正则化值:算法

{
    "C": {"_type":"uniform","_value":[0.1, 1]},
}

若是要选择不一样的正则化参数、核函数等,能够将其放进一个search_space.json文件中。编程

{
    "C": {"_type":"uniform","_value":[0.1, 1]},
    "keral": {"_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]}
}

在 Python 代码中,能够将这些值做为一个 dict,读取到 Python 代码中。json

  • 第二步,代码修改

在代码最前面,要加上 import nni 来导入 NNI 包。
而后,要使用nni.get_next_parameter() 函数从 NNI 中获取参数。 而后在代码中使用这些参数。 例如,若是定义了如上的 search_space.json,就会得到像下面同样的 dict,就可使用这些变量来编写 scikit-learn 的代码。服务器

params = {
    "C": 0.1,
    "keral": "linear",
    "degree": 1,
    "gamma": 0.01,
    "coef0 ": 0.01
}

完成训练后,能够获得模型分数,如:精度,召回率,均方差等等。 NNI 会将分数发送给 Tuner 算法,并据今生成下一组参数,因此须要将分数返回给 NNI。NNI 会开始下一个 Trial 任务。
所以只须要在训练结束后调用 nni.report_final_result(score),就能够将分数传给 NNI。 若是训练过程当中有中间分数,也可使用 nni.report_intemediate_result(score) 返回给 NNI。 注意, 能够不返回中间分数,但必须返回最终的分数。

def run(X_train, X_test, y_train, y_test, PARAMS):
    '''Train model and predict result'''
    model.fit(X_train, y_train)
    score = model.score(X_test, y_test)
    LOG.debug('score: %s' % score)
    nni.report_final_result(score)

if __name__ == '__main__':
    X_train, X_test, y_train, y_test = load_data()

    try:
        # get parameters from tuner
        RECEIVED_PARAMS = nni.get_next_parameter()
        LOG.debug(RECEIVED_PARAMS)
        PARAMS = get_default_parameters()
        PARAMS.update(RECEIVED_PARAMS)
        LOG.debug(PARAMS)
        model = get_model(PARAMS)
        run(X_train, X_test, y_train, y_test, model)
    except Exception as exception:
        LOG.exception(exception)
        raise
}

如上代码所示,在运行开始经过nni.get_next_parameter()调用参数,结束后在run()中经过nni.report_final_result(score)返回评估值,具体代码可参考样例

  • 第三步,准备 Tuner以及配置文件

准备 Tuner: NNI 支持多种流行的自动机器学习算法,包括:Random Search(随机搜索),Tree of Parzen Estimators (TPE),Evolution(进化算法)等等。 也能够实现本身的 Tuner(参考这里)。下面使用了 NNI 内置的 Tuner:

tuner:
    builtinTunerName: TPE
    classArgs:
      optimize_mode: maximize

builtinTunerName 用来指定 NNI 中的 Tuner,classArgs 是传入到 Tuner的参数( 内置 Tuner在这里),optimization_mode 代表须要最大化仍是最小化 Trial 的结果。

准备配置文件: 实现 Trial 的代码,并选择或实现自定义的 Tuner 后,就要准备 YAML 配置文件了。 其大体内容以下:

authorName: default
experimentName: example_sklearn-classification
# 并发运行数量
trialConcurrency: 1
# Experiment 运行时间
maxExecDuration: 1h
# 可为空,即数量不限
maxTrialNum: 100
#choice: local, remote
trainingServicePlatform: local
searchSpacePath: search_space.json
#choice: true, false
useAnnotation: false
tuner:
  #choice: TPE, Random, Anneal, Evolution
  builtinTunerName: TPE
  classArgs:
    #choice: maximize, minimize
    optimize_mode: maximize
trial:
  command: python3 main.py
  codeDir: .
  gpuNum: 0

由于这个 Trial 代码没有使用 NNI Annotation的方法,因此useAnnotation 为 false。 command 是运行 Trial 代码所须要的命令,codeDir 是 Trial 代码的相对位置。 命令会在此目录中执行。 同时,也须要提供每一个 Trial 进程所需的 GPU 数量。

完成上述步骤后,可经过下列命令来启动 Experiment:

nnictl create --config ~/nni/examples/trials/sklearn/classification/config.yml

参考这里来了解 nnictl 命令行工具的更多用法。

  1. 查看 Experiment 结果
    在这里插入图片描述

当出现Successfully started experiment!即表示实验成功,可经过Web UI的地址来查看实验结果,本次实验的实验结果以下图所示:

查看概要页面:
点击标签 "Overview"。
简介

此图为Web UI的整体界面,经过此界面能够查看运行状态、搜索空间。能够在运行中或结束后,随时下载 Experiment 的结果。从上图中咱们能够发现,咱们最好的运行结果为0.98222,运行11次共花费2分钟。前 10 个 Trial 结果也会列在 Overview 页面中,以下所示:
在这里插入图片描述

点击➕,还能够查看具体的参数值。
在这里插入图片描述

查看 Trial 详情页面:
点击 "Default Metric" 来查看全部 Trial 的点图。
在这里插入图片描述

点击 "Hyper Parameter" 标签查看图像。

  • 可选择百分比查看最好的 Trial。
  • 选择两个轴来交换位置。
    在这里插入图片描述

点击 "Trial Duration" 标签来查看柱状图,可观察到每次的运行时间。
在这里插入图片描述

3、使用NNI对TensorFlow进行调参

TensorFlow是一个基于数据流编程(dataflow programming)的符号数学系统,被普遍应用于各种机器学习(machine learning)算法的编程实现,它支持多种深度学习的架构。

  1. 样例概述

MINIST是深度学习的经典入门demo,它是由6万张训练图片和1万张测试图片构成的,每张图片都是28*28大小(以下图),并且都是黑白色构成(这里的黑色是一个0-1的浮点数,黑色越深表示数值越靠近1),这些图片是采集的不一样的人手写从0到9的数字。TensorFlow将这个数据集和相关操做封装到了库中,而NNI能够为基于TensorFlow的深度学习算法搜索最佳的模型和超参。
在这里插入图片描述

  1. 如何在 NNI 中使用 TensorFlow

只须要以下几步,便可在 TensorFlow 代码中使用 NNI。由于具体步骤与上一个样例相同,在本例中仅给出相应代码。

  • 第一步,定义搜索空间

search_space.json文件为:

{
    "dropout_rate":{"_type":"uniform","_value":[0.5, 0.9]},
    "conv_size":{"_type":"choice","_value":[2,3,5,7]},
    "hidden_size":{"_type":"choice","_value":[124, 512, 1024]},
    "batch_size": {"_type":"choice", "_value": [1, 4, 8, 16, 32]},
    "learning_rate":{"_type":"choice","_value":[0.0001, 0.001, 0.01, 0.1]}
}

本例对于正则化、网络架构以及学习速率等超参进行调试。

  • 第二步,代码修改

在代码最前面,加上 import nni 来导入 NNI 包。
而后,要使用nni.get_next_parameter() 函数从 NNI 中获取参数。
最后只须要在训练结束后调用 nni.report_final_result(score),就能够将分数传给 NNI。具体代码可参考样例

  • 第三步,准备 Tuner以及配置文件

准备 Tuner: 本例使用 NNI 内置的 Tuner :Tree of Parzen Estimators (TPE)

tuner:
    builtinTunerName: TPE
    classArgs:
      optimize_mode: maximize

准备配置文件: 实现 Trial 的代码,并选择或实现自定义的 Tuner 后,就要准备 YAML 配置文件了。 其大体内容以下:

authorName: default
experimentName: example_mnist
trialConcurrency: 1
maxExecDuration: 1h
maxTrialNum: 10
#choice: local, remote, pai
trainingServicePlatform: local
searchSpacePath: search_space.json
#choice: true, false
useAnnotation: false
tuner:
  #choice: TPE, Random, Anneal, Evolution, BatchTuner
  #SMAC (SMAC should be installed through nnictl)
  builtinTunerName: TPE
  classArgs:
    #choice: maximize, minimize
    optimize_mode: maximize
trial:
  command: python3 mnist.py
  codeDir: .
  gpuNum: 0

由于这个 Trial 代码没有使用 NNI Annotation的方法,因此useAnnotation 为 false。 command 是运行 Trial 代码所须要的命令,codeDir 是 Trial 代码的相对位置。 命令会在此目录中执行。 同时,也须要提供每一个 Trial 进程所需的 GPU 数量。

完成上述步骤后,可经过下列命令来启动 Experiment:

nnictl create --config ~/nni/examples/trials/minist/config.yml

参考这里来了解 nnictl 命令行工具的更多用法。

  1. 查看 Experiment 结果

本例将最大次数设置为20,实验结果以下图所示:

查看概要页面:

在这里插入图片描述

从上图中咱们能够发现,咱们最好的运行结果为0.981900,运行19次共花费60分钟。前 10 个 Trial 结果以下所示:

在这里插入图片描述
具体的参数值为:
在这里插入图片描述
查看 Trial 详情页面:
点击 "Default Metric" 来查看全部 Trial 的点图。
在这里插入图片描述
点击 "Hyper Parameter" 标签查看图像。

  • 可选择百分比查看最好的 Trial。
  • 选择两个轴来交换位置。
    在这里插入图片描述
    点击 "Trial Duration" 标签来查看柱状图,可观察到每次的运行时间。
    在这里插入图片描述

    4、总结

经过本文所应用的两个示例咱们能够看到,NNI工具包能够帮助用户或者开发者自动进行数据分析,自动帮他们搜索模型,进行参数调试和性能分析。NNI极大的简便了 scikit-learn以及TensorFlow的调试工做。NNI仅仅须要定义搜索空间、简单的修改代码、编写配置文件就能够快速调试超参,而且其参数性能优越,并且提供了Web UI来查看调试过程当中的相应信息。NNI能够为用户能够节省更多的时间,将精力放在探索更有深度的机器学习上。

相关文章
相关标签/搜索