41
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

argparseからhydraへの移植

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さんブログをご参照ください.

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
41
Help us understand the problem. What are the problem?