こんにちは。今日は研究で使っているHydraでディレクトリの作成の際に、ランダムに生成した実験IDを使うための方法です。
Hydraでは自動で実験の結果をいい感じにディレクトリを切ってくれて出力してくれるのですが、デフォルトの設定では日付/時間
と行った形でディレクトリが切られます。
ただ、実験を多く重ねていくと、あれこの結果っていつの実験だっけ?となることが多々あり、実験の際の設定を探そうにも膨大な数のディレクトリを一つ一つ開けて探すことになるので、実験の管理としてはあまり良くありません。
そこで、今回はPythonのuuid
ライブラリを使用して、ランダムな実験IDを発行し、それをHydraで使う方法についてご説明します。
Hydraの出力ディレクトリをカスタマイズする
まず最初にHydraの出力ディレクトリのカスタマイズ方法について確認していきます。
これは公式ドキュメントにも記載されていますが、スクリプトで使用する.yml
ファイルに以下を追記することで出力ディレクトリをカスタマイズすることができます。
hydra:
run:
dir: ${now:%Y%m%d}T${now:%H%M%S}-${experiment_id}
sweep:
dir: ${now:%Y%m%d}T${now:%H%M%S}-${experiment_id}
subdir: ${hydra.job.num}
experiment_id: "30d3974d"
このように、hydra.run.dir
を指定してあげることで、出力フォルダ名をカスタマイズすることができます。
しかしこの方法では、わざわざ毎回手作業でexperiment_idを発行して、貼り付ける必要があり、面倒ですし、ミスも増えます。
そこでこの部分を自動化したいのですが、調べてもなかなか類似のことを行おうとしている記事が存在せずに困っていました。
hydra.job_id
も使おうと思ったのですが、普通にhydraを実行するとこの値はNoneになってしまうので使えませんでした。
実験IDとしてuuid
を使う
そこで今回はPythonでuuid
を発行し、ディレクトリに使うことを考えます。
やり方は2つあり、
-
ComposeAPI
を使う -
hydra-plugins
を作る
のどちらでも目標を達成することができます。
ただ、ComposeAPI
は古いAPIで使用すると本来のHydraでできることができなくなり、かえって手間が増えることがあります。
なので今回は2の方法で実装していきたいと思います。
といってもやり方は単純で以下の方法で終わりです。
ソースコードが書かれているルートディレクトリに(今回の場合は便宜的にsrc
とします)、hydra-plugins
フォルダを作成して、以下のpythonファイルを作ります。
# src/hydra-plugins/random_id_provide.py
import uuid
from omegaconf import OmegaConf
class IDGenerator:
def __init__(self, digit: int = 8) -> None:
self.digit = digit # 長すぎるので切り捨てる桁数を指定。
def generate(self) -> str:
return str(uuid.uuid4())[: self.digit]
id_generator = IDGenerator()
OmegaConf.register_new_resolver("experiment_id", id_generator.generate)
hydra
で使われているOmegaConf
のregister_new_resolver
に呼び出したい関数を渡すだけです。このようにhydra-plugins
の中に適当なファイルを作成しておくだけで、後はhydraがよしなに読み取ってくれてconfig内で使用することが可能です。
以下のようなディレクトリを考えてみましょう。
hydra:
run:
dir: ${now:%Y%m%d}T${now:%H%M%S}-${experiment_id}
sweep:
dir: ${now:%Y%m%d}T${now:%H%M%S}-${experiment_id}
subdir: ${hydra.job.num}
experiment_id: "${experiment_id:}"
このようにするだけで以下のようにuuidに従って出力用ディレクトリが作成されます!
以上です!