0

假设目录结构如下:

/input/files/path
  /input1
    /file1_1.json
    /file1_2.json
  /input2
    /file2_1.json
  /someting_unrelated
  ...

我想多次运行使用 Hydra 配置的脚本,每次都获取其中一个input*文件夹的完整路径。

这怎么可能实现?

4

2 回答 2

1

以下是我能想到的两种方法:

方法 1:使用 shell 实用程序将*.json文件名列表传递给您的应用程序

您可以使用外部实用程序(例如 GNUfindpaste)来创建*.json您想要使用的文件的逗号分隔列表。

$ find input -name '*.json' | paste -sd "," -
input/files/path/input1/file1_1.json,input/files/path/input1/file1_2.json,input/files/path/input2/file2_1.json

然后,您可以将这些文件路径传递给您的应用程序以执行多运行扫描

$ python my_app.py --multirun file_path="$(find input -name '*.json' | paste -sd ',' -)"
[2021-10-29 12:53:37,059][HYDRA] Launching 3 jobs locally
[2021-10-29 12:53:37,059][HYDRA]        #0 : file_path=input/files/path/input1/file1_1.json
{'file_path': 'input/files/path/input1/file1_1.json'}
[2021-10-29 12:53:37,136][HYDRA]        #1 : file_path=input/files/path/input1/file1_2.json
{'file_path': 'input/files/path/input1/file1_2.json'}
[2021-10-29 12:53:37,219][HYDRA]        #2 : file_path=input/files/path/input2/file2_1.json
{'file_path': 'input/files/path/input2/file2_1.json'}

.json 文件的文件路径可通过file_path应用程序配置中的键用于应用程序的主要功能。

以下是我用来生成上述输出的my_app.py和文件:config.yaml

# my_app.py
import hydra

@hydra.main(config_path=".", config_name="config")
def main(cfg):
    print(cfg)

if __name__ == "__main__":
    main()
# config.yaml
file_path: ???

.json方法2:注册配置组中文件的路径

  • 第 1 步:使用 python 代码生成.json您感兴趣的文件的路径列表。
  • 第 2 步:使用Config Store API注册包含每个文件路径的输入配置。
  • 第 3 步:在命令行中,使用glob 选择扫描扫描在第 2 步中注册的所有输入配置。

详细地:

# my_app.py
import os
import hydra

# Step 1: Use os.walk to make a list of paths to .json files
json_filepaths = []
for dirpath, dirnames, filenames in os.walk("input"):
    for filename in filenames:
        if filename.endswith(".json"):
            json_filepaths.append(f"{dirpath}/{filename}")

# Step 2: For each .json file path, register an input config
cs = hydra.core.config_store.ConfigStore.instance()
for fpath in json_filepaths:
    cs.store(
        name=fpath.replace("/", "-"),  # the names must be unique for each fpath and must not contain a forward slash
        node={"file_path": fpath},
        group="json_input",
    )

@hydra.main(config_path=".", config_name="config")
def main(cfg):
    print(cfg)

if __name__ == "__main__":
    main()
# config.yaml
defaults:
  - json_input: ???
$ # Step 3: Doing a --multirun sweep over the `json_input` group:
$ p3 my_app.py --multirun 'json_input=glob(*)'
[2021-10-29 21:14:28,643][HYDRA] Launching 3 jobs locally
[2021-10-29 21:14:28,643][HYDRA]        #0 : json_input=input-files-path-input1-file1_1.json
{'json_input': {'file_path': 'input/files/path/input1/file1_1.json'}}
[2021-10-29 21:14:28,726][HYDRA]        #1 : json_input=input-files-path-input1-file1_2.json
{'json_input': {'file_path': 'input/files/path/input1/file1_2.json'}}
[2021-10-29 21:14:28,817][HYDRA]        #2 : json_input=input-files-path-input2-file2_1.json
{'json_input': {'file_path': 'input/files/path/input2/file2_1.json'}}

.json 文件的文件路径可通过json_input.file_path应用程序配置中的键用于应用程序的主要功能。

于 2021-10-30T02:15:53.713 回答
1

Hydra 不支持 json。使用 yaml 文件。

至于 glob 上的 multirun,请参阅覆盖语法页面中的glob 。

例如:

python foo.py 'config/group=glob(input*)'

请注意,根据您的 shell 行为,可能需要引用。

您的问题不清楚的一件事是您的配置文件是否在配置搜索路径中。如果不是,您必须将他们的目录添加到搜索路径。有关更多信息,请参阅搜索路径。

于 2021-12-16T06:43:47.763 回答