LoginSignup
65
49

More than 3 years have passed since last update.

argparseからhydraへの移植

Last updated at Posted at 2020-03-28

Pythonのargparseの設定をhydraに変換する際に,調べたことを備忘録的にまとめたものです.
最後にhydraにしかない便利機能を書いています.

はじめに

機械学習の実験スクリプトをpythonで書く際,ハイパーパラメータなどの設定方法として,argparseを使っていました.
しかし,実験が複雑になるにつれて,argparseの設定を記述したファイルだけで,かなりの行数になってしまったり,設定を構造化したいなどの欲が出てきました...
そこで,ymymさんの「ハイパラ管理のすすめ -ハイパーパラメータをHydra+MLflowで管理しよう-」を読み,「これだ!」となったので,使ってみることにしました.
そして,argparseで書いていた実験の設定をhydraに移行する際にいろいろ調べたので,それをまとめてみました.

hydraとは?

image.png

"A framework for elegantly configuring complex applications"
"複雑なアプリケーションの設定をエレガントに管理するためのフレームワーク"らしいです.
facebook researchを中心に開発が行われています.

GitHub / Official Document

hydraの使い方

詳しい設定については,上のymymさんの記事と,公式 Tutorialを参照いただければと思います.
1番の特徴は,yaml fileに設定を構造的に記述して,その内容を上書きしたければ,実行時にコマンドラインで上書きをするという感じです.

各種書き方

オプションの定義と読み込み

  • hydraはyamlファイルに設定を記述して,それを実行する関数にデコレータとして付与する形になります.

argparse

main.py
def main():
    parser = parser.ArgumentParser(...)
    parser.add_argument('--hoge', type=int, default=1)
    cfg = parser.parse_args()
    print(cfg.hoge) # 1

hydra

config.yaml
hoge: 1
main.py
@hydra.main(config_path='config.yaml')
def main(cfg):
    print(cfg.hoge) # 1

defaultを上書き

  • =で指定する
  • keyとvalueの間にスペースは開けない

argparse

shell
$ python main.py --hoge 2

hydra

shell
$ python main.py hoge=1

nargs

  • hydraからparseされてくる設定は,omegaconfで全て記述されているため,単なるlistではないことに注意が必要です.

argparse

main.py
parser.add_argument('--hoge', type=int, nargs=3, default=[1, 2, 3])
shell
$ python main.py --hoge 4 5 6

hydra

config.yaml
hoge:
  - 1
  - 2
  - 3
shell
$ python main.py hoge=[1,2,3]

required=True

  • valueに???を指定する
  • 指定しないで実行すると,OmegaConfのomegaconf.errors.MissingMandatoryValueというエラーが出る.
  • しかし,これは実行時に評価されるわけではなく,keyにアクセスしたタイミングで評価されてエラーが出ます.そのため,指定しないで実行しても,???で指定してkeyにアクセスする行までのコードは実行されてしまいます.(hydra側の設定で実行時に評価させる方法などがあったら教えていただきたいです)

argparse

main.py
parser.add_argument('--hoge', type=int, required=True)

hydra

config.yaml
hoge: ???

choices

  • 特定のkeyに対して,許可する値のリストを指定する,という機能は今のところなさそうです. (将来的に機能追加されるかどうかも怪しいと思います.)
  • 近い機能は,configを構造化することによって,達成できます.
    • 詳しくはここら辺を参照するのが良いと思います.

argparse

main.py
parser.add_argument('--hoge', type=int, default=1, choices=[1, 2])
print(cfg.hoge)
shell
$ python main.py --hoge 2
# 2

hydra

tree
├── config
|   ├── config.yaml
│   └── choice
│       ├── a.yaml
│       └── b.yaml
└── main.py
config.yaml
choice: a
choice/a.yaml
hoge: 1
choice/b.yaml
hoge: 2
main.py
print(cfg.hoge)
shell
$ python main.py choice=b
# 2

--help

argparse

shell
$ python main.py --help

hydra

shell
$ python main.py --cfg job

hydraにしかない便利機能

ほとんどtutorialの紹介になってしまうので,section名に対象のtutorialへのリンクを埋め込みます.
詳細はそちらをご参照ください.

Multi-run

上のchoicesのところで設定したconfigで,複数の設定での同時実行をしてみます.

shell
$ python main.py hoge=a,b

タブ補完

スクリプト実行前に,一度以下のコマンドを実行すると,コマンドラインからオプションを指定する際に,タブ補完を利用できます.

shell
$ eval "$(python main.py -sc install=bash)"

ログディレクトリの作成

hydraは何も設定をしなくても,自動で日付と時間をもとに構造化されたログのディレクトリを作成し,そこを実行時のワーキングディレクトリとして,実行時に生成されたファイルや保存されたファイル等を保存します.

main.py
import os

@hydra.main()
def main(_cfg):
    print("Working directory : {}".format(os.getcwd()))
shell
$ python main.py
Working directory : /home/omry/dev/hydra/outputs/2019-09-25/15-16-17

$ python main.py
Working directory : /home/omry/dev/hydra/outputs/2019-09-25/15-16-19

しかし,勝手にワーキングディレクトリ指定するなや!っていう人もいると思うので(自分),そういう人は,自らhydraにディレクトリを指定するようにしましょう.

まとめ

僕自身使い始めたばかりなので,記事中で間違っている箇所や,もっと良い方法を知っている方などいれば,ご教授いただけますと幸いです.
hydraを使うと,コードがスッキリするので,是非使ってみてください!(特に大規模なコードほど)

最後に,詳しい使い方を知りたい方は,公式documentymymさんブログをご参照ください.

65
49
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
65
49