參考與前言
主要是介紹python hydra庫如何使用,如果不知道這是什么,簡單介紹:
Hydra 是一個開源 Python 框架,可簡化研究和其他復雜應用程序的開發。
關鍵特性是能夠通過組合動態創建分層配置,並通過配置文件和命令行覆蓋它。 Hydra 這個名字來源於它能夠運行多個類似的工作——就像一個有多個頭的 Hydra。
簡單來講,就是管理yaml config配置文件的,更方便一點的,雖然也可以yaml.load()
,但是這個就是遇到了和沒遇到一些工具的區別,比如 tensorboard 和wandb 之類的 wandb真的是香,主要是yaml我也沒咋用,近來覺得應該要更為規范些了 所以看了看就先學到了hydra,yaml.load對於小的網絡和測試應該綽綽有余了
- 官方文檔:https://hydra.cc/docs/intro/
- towards上英文教程:Complete tutorial on how to use Hydra in Machine Learning projects
- 配合使用OmegaConf:https://omegaconf.readthedocs.io/en/latest/index.html
1. 簡單介紹
安裝
pip install hydra-core
注意其版本和python對應關系:
Version | Release notes | Python Versions | |
---|---|---|---|
► | 1.1 (Stable) | Release notes | 3.6 - 3.9 |
1.0 | Release notes | 3.6 - 3.8 | |
0.11 | Release notes | 2.7, 3.5 - 3.8 |
初步測試
假設代碼位置和配置文件位置如下:
folder
├── config
│ └── config.yaml
└── main.py
其中main.py如下:
import hydra
from omegaconf import DictConfig, OmegaConf
from pathlib import Path
@hydra.main(config_path="config", config_name="config")
def main(config):
running_dir = str(hydra.utils.get_original_cwd())
working_dir = str(Path.cwd())
print(f"The current running directory is {running_dir}")
print(f"The current working directory is {working_dir}")
# To access elements of the config
print(f"The batch size is {config.batch_size}")
print(f"The learning rate is {config['lr']}")
if __name__ == "__main__":
main()
config.yaml為:
### config/config.yaml
batch_size: 10
lr: 1e-4
結果為:
The current running directory is C:\Users\xx\xx\xx\folder\
The current working directory is C:\Users\xx\xx\xx\folder\outputs\2021-12-26\22-47-06
The batch size is 10
The learning rate is 0.0001
首先從這里我們可以看到hydra運行時,會自動建立一個輸出文件夾,包含日期和時間信息,然后還會直接將路徑調到里面去,以方便保存腳本內的各種東西。這就是初步測試,全部都在這一行:配置的路徑在"config",配置的文件名為"config"
@hydra.main(config_path="config", config_name="config")
2. 詳細使用
套娃使用法
此處主要就是套娃使用,假設我們的conf文件這么復雜:
├───conf
│ │ evaluate.yaml
│ │ preprocess.yaml
│ │ train.yaml
│ │
│ ├───data
│ │ vectornet_train.yaml
│ │ vectornet_val.yaml
│ │
│ ├───hparams
│ │ vectornet_baseline.yaml
│ │
│ ├───model
│ │ vectornet.yaml
│ │
│ └───status
│ debug.yaml
│ train.yaml
其中主conf文件夾下有三個yaml文件,train.yaml如下:
resume:
save_dir: models/
log_dir: ${name}/
defaults:
- data: vectornet_train
- model: vectornet
- hparams: vectornet_baseline
- status: train
前面三個變量均為直接獲取的值,后面defaults里就是套娃的,比如第一個data就是跳入data文件夾下讀取vectornet_train文件名的yaml,其余的同理,讀進來的變量直接做為config的字典里的成員... 我也不知道咋個描述法,就是config也是自定義的格式為DictConfig,然后defaults下來讀到的都直接做為其Dict,這是因為在其yaml下聲明了global,示例如下圖:

對於每一個Yaml文件開頭的一行,定義了這個packages內的配置變量性質,下面摘自官方文檔:
PACKAGE : _global_ | COMPONENT[.COMPONENT]*
COMPONENT : _group_ | _name_ | \w+
_global_ : the top level package (equivalent to the empty string).
_group_ : the config group in dot notation: foo/bar/zoo.yaml -> foo.bar
_name_ : the config file name: foo/bar/zoo.yaml -> zoo
直接的使用方式為,在yaml開頭選擇性添加其中一行:
# @package _global_
# @package _group_
# @package _group_._name_
# @package foo.bar
# @package foo._group_._name_
在最新的 Hydra 1.1 默認配置為 _group_
參數搭配運行
也就是說在你運行文件時,如果給出多個config內參數當做輸入參數,即此腳本會自動運行多次,比如:
❯ python main.py lr=1e-3,1e-2 wd=1e-4,1e-2 -m
[2021-03-15 04:18:57,882][HYDRA] Launching 4 jobs locally
[2021-03-15 04:18:57,882][HYDRA] #0 : lr=0.001 wd=0.0001
[2021-03-15 04:18:58,016][HYDRA] #1 : lr=0.001 wd=0.01
[2021-03-15 04:18:58,149][HYDRA] #2 : lr=0.01 wd=0.0001
[2021-03-15 04:18:58,275][HYDRA] #3 : lr=0.01 wd=0.01
❯ python my_app.py -m db=mysql,postgresql schema=warehouse,support,school
[2021-01-20 17:25:03,317][HYDRA] Launching 6 jobs locally
[2021-01-20 17:25:03,318][HYDRA] #0 : db=mysql schema=warehouse
[2021-01-20 17:25:03,458][HYDRA] #1 : db=mysql schema=support
[2021-01-20 17:25:03,602][HYDRA] #2 : db=mysql schema=school
[2021-01-20 17:25:03,755][HYDRA] #3 : db=postgresql schema=warehouse
[2021-01-20 17:25:03,895][HYDRA] #4 : db=postgresql schema=support
[2021-01-20 17:25:04,040][HYDRA] #5 : db=postgresql schema=school
OmegaConf
這個部分主要是to_yaml到無結構的 直接是文本信息 str類型了,通過換行符來分隔
config = OmegaConf.to_yaml(config, resolve=True)
# initialize training config
config = OmegaConf.create(config)
config.local_rank = rank
config.cwd = working_dir
# prevent access to non-existing keys
OmegaConf.set_struct(config, True)
然后再通過create又create回來,順便往里面添加兩個屬性再結構化
3. 更多探索
見官方文檔 emmm 因為我也是閱讀CJ哥的代碼 看起來很好用,順手寫一下中文版記錄好了
大概已知有:config可以重覆蓋,