运行实验
我们解释如何执行 DVC 实验,设置其参数、将它们排队以供将来执行、并行运行实验等细节。
运行实验命令和管道
DVC 依赖包含运行实验命令的 dvc.yaml
文件。这些文件定义了指定一个或多个实验工作流阶段(代码、依赖项、输出等)的管道。
有关此主题的介绍,请参阅入门:使用管道进行实验。
运行管道
您可以使用 dvc exp run
运行实验管道。默认情况下,它使用当前目录下的 ./dvc.yaml
文件。
DVC 会观察各阶段之间的依赖关系图,因此只会运行那些依赖项已更改或输出在缓存中缺失的阶段。您可以通过指定复现目标来限制运行范围,甚至可以只运行单个阶段(使用 --single-item
参数)。
DVC 项目实际上支持一个或多个 dvc.yaml
文件中的多个管道。--all-pipelines
选项允许您一次性运行所有管道。
dvc exp run
是 dvc repro
的实验专用替代命令。详见运行管道以了解两者之间的区别。
实验结果
最近一次 dvc exp run
的结果可以在工作区中看到。这些结果由 DVC 内部存储和跟踪。
要显示并比较多个实验及其参数和指标,请使用 dvc exp show
。dvc plots diff
也接受实验作为 revisions
参数。更多详情请参见查看和比较实验。
若要恢复其他任意实验的结果,请使用 dvc exp apply
。更多信息请参见将实验结果带回工作区。
只有被 Git 或 DVC 跟踪的文件才会被保存到实验中。未跟踪的文件无法恢复。
调整(超)参数
参数是代码中用于调整模型属性或以任何方式影响实验结果的值。例如,随机森林分类器可能需要一个最大深度值。机器学习实验通常涉及定义和搜索超参数空间,以优化最终的模型指标。
您的源代码应从结构化的参数文件(默认为 params.yaml
)中读取参数。通过在 dvc.yaml
中使用 params
字段定义这些文件,以便 DVC 能够追踪它们。当某个参数值发生变化时,dvc exp run
会使其依赖的任何阶段失效并重新执行这些阶段。
更多详情请参见 dvc params
。
您可以手动编辑参数文件,并使用这些参数作为输入运行实验。由于这是常见操作流程,内置选项 dvc exp run --set-param
(-S
)提供了快捷方式。它接收一个已存在的参数名和值,并在执行前动态更新文件。
$ cat params.yaml
...
train:
valid_pct: 0.1
arch: shufflenet_v2_x2_0
img_size: 256
batch_size: 8
fine_tune_args:
epochs: 8
base_lr: 0.01
...
$ dvc exp run --set-param train.fine_tune_args.base_lr=0.001
...
$ dvc exp run -S train.img_size=1024 -S train.batch_size=512 # set multiple params
...
有关通过参数覆盖(修改、追加或删除,或使用“选择”集合和范围)实现更高级配置的选项,请参见 Hydra 组合。
实验队列
dvc exp run
的 --queue
选项指示 DVC 将实验添加到队列中以供稍后执行。此时实际上并未运行任何内容。让我们先将几个实验加入队列:
$ dvc exp run --queue -S train.fine_tune_args.base_lr=0.001
Queueing with overrides '{'params.yaml': ['train.fine_tune_args.base_lr=0.001']}'.
Queued experiment 'blowy-pail' for future execution.
$ dvc exp run --queue -S train.fine_tune_args.base_lr=0.002
Queueing with overrides '{'params.yaml': ['train.fine_tune_args.base_lr=0.002']}'.
Queued experiment 'nubby-gram' for future execution.
或者,我们可以设置一个超参数网格搜索:
$ dvc exp run --queue \
-S train.arch='resnet18,shufflenet_v2_x2_0' \
-S 'train.fine_tune_args.base_lr=range(0.001, 0.01, 0.001)'
Queueing with overrides '{'params.yaml': ['train.arch=resnet18', 'train.fine_tune_args.base_lr=0.001']}'.
Queued experiment 'bijou-chis' for future execution.
Queueing with overrides '{'params.yaml': ['train.arch=resnet18', 'train.fine_tune_args.base_lr=0.002']}'.
Queued experiment 'color-meal' for future execution.
Queueing with overrides '{'params.yaml': ['train.arch=resnet18', 'train.fine_tune_args.base_lr=0.003']}'.
Queued experiment 'fusil-chin' for future execution.
...
Queueing with overrides '{'params.yaml': ['train.arch=shufflenet_v2_x2_0', 'train.fine_tune_args.base_lr=0.001']}'.
Queued experiment 'lumpy-jato' for future execution.
Queueing with overrides '{'params.yaml': ['train.arch=shufflenet_v2_x2_0', 'train.fine_tune_args.base_lr=0.002']}'.
Queued experiment 'gypsy-wino' for future execution.
Queueing with overrides '{'params.yaml': ['train.arch=shufflenet_v2_x2_0', 'train.fine_tune_args.base_lr=0.003']}'.
...
使用 dvc queue start
一次性运行所有实验:
$ dvc queue start
...
大多数情况下,实验任务将按照其加入队列的顺序执行(先进先出),但这并不保证。
实验在临时目录中的独立环境里运行,与您的工作区隔离,因此每个实验都基于其入队时的工作区状态派生而来。
默认情况下,排队的实验是串行处理的,但可以通过指定多个 --jobs
参数(启动多个 dvc queue start
工作进程)来并行运行。
请确保使用的作业数量不超过您的环境可承受的范围(通常不应超过 CPU 核心数)。
请注意,由于排队的实验彼此隔离运行,具体取决于当时运行缓存的状态,某些公共阶段可能会被多次执行。
DVC 会在 .dvc/tmp/exps/
中创建实验原始工作区的副本并在其中运行。不过,所有工作区共享同一个项目缓存。
💡 若要隔离运行任意实验(而不将其加入队列),可以使用 --temp
标志。这允许您在长时间运行实验的同时继续工作,例如:
$ nohup dvc exp run --temp &
[1] 30473
nohup: ignoring input and appending output to 'nohup.out'
请注意,Git 忽略的文件/目录会被排除在排队或临时运行之外,以避免将不需要的文件提交到 Git(例如,在成功实验被持久化时)。若要包含未跟踪的文件,请先用 git add
将其暂存(在 dvc exp run
前),之后再用 git reset
撤销暂存。
要清空实验队列并重新开始,请使用 dvc queue remove --queued
。
对于更复杂的网格搜索,DVC 支持通过 Hydra 组合进行复杂配置。