使用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能夠爲用戶能夠節省更多的時間,將精力放在探索更有深度的機器學習上。

相關文章
相關標籤/搜索