用实验配置覆盖Hydra配置-额外文件夹层次

1 投票
2 回答
66 浏览
提问于 2025-04-14 16:24

我正在研究这个Hydra文档示例,目的是用实验配置来覆盖主配置。与Hydra的示例不同,我有一个额外的文件夹层级,用来把所有相关的配置放到一个子文件夹里。

conf
├── data
│   ├── cifar100_data
│   │   ├── cifar100_extended.yaml
│   │   └── cifar100.yaml
│   └── default.yaml
├── experiment
│   └── cifar100.yaml
└── training_config.yaml

在我的例子中,我有一个基本的training_config

defaults:
   - data: default

data/default.yaml

# @package data
dataset: mnist
n_classes: 10

还有两个关于cifar100数据的配置文件
cifar100_data/cifar100.yaml

name: cifar100
n_classes: 100

cifar100_data/cifar100_extended.yaml

# @package data
defaults:
  - cifar100
augmentations:
  - rotate

我想用experiment/cifar100来覆盖training_config,也就是说我会运行python my_app.py experiment=cifar100

experiment/cifar100 第一次尝试:

# @package _global_
defaults:
  - override /data/cifar100_data: cifar100_extended

错误信息:

hydra.errors.ConfigCompositionException: 在 'experiment/cifar100' 中:无法覆盖 'data/cifar100_data'。在默认列表中没有匹配项。

experiment/cifar100 第二次尝试:

# @package _global_
defaults:
  - override /data: cifar100_data/cifar100_extended

错误信息:

hydra.errors.MissingConfigException: 在 'data/cifar100_data/cifar100_extended' 中:无法加载 'data/cifar100'。

我该如何正确运行这样一个实验,尤其是相比默认配置多了一个层级?

根据回答的编辑:
我已经调整了cifar100_extended.yaml为:

# @package data
defaults:
  - cifar100_data/cifar100
augmentations:
  - rotate

按照回答中的建议,我成功生成了一个有效的配置。不过,现在我无法直接运行cifar100_extended.yaml,并且收到了以下错误:

hydra.errors.MissingConfigException: In 'cifar100_data/cifar100_extended': Could not load 'cifar100_data/cifar100_data/cifar100'.

2 个回答

0

我通过从 conf/experiment/cifar100.yaml 文件中去掉 override 这个关键词,让你的原始配置正常工作了:

# @package _global_
defaults:
  - /data/cifar100_data: cifar100_extended
$ python test.py +experiment=cifar100
data:
  dataset: mnist
  n_classes: 100
  name: cifar100
  augmentations:
  - rotate

不过,我不太确定这是不是你想要的结果。你是希望将cifar的配置放在 data.cifar100_data 这个包下面吗?如果是这样的话,你可以在 conf/experiment/cifar100.yaml 文件中使用 group@pkg 这种写法:

# @package _global_
defaults:
  - /data/cifar100_data@data.cifar100_data: cifar100_extended
$ python test.py +experiment=cifar100
data:
  dataset: mnist
  n_classes: 10
  cifar100_data:
    name: cifar100
    n_classes: 100
    augmentations:
    - rotate

override 这个关键词在你想要覆盖默认设置中已经存在的内容时很有用。但在这个情况下,实验文件并没有覆盖 data/cifar100_data,因为它在默认设置中并不存在。

0

这有点不寻常。你的数据配置组应该是 data,而不是 /data/cifar100_data,所以第二种形式是正确的:

# @package _global_
defaults:
  - override /data: cifar100_data/cifar100_extended

你遇到的错误是:

hydra.errors.MissingConfigException: In 'data/cifar100_data/cifar100_extended': Could not load 'data/cifar100'.

这个错误告诉你,在尝试加载 data/cifar100_data/cifar100_extended 时,Hydra 试图去找 data/cifar100,但找不到这个文件。实际上,这个文件是在 data/cifar100_data/cifar100 里,而不是在 data/cifar100 里。

这看起来像是一个bug,因为相对配置组的条目应该是相对于包含它的配置的,而 cifar100 就在 cifar100_extended 的旁边。

这个bug和你不寻常的配置组结构有关,因为你用了子目录,这种方式并不是很被支持(通常的期望是每个子目录都是自己的配置组)。

一个解决方法是调整 cifar100_extended.yaml 为:

# @package data
defaults:
  - cifar100_data/cifar100
augmentations:
  - rotate

撰写回答