Auto ML : NNI Tutorials : チューナー (2) カスタマイズ・チューナー & アドバイザー (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 03/03/2019
* 本ページは、NNI の以下のドキュメントを翻訳した上で適宜、補足説明したものです:
- https://nni.readthedocs.io/en/latest/tuners.html
- https://nni.readthedocs.io/en/latest/Customize_Tuner.html
- https://nni.readthedocs.io/en/latest/Customize_Advisor.html
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
NNI Tutorials : チューナー
NNI はパラメータ調整アルゴリズムをセットアップするアプローチを採用するための簡単な方法を提供します、それらをチューナーと呼びます。
チューナーは、特定のパラメータ/アーキテクチャ構成のパフォーマンスを評価するためにトライアルからメトリクスを受け取ります。
NNI では、チューナーを設定するために 2 つのアプローチをサポートします : 1 番目は nni sdk により提供される組み込みチューナーを直接的に使用します、2 番目は貴方自身でチューナーファイルをカスタマイズします。チューナー & アセッサーの機能を結合する Advisor もまた持ちます。
カスタマイズ-チューナー
チューナーをカスタマイズする
NNI は組み込みチューナーで先端技術のチューニング・アルゴリズムを提供します。NNI はチューニング要件のために貴方自身でチューナーを構築することもサポートします。
貴方自身のチューニング・アルゴリズムを実装することを望むのであれば、カスタマイズされたチューナーを実装することができます、3 つの行なうべきことがあります :
- 基底 Tuner クラスを継承する
- receive_trial_result と generate_parameter 関数を実装する
- 実験 YAML config ファイルで貴方のカスタマイズされたチューナーを configure する
ここにサンプルがあります :
1. 基底 Tuner クラスを継承する
from nni.tuner import Tuner class CustomizedTuner(Tuner): def __init__(self, ...): ...
2. receive_trial_result と generate_parameter 関数を実装する
from nni.tuner import Tuner class CustomizedTuner(Tuner): def __init__(self, ...): ... def receive_trial_result(self, parameter_id, parameters, value): ''' Receive trial's final result. parameter_id: int parameters: object created by 'generate_parameters()' value: final metrics of the trial, including default metric ''' # your code implements here. ... def generate_parameters(self, parameter_id): ''' Returns a set of trial (hyper-)parameters, as a serializable object parameter_id: int ''' # your code implements here. return your_parameters ...
receive_trial_result はパラメータ入力として parameter_id, parameters, value を受け取ります。また、Tuner は Trial が送ったものと正確に同じ value オブジェクトを受け取ります。
generate_parameters 関数から返される your_parameters は NNI SDK により json オブジェクトとして pack されます。NNI SDK は json オブジェクトを unpack してトライアルは正確に同じ your_parameters を Tuner から受け取ります。
例えば : 貴方がこのように generate_parameters を実装する場合 :
def generate_parameters(self, parameter_id): ''' Returns a set of trial (hyper-)parameters, as a serializable object parameter_id: int ''' # your code implements here. return {"dropout": 0.3, "learning_rate": 0.4}
それは貴方の Tuner は常にパラメータ {“dropout”: 0.3, “learning_rate”: 0.4} を生成することを意味します。それから Trial は API nni.get_next_parameter() を呼び出すことにより {“dropout”: 0.3, “learning_rate”: 0.4} を受け取ります。ひとたび Trial が結果 (通常はある種のメトリクス) で終われば、それは API nni.report_final_result() を呼び出すことにより結果を Tuner に送ることができます、例えば nni.report_final_result(0.93) です。それから貴方の Tuner の receive_trial_result 関数は次のように結果を受け取ります :
parameter_id = 82347 parameters = {"dropout": 0.3, "learning_rate": 0.4} value = 0.93
貴方自身のチューナーのディレクトリでファイル (e.g., data.txt) にアクセスすることを望む場合、open(‘data.txt’, ‘r’) は使用できないことに注意してください。代わりに、次を使用するべきです :
_pwd = os.path.dirname(__file__) _fd = open(os.path.join(_pwd, 'data.txt'), 'r')
これは貴方のチューナーが貴方のチューナーのディレクトリで実行されないからです (i.e., pwd は貴方自身のオーナーのディレクトリではありません)。
3. 実験 YAML config ファイルで貴方のカスタマイズされたチューナーを configure する
NNI は貴方のカスタマイズされたチューナークラスの位置を特定してクラスをインスタンス化する必要がありますので、カスタマイズされたチューナークラスの位置を指定してパラメータとして literal values を __init__ コンストラクタに渡す必要があります。
tuner: codeDir: /home/abc/mytuner classFileName: my_customized_tuner.py className: CustomizedTuner # Any parameter need to pass to your tuner class __init__ constructor # can be specified in this optional classArgs field, for example classArgs: arg1: value1
より詳細なサンプルは以下を見ることができるでしょう :
より進んだ automl アルゴリズムを書く
上のメソッドは通常は一般的なチューナーを書くために十分です。けれども、よりパワフルな automl アルゴリズムを持つために、ユーザはより多くのメソッド、例えば、中間結果、トライアルの状態 (アセッサーのメソッド) も望むかも知れません。従って、アドバイザーと呼ばれるもう一つの概念を持ちます、これは src/sdk/pynni/nni/msg_dispatcher_base.py の MsgDispatcherBase から直接に継承します。
How To – 貴方自身のアドバイザーをカスタマイズする
アドバイザーは automl アルゴリズムがチューナーとアセッサーの両者のメソッドを望むシナリオを対象としています。アドバイザーはそれがトライアル・パラメータ・リクエスト、最終結果を受け取り、トライアル・パラメータを生成するという点でチューナーに類似しています。また、それが中間結果、トライアルの最終状態を受け取り、そしてトライアル kill コマンドを送ることができるという点でアセッサーに類似しています。アドバイザーを使用する場合、チューナーとアセッサーは同時に使用されることが許されないことに注意してください。
従って、ユーザがカスタマイズされたアドバイザーを実装することを望む場合、以下が必要なだけです :
- MsgDispatcherBase クラスから継承して Advisor を定義する
- handle_request を除いてプレフィクス handle_ でメソッドを実装する
- 実験 YAML config ファイルで貴方のカスタマイズされたアドバイザーを configure する
ここにサンプルがあります :
1) MsgDispatcherBase クラスから継承して Advisor を定義する
from nni.msg_dispatcher_base import MsgDispatcherBase class CustomizedAdvisor(MsgDispatcherBase): def __init__(self, ...): ...
2) handle_request を除いてプレフィクス handle_ でメソッドを実装する
メソッドをどのように実装するかについては Hyperband (src/sdk/pynni/nni/hyperband_advisor/hyperband_advisor.py) の実装を参照してください。
3) 実験 YAML config ファイルで貴方のカスタマイズされたアドバイザーを configure する
チューナーとアセッサーと同様です。NNI は貴方のカスタマイズされた Advisor クラスの位置を特定してクラスをインスタンス化する必要がありますので、カスタマイズされた Advisor クラスの位置を指定してパラメータとして literal values を __init__ コンストラクタに渡す必要があります。
advisor: codeDir: /home/abc/myadvisor classFileName: my_customized_advisor.py className: CustomizedAdvisor # Any parameter need to pass to your advisor class __init__ constructor # can be specified in this optional classArgs field, for example classArgs: arg1: value1
以上