機械学習モデルの実験管理でHydraを使ってみて便利に感じた点を紹介する。
細かい使い方は他に良い記事がたくさんあるのでそちらを参照。
1. デコレータ一つでyamlをスムーズに読み込める
model:
activation: relu
optimizer:
type: Adam
learning_rate: 0.01
@hydra.main(config_path="conf", config_name="config")
def main(config):
print("optimizer type: ", config.optimizer.type)
print("optimizer type: ", config["optimizer"]["type"])
デコレータの中でconfigファイルのパスを指定すると、その内容がOmegaConfのオブジェクトとして関数に渡される。config
の中身にはドットでアクセスすることができる(もちろん、通常の辞書のような形でのアクセスも可能)。
2. コマンドラインから簡単に設定値を変更できる
python main.py optimizer.type=momentum
このような形でコマンドライン上でyamlの設定値を書き換えて実行することができる。
また、複数の設定値で実験を回したいときは-m
オプションをつけることでmultirunが実行され、与えた全ての組み合わせに対して処理が行われる。
python main.py -m optimizer.learning_rate=0.05,0.1
3. yaml上で補完機能が使える
model:
middle_layer_1: 20
middle_layer_2: ${model.middle_layer_1}
OmegaConfのinterpolation機能によって、yaml上で変数を利用するような書き方ができる。
4. yamlを構造化して管理できる
defaults:
- model: nn
optimizer:
type: Adam
learning_rate: 0.01
activation: relu
これをHydraで読み込むと、以下のようなyamlとして読み込まれる。
model:
activation: relu
optimizer:
type: Adam
learning_rate: 0.01
この機能により、設定を分割化し、構造的に管理できる。ただし、あまり多くファイルを分割しすぎると逆に管理が面倒になるのでほどほどに。
5. 実行ごとに自動的に出力用のディレクトリが生成される
実行ごとに、自動的に以下にようなディレクトリ構成でファイルが出力される(multirunの場合はmultirun
ディレクトリが生成される)。
outputs
└─2023-01-01
└─12-00-00
├─.hydra
│ ├─config.yaml
│ ├─hydra.yaml
│ └─overrides.yaml
└─main.log
それぞれのファイルの内容は以下の通り。
-
config.yaml
:実際に読み込まれたconfig(コマンドラインに与えた設定値で上書きされている) -
hydra.yaml
:Hydraの実行時の設定 -
overrides.yaml
:コマンドラインから上書きされた設定値 -
main.log
:実行時に出力したlog
これにより、実験の設定をタイムスタンプとともに保存しておくことができる。
また、main()
内ではワーキングディレクトリが自動的にoutput/2023-01-01/12-00-00/
に書き換わる。これにより、関数内で出力したファイルも自動的に同フォルダ内に保存される。
この機能は便利だが、ハマりポイントでもあるので注意。例えば相対パスでファイルを読み込む際、想定通り読み込めないというのはありがち。また、MLflowと併用する際にもmlruns
がこのディレクトリ内に生成されてしまうため適切に設定を書き換える必要がある。