Auto ML : NNI 1.5 : 自動調整 : 自動 (ハイパーパラメータ) 調整 &トライアル Run を書く (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 05/24/2020 (1.5)
* 本ページは、NNI の以下のドキュメントを翻訳した上で適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
自動 (ハイパーパラメータ) 調整
自動調整は NNI により提供される主要な特徴の一つです ; 主要な適用シナリオはハイパーパラメータ調整です。調整は特にトライアルコードに適用されます。多くのポピュラーな自動調整アルゴリズム (チューナーと呼びます) と幾つかの early stop アルゴリズム (アセッサーと呼びます) を提供します。NNI は様々なプラットフォーム、例えば、ローカルマシン、分散流儀の幾つかのサーバ、あるいは OpenPAI, Kubernetes のようなプラットフォームでのトライアルの実行をサポートしています。
モデル圧縮、特徴エンジニアリングのような NNI の他の主要特徴も自動調整により更に拡張できます、それらの特徴を紹介するときに説明されます。
NNI は高い拡張性を持ち、上級ユーザはニーズに従って彼ら自身のチューナー、アセッサーそして訓練サービスをカスタマイズできます。
自動調整 : トライアル Run を書く
NNI のトライアルはモデルに configuration (e.g., ハイパーパラメータのセット) を適用する個々の試行です。
NNI トライアルを定義するためには、最初にパラメータのセット (i.e., 探索空間) を定義してからモデルを更新する必要があります。
NNI はトライアルを定義するために貴方に 2 つのアプローチを提供します : NNI API と NNI Python アノテーション です。より多くのトライアル・サンプルは こちら を参照できるでしょう。
NNI API
Step 1 – 探索空間パラメータ・ファイルを準備する
サンプルは下で示されます :
{ "dropout_rate":{"_type":"uniform","_value":[0.1,0.5]}, "conv_size":{"_type":"choice","_value":[2,3,5,7]}, "hidden_size":{"_type":"choice","_value":[124, 512, 1024]}, "learning_rate":{"_type":"uniform","_value":[0.0001, 0.1]} }
探索空間について更に学習するためには SearchSpaceSpec.md を参照してください。チューナーはこの探索空間から configuration を生成します、つまり、範囲から各ハイパーパラメータのための値を選択します。
Step 2 – モデル・コードを更新する
- NNI をインポートする。
NNI API を使用するためにトライアル・コードに “import nni” を含めます。 - チューナーから configuration を得る。
RECEIVED_PARAMS = nni.get_next_parameter()
RECEIVED_PARAMS はオブジェクトです、 例えば :
{"conv_size": 2, "hidden_size": 124, "learning_rate": 0.0307, "dropout_rate": 0.2029}.
- メトリックデータを定期的に報告する (オプション)。
nni.report_intermediate_result(metrics)
メトリクスは任意の python オブジェクトであり得ます。ユーザが NMI 組込みチューナー/アセッサーを使用するのであれば、メトリクスは 2 つの形式だけを持つことができます : 1) 数字 e.g., float, int, 2) 辞書オブジェクト、これは default と名前付けられたキーを持ちその値は数字です。これらのメトリクスは アセッサー に報告されます。しばしば、メトリクスは定期的に評価される損失か精度を含みます。
- configuration のパフォーマンスを報告する。
nni.report_final_result(metrics)
メトリクスはまた任意の python オブジェクトであり得ます。ユーザが NNI 組込みチューナー/アセッサーを使用するのであれば、メトリクスは report_intermediate_result と同じ形式ルールに従います、数字はモデルのパフォーマンスを示します、例えば、モデルの精度、損失等です。このメトリクスは チューナー に報告されます。
Step 3 – NNI API を有効にする
NNI API モードを有効にするには、useAnnotation を false に設定して (step 1 で定義された) SearchSpace ファイルのパスを提供する必要があります :
useAnnotation: false searchSpacePath: /path/to/your/search_space.json
実験 configuration をどのようにセットアップするかについてより多くの情報は こちら を参照できます。
* NNI により提供されるより多くの API (e.g., nni.get_sequence_id()) については こちら を参照してください。
NNI Python アノテーション
トライアルを書くための代替は python のための NNI のシンタクスを使用します。NNI アノテーションは単純で、コメントに類似しています。既存のコードに構造的な変更を行なわなくて構いません。NNI アノテーションの数行で、以下が可能です :
- 調整したい変数 (= variables) をアノテートする
- どの範囲内で変数を調整することを望むか指定する
- どの変数をアセッサーに中間結果として報告することを望むかをアノテートする
- どの変数をチューナーに最終結果 (e.g. モデル精度) として報告することを望むかをアノテートする
再度、MNIST を例に取れば、それは NNI アノテーションでトライアルを書くために 2 ステップだけを要求します。
Step 1 – アノテーションでコードを更新する
以下は NNI アノテーションのための TensorFlow コード・スニペットです、そこではハイライトされた 4 行が次のようなアノテーションです :
- batch_size と dropout_rate を調整する
- 100 ステップ毎に test_acc を報告する
- 最後に最終結果として test_acc を報告する
注目すべきことは、これらの新たに追加されたコードは単なるアノテーションですので、NNI がインストールされていない環境で通常のようにコードを依然として実行できることです。
with tf.Session() as sess: sess.run(tf.global_variables_initializer()) + """@nni.variable(nni.choice(50, 250, 500), name=batch_size)""" batch_size = 128 for i in range(10000): batch = mnist.train.next_batch(batch_size) + """@nni.variable(nni.choice(0.1, 0.5), name=dropout_rate)""" dropout_rate = 0.5 mnist_network.train_step.run(feed_dict={mnist_network.images: batch[0], mnist_network.labels: batch[1], mnist_network.keep_prob: dropout_rate}) if i % 100 == 0: test_acc = mnist_network.accuracy.eval( feed_dict={mnist_network.images: mnist.test.images, mnist_network.labels: mnist.test.labels, mnist_network.keep_prob: 1.0}) + """@nni.report_intermediate_result(test_acc)""" test_acc = mnist_network.accuracy.eval( feed_dict={mnist_network.images: mnist.test.images, mnist_network.labels: mnist.test.labels, mnist_network.keep_prob: 1.0}) + """@nni.report_final_result(test_acc)"""
NOTE:
- @nni.variable はそれに続く行に影響を与え、それは割り当てステートメントであるはずで、その左辺は @nni.variable ステートメントでキーワード “name” と同じでなければなりません。
- @nni.report_intermediate_result/@nni.report_final_result はその行でデータをアセッサー/チューナーに送ります。
アノテーション・シンタックスとその使用方法についてのより多くの情報については、Annotation を参照してください。
Step 2 – NNI アノテーションを有効にする
YAML configuration ファイルでは、NNI アノテーションを有効にするために useAnnotation を true に設定する必要があります :
useAnnotation: true
デバッグのためのスタンドアロン・モード
NNI は NNI 実験を開始することなくトライアルコードを実行するためのスタンドアロン・モードをサポートしています。これはトライアルコードでバグをより便利に見つけ出すためです。追加された NNI 関連行がコメントであるため NNI アノテーションはスタンドアロン・モードを元々サポートします。NNI トライアル API については、API はスタンドアロン・モードでは動作を変更し、幾つかの API はダミー値を返し、そして幾つかの API は実際には値をレポートしません。これらの API の完全なリストについては次のテーブルを参照してください。
# NOTE: please assign default values to the hyperparameters in your trial code nni.get_next_parameter # return {} nni.report_final_result # have log printed on stdout, but does not report nni.report_intermediate_result # have log printed on stdout, but does not report nni.get_experiment_id # return "STANDALONE" nni.get_trial_id # return "STANDALONE" nni.get_sequence_id # return 0
mnist サンプル でスタンドアロン・モードを試すことができます。単純にコード・ディレクトリで python3 mnist.py を実行します。トライアルコードはデフォルトのハイパーパラメータ値で成功的に実行されるはずです。
デバッグ上のより多くの情報については、How to Debug を参照してください。
私のトライアルはどこでしょう?
ローカルモード
NNI では、総てのトライアルは自身のデータを出力するためにそれらのための専用ディレクトリを持ちます。各トライアルで、NNI_OUTPUT_DIR と呼ばれる環境変数がエクスポートされます。このディレクトリ下で、各トライアルのコード、データと他のログを見つけられます。加えて、(stdout を含む) 各トライアルのログはそのディレクトリ下で trial.log と名前付けられたファイルにリダイレクトされます。
NNI アノテーションが使用される場合、トライアルの変換されたコードはもう一つの一時ディレクトリにあります。それを NNI_OUTPUT_DIR で示されたディレクトリ下の run.sh と名前付けられたファイル内で確認できます。このファイルの 2 行目 (i.e., cd コマンド) はディレクトリをコードが位置する実際のディレクトリに変更します。下は run.sh のサンプルです :
#!/bin/bash cd /tmp/user_name/nni/annotation/tmpzj0h72x6 #This is the actual directory export NNI_PLATFORM=local export NNI_SYS_DIR=/home/user_name/nni/experiments/$experiment_id$/trials/$trial_id$ export NNI_TRIAL_JOB_ID=nrbb2 export NNI_OUTPUT_DIR=/home/user_name/nni/experiments/$eperiment_id$/trials/$trial_id$ export NNI_TRIAL_SEQ_ID=1 export MULTI_PHASE=false export CUDA_VISIBLE_DEVICES= eval python3 mnist.py 2>/home/user_name/nni/experiments/$experiment_id$/trials/$trial_id$/stderr echo $? `date +%s%3N` >/home/user_name/nni/experiments/$experiment_id$/trials/$trial_id$/.nni/state
他のモード
トライアルを遠隔マシンや PAI のような他のプラットフォーム上で実行するとき、環境変数 NNI_OUTPUT_DIR はトライアルの出力ディレクトリを参照するだけです、一方でトライアルコードと run.sh はそこにないかもしれません。けれども、trial.log は trail のディレクトリ内でローカルマシンに送り返されます、それは ~/nni/experiments/$experiment_id$/trials/$trial_id$/ がデフォルトです。
より多くの情報については、HowToDebug を参照してください。
より多くのトライアル・サンプル
- MNIST examples
- Finding out best optimizer for Cifar10 classification
- How to tune Scikit-learn on NNI
- Automatic Model Architecture Search for Reading Comprehension.
- Tuning GBDT on NNI
- Tuning RocksDB on NNI
以上