Skip to content
marsggbo edited this page Apr 29, 2022 · 9 revisions
如何基于之前的实验配置重新跑一组实验?

1. 如何基于之前的实验配置重新跑一组实验?

太长不看可以直接跳到 1.3 节

1.1 Hyperbox读取实验配置的逻辑

整个框架的入口是run.py,实验参数配置都是通过@hydra.main函数读取的,如下面代码所示,其中config_path指的是yaml文件的相对路径,注意你需要输入的是相对路径config_name则是文件名。下面的代码的意思就是会自动读取configs/config.yaml得到参数设置。

#run.py
@hydra.main(config_path="configs/", config_name="config.yaml")
def main(config: DictConfig):
    ....

1.2 日志信息

每次跑一组实验后,默认情况下会在 logs/runs路径下生成对应的实验日志信息,比如是logs/runs/2021-07-21/22-52-36,这个文件夹的结构如下:

logs/runs/2021-07-21/22-52-36
|_.hdyra
  |_config.yaml
  |_hydra.yaml
  |_overrides.yaml

overrides.yaml记录了之前实验从命令行输入的命令,config.yaml包含了之前实验的所有配置信息,当然也包含了overrides.yaml,所以你需要重新读取config.yaml即可。

1.3 重新读取配置

方法很简单,你只需要修改--config-path即可,假设你之前跑的实验数据存储路径是./logs/runs/2021-07-21/22-52-36/.hydra,那么要重复跑这个实验的命令如下(当然你也可以在后面继续添加新的需要override的参数)

python run.py --config-path=logs/runs/2021-07-21/22-52-36/.hydra datamodule.batch_size=128

注意带--的参数一定要放在前面,因为它们是hydra库自带的参数,在解析参数时需要优先解析这些参数。

另外需要注意的是上述方法hydra只会默认读取logs/runs/2021-07-21/22-52-36/.hydra路径下的config.yaml文件,而overrides.yamlhydra.yaml文件是不会读取的:

    1. 一是因为overrides.yaml文件内的内容其实已经保存在config.yaml里了,所以没必要再读取了
    1. 需要注意的问题是hydra.yaml文件里的设置会被忽略掉,所以如果你之前实验设置了hydra相关的参数,假如你之前设置了实验数据存储路径,hydra.yaml部分相应设置会保存如下
#hydra.yaml
hydra:
    run:
        dir: logs/runs/${hydra.job.name}/${now:%Y-%m-%d_%H-%M-%S}

但是实际在跑的时候存储路径会变成hydra的默认路径outputs/%Y-%m-%d/%H-%M-%S,如果你想还是按照你指定的存储路径,你需要手动把上面那部分代码拷贝到config.yaml文件里。

如果要传入的参数中含有`=`该怎么办?

2. 如果要传入的参数中含有=该怎么办?

参考: https://github.com/facebookresearch/hydra/issues/938

Hyperbox框架支持命令行修改参数配置,命令是 arg=value,其中arg就是某一个具体的变量名,例如 datamodule.batch_size,value就是具体的值。 可以看到是通过使用等于符号,即=完成赋值操作的,但是有的时候我们的value里可能也会含有=,这个时候该怎么办呢?方法很简单,我们用一个例子来演示:

假设我们想基于之前的一个checkpoint重新跑一遍代码,路径是./logs/run/20210606/checkpoints/epoch=66/acc=66.66.ckpt,命令如下:

python run.py "trainer.resume_from_checkpoint='./logs/run/20210606/checkpoints/epoch=66/acc=66.66.ckpt'"
`trainer.resume_from_checkpoint`和`model.load_from_checkpoint`有什么区别?

3. trainer.resume_from_checkpointmodel.load_from_checkpoint有什么区别?

model.load_from_checkpoint只会load模型权重, trainer.resume_from_checkpoint会resume上一次实验的所有配置,包括模型权重,优化器状态,scheduler状态等

如果要传入的参数中含有`=`该怎么办?

5. 如果要传入的参数中含有=该怎么办?

参考: https://github.com/facebookresearch/hydra/issues/938

Hyperbox框架支持命令行修改参数配置,命令是 arg=value,其中arg就是某一个具体的变量名,例如 datamodule.batch_size,value就是具体的值。 可以看到是通过使用等于符号,即=完成赋值操作的,但是有的时候我们的value里可能也会含有=,这个时候该怎么办呢?方法很简单,我们用一个例子来演示:

假设我们想基于之前的一个checkpoint重新跑一遍代码,路径是./logs/run/20210606/checkpoints/epoch=66/acc=66.66.ckpt,命令如下:

python run.py "trainer.resume_from_checkpoint='./logs/run/20210606/checkpoints/epoch=66/acc=66.66.ckpt'"
`trainer.resume_from_checkpoint`和`model.load_from_checkpoint`有什么区别?

6. trainer.resume_from_checkpointmodel.load_from_checkpoint有什么区别?

model.load_from_checkpoint只会load模型权重, trainer.resume_from_checkpoint会resume上一次实验的所有配置,包括模型权重,优化器状态,scheduler状态等

`LightningModule.log`中的`on_step`,`on_epoch`和`sync_dist`区别是什么?

7. LightningModule.log中的on_step,on_epochsync_dist区别是什么?

参考:

嵌套override配置

8. 嵌套override配置

假如example_darts.yaml原本设置如下:

defaults:
  - override /model: random_model.yaml

可以看到我们通过 - override /命令将model设置成了random_model.yaml文件中指定的配置。在Hyperbox中,model包含了多个模块,如network_cfg,mutator_cfg等,他们都可以由一个yaml文件来指定。

如果我们想在example_darts.yaml中修改model.network_cfg,方式如下:

defaults:
  - override /model: random_model.yaml
  - override /model/network_cfg: resnet.yaml

所以可以看出/是用来指定yaml文件的,如果我们只是想修改某一个属性的值,比如network最后的类别数量,方式如下

defaults:
  - override /model: random_model.yaml
  - override /model/network_cfg: resnet.yaml
model:
  network_cfg:
    num_classes: 10