AutoML : NNI 1.5 : 自動調整 : チューナー : ネットワーク Morphism (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 05/28/2020 (1.6.0)
* 本ページは、NNI の以下のドキュメントを翻訳した上で適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
自動調整 : チューナー : ネットワーク Morphism
1. イントロダクション
Autokeras はネットワーク Morphism を利用するポピュラーな autoML ツールです。Autokeras の基本的なアイデアはニューラルネットワーク・アーキテクチャのメトリックを推定するために Bayesian 回帰を利用することです。毎回、それは father ネットワークから幾つかの child ネットワークを生成します。それからそれはネットワークの訓練結果の履歴からメトリック値とメトリック値ペアを推定するために naive Bayesian 回帰を利用します。次に、それは最善の、推定されたパフォーマンスを持つ child を選択してそれを訓練キューに追加します。Autokeras のワークにインスパイアされてその コード を参照し、私達は NNI プラットフォームでネットワーク Morphism 法を実装しました。
ネットワーク morphism トライアル使用方法についてより多く知ることを望むのであれば、Readme.md を見てください。
2. 使用方法
ネットワーク Morphism を使用するには、config.yml ファイルで以下の spec を変更するべきです :
tuner:
#choice: NetworkMorphism
builtinTunerName: NetworkMorphism
classArgs:
#choice: maximize, minimize
optimize_mode: maximize
#for now, this tuner only supports cv domain
task: cv
#modify to fit your input image width
input_width: 32
#modify to fit your input image channel
input_channel: 3
#modify to fit your number of classes
n_output_node: 10
訓練手続きでは、それはネットワークグラフを表す JSON ファイルを生成します。ユーザはこの JSON ファイルから PyTorch or Keras モデルを構築するために “json_to_graph()” 関数を呼び出すことができます。
import nni
from nni.networkmorphism_tuner.graph import json_to_graph
def build_graph_from_json(ir_model_json):
"""build a pytorch model from json representation
"""
graph = json_to_graph(ir_model_json)
model = graph.produce_torch_model()
return model
# trial get next parameter from network morphism tuner
RCV_CONFIG = nni.get_next_parameter()
# call the function to build pytorch model or keras model
net = build_graph_from_json(RCV_CONFIG)
# training procedure
# ....
# report the final accuracy to NNI
nni.report_final_result(best_acc)
最善のモデルをセーブしてロードすることを望む場合、以下のメソッドが勧められます。
# 1. Use NNI API
## You can get the best model ID from WebUI
## or `nni/experiments/experiment_id/log/model_path/best_model.txt'
## read the json string from model file and load it with NNI API
with open("best-model.json") as json_file:
json_of_model = json_file.read()
model = build_graph_from_json(json_of_model)
# 2. Use Framework API (Related to Framework)
## 2.1 Keras API
## Save the model with Keras API in the trial code
## it's better to save model with id in nni local mode
model_id = nni.get_sequence_id()
## serialize model to JSON
model_json = model.to_json()
with open("model-{}.json".format(model_id), "w") as json_file:
json_file.write(model_json)
## serialize weights to HDF5
model.save_weights("model-{}.h5".format(model_id))
## Load the model with Keras API if you want to reuse the model
## load json and create model
model_id = "" # id of the model you want to reuse
with open('model-{}.json'.format(model_id), 'r') as json_file:
loaded_model_json = json_file.read()
loaded_model = model_from_json(loaded_model_json)
## load weights into new model
loaded_model.load_weights("model-{}.h5".format(model_id))
## 2.2 PyTorch API
## Save the model with PyTorch API in the trial code
model_id = nni.get_sequence_id()
torch.save(model, "model-{}.pt".format(model_id))
## Load the model with PyTorch API if you want to reuse the model
model_id = "" # id of the model you want to reuse
loaded_model = torch.load("model-{}.pt".format(model_id))
3. ファイル構造
チューナーは多くの様々なファイル、関数とクラスを持ちます。ここで、それらのファイルの多くに簡潔な紹介だけ与えます :
- networkmorphism_tuner.py はネットワーク morphism テクニックを使用するチューナーです。
- bayesian.py は既に探求したモデルに基づいて未知のモデルのメトリックを推定するための Bayesian 法です。
- graph.py はメタグラフ・データ構造です。クラス Graph はモデルのニューラル・アーキテクチャ・グラフを表します。
- グラフはモデルからニューラル・アーキテクチャ・グラフを抽出します。
- グラフの各ノードは層間の中間 tensor です。
- 各層はグラフのエッジです。
- 特に、マルチエッジは同じ層を参照するかもしれません。
- graph_transformer.py は幾つかのグラフ変換を含みます、これはグラフを拡大し、深くし、あるいはスキップ接続を追加します。
- layers.py はモデルで使用する総ての層を含みます。
- layer_transformer.py は幾つかの層変換を含みます、これは層を拡大し、深くし、あるいはスキップ接続を追加します。
- nn.py は初期ネットワークを生成するクラスを含みます。
- metric.py Accuracy と MSE を含む幾つかのメトリッククラス。
- utils.py は Keras を使用する、cifar10 データセットのためのサンプル探索ネットワーク・アーキテクチャです。
4. ネットワーク表現 Json サンプル
ここに私達が定義した中間表現 JSON ファイルのサンプルがあります、これはアーキテクチャ探索手続きでチューナーからトライアルに渡されます。ユーザはこの JSON ファイルから PyTorch か Keras モデルを構築するためにトライアルコードで “json_to_graph()” 関数を呼び出すことができます。
{
"input_shape": [32, 32, 3],
"weighted": false,
"operation_history": [],
"layer_id_to_input_node_ids": {"0": [0],"1": [1],"2": [2],"3": [3],"4": [4],"5": [5],"6": [6],"7": [7],"8": [8],"9": [9],"10": [10],"11": [11],"12": [12],"13": [13],"14": [14],"15": [15],"16": [16]
},
"layer_id_to_output_node_ids": {"0": [1],"1": [2],"2": [3],"3": [4],"4": [5],"5": [6],"6": [7],"7": [8],"8": [9],"9": [10],"10": [11],"11": [12],"12": [13],"13": [14],"14": [15],"15": [16],"16": [17]
},
"adj_list": {
"0": [[1, 0]],
"1": [[2, 1]],
"2": [[3, 2]],
"3": [[4, 3]],
"4": [[5, 4]],
"5": [[6, 5]],
"6": [[7, 6]],
"7": [[8, 7]],
"8": [[9, 8]],
"9": [[10, 9]],
"10": [[11, 10]],
"11": [[12, 11]],
"12": [[13, 12]],
"13": [[14, 13]],
"14": [[15, 14]],
"15": [[16, 15]],
"16": [[17, 16]],
"17": []
},
"reverse_adj_list": {
"0": [],
"1": [[0, 0]],
"2": [[1, 1]],
"3": [[2, 2]],
"4": [[3, 3]],
"5": [[4, 4]],
"6": [[5, 5]],
"7": [[6, 6]],
"8": [[7, 7]],
"9": [[8, 8]],
"10": [[9, 9]],
"11": [[10, 10]],
"12": [[11, 11]],
"13": [[12, 12]],
"14": [[13, 13]],
"15": [[14, 14]],
"16": [[15, 15]],
"17": [[16, 16]]
},
"node_list": [
[0, [32, 32, 3]],
[1, [32, 32, 3]],
[2, [32, 32, 64]],
[3, [32, 32, 64]],
[4, [16, 16, 64]],
[5, [16, 16, 64]],
[6, [16, 16, 64]],
[7, [16, 16, 64]],
[8, [8, 8, 64]],
[9, [8, 8, 64]],
[10, [8, 8, 64]],
[11, [8, 8, 64]],
[12, [4, 4, 64]],
[13, [64]],
[14, [64]],
[15, [64]],
[16, [64]],
[17, [10]]
],
"layer_list": [
[0, ["StubReLU", 0, 1]],
[1, ["StubConv2d", 1, 2, 3, 64, 3]],
[2, ["StubBatchNormalization2d", 2, 3, 64]],
[3, ["StubPooling2d", 3, 4, 2, 2, 0]],
[4, ["StubReLU", 4, 5]],
[5, ["StubConv2d", 5, 6, 64, 64, 3]],
[6, ["StubBatchNormalization2d", 6, 7, 64]],
[7, ["StubPooling2d", 7, 8, 2, 2, 0]],
[8, ["StubReLU", 8, 9]],
[9, ["StubConv2d", 9, 10, 64, 64, 3]],
[10, ["StubBatchNormalization2d", 10, 11, 64]],
[11, ["StubPooling2d", 11, 12, 2, 2, 0]],
[12, ["StubGlobalPooling2d", 12, 13]],
[13, ["StubDropout2d", 13, 14, 0.25]],
[14, ["StubDense", 14, 15, 64, 64]],
[15, ["StubReLU", 15, 16]],
[16, ["StubDense", 16, 17, 64, 10]]
]
}
モデルを 有向非巡回グラフ として考えることができます。各モデルの定義は JSON オブジェクトです、そこでは :
(訳注: 定義の詳細は 原文 参照)
5. TODO
次のステップで、API を固定ネットワーク generator からより多くの利用可能な演算子を持つネットワーク generator に変更します。将来的に中間表現 spec として JSON の代わりに ONNX を後で使用します。
以上