Skip to content

命令行使用说明

Aryalfrat edited this page Nov 16, 2022 · 6 revisions

English | 简体中文

以下所有命令前面都加入了$(它也是普通用户下Linux提示符),在实际向控制台输入命令时,$不需要一起输入。

1 准备外部数据

本系统对外部数据有以下要求:

1.标注为VOC格式

  1. 所有图片(本系统中统称为assets或medias)的路径需要统一写入index.tsv文件,同时,所有标注文件都需要位于同一个目录中;

  2. 运行命令行的用户需要index.tsv,所有图片文件和所有标注文件的读权限。

我们以 pascal 2017 test 数据集为例,描述一下外部数据集的准备过程。 在官网下载数据集VOC2012test.tar,使用以下命令解压:

$ tar -xvf VOC2012test.tar

解压以后,可以得到以下目录结构(假设VOCdevkit位于/data目录下):

/data/VOCdevkit
`-- VOC2012
    |-- Annotations
    |-- ImageSets
    |   |-- Action
    |   |-- Layout
    |   |-- Main
    |   `-- Segmentation
    `-- JPEGImages

其中,所有标注都位于annotations目录,而所有图片都位于JPEGImages目录。 使用下述命令生成index.tsv文件:

$ find /data/VOCdevkit/VOC2012/JPEGImages -type f > index.tsv

可以看到index.tsv中有如下内容:

/data/VOCdevkit/VOC2012/JPEGImages/2009_001200.jpg
/data/VOCdevkit/VOC2012/JPEGImages/2009_004006.jpg
/data/VOCdevkit/VOC2012/JPEGImages/2008_006022.jpg
/data/VOCdevkit/VOC2012/JPEGImages/2008_006931.jpg
/data/VOCdevkit/VOC2012/JPEGImages/2009_003016.jpg
...

这个index.tsv可用于下一步的数据导入。

另外,在Annotations文件夹中,每个标注都拥有和图片相同的主文件名。其中的xxx属性将被提取成为预定义关键字,被用于后面一步的数据筛选。

2 建立本地repo并导入数据

本系统的命令行采用和 git 类似的做法对用户的资源进行管理,用户建立自己的 mir repository,并在此 mir repo 中完成接下来的所有任务。

想要建立自己的 mir repo,用户只需要:

$ mkdir ~/mir-demo-repo && cd ~/mir-demo-repo # 建立目录并进入
$ mir init # 将此目录初始化成一个mir repo
$ mkdir ~/ymir-assets ~/ymir-models # 建立资源和模型存储目录,所有的图像资源都会保存在此目录中,而在mir repo中只会保留对这些资源的引用

mir repo 中的标签通过标签文件进行统一管理,打开标签文件 ~/mir-demo-repo/.mir/labels.yaml,可以看到类似以下内容:

labels:
- create_time: 1646728410.570311
  id: 0
  update_time: 1646728410.570311
  name: frisbee
- create_time: 1646728410.570311
  id: 1
  update_time: 1646728410.570311
  name: car

可以添加自己的标签,就像下面这样:

labels:
- create_time: 1646728410.570311
  id: 0
  update_time: 1646728410.570311
  name: frisbee
- create_time: 1646728410.570311
  id: 1
  update_time: 1646728410.570311
  name: car
- create_time: 1646728410.570311
  id: 2
  update_time: 1646728410.570311
  name: tv

一个类别标签可以指定一个或多个别名,例如,如果指定 television 和 tv_monitor 作为 tv 的别名,则 labels.yaml 文件可更改为:

- create_time: 1646728410.570311
  id: 0
  update_time: 1646728410.570311
  name: frisbee
- create_time: 1646728410.570311
  id: 1
  update_time: 1646728410.570311
  name: car
- create_time: 1646728410.570311
  id: 2
  update_time: 1646728410.570311
  name: tv
  aliases:
  - television
  - tv_monitor

可以使用vi,或其他的编辑工具对此文件进行编辑,用户可以添加类别的别名,也可以增加新的类别,但不建议更改或删除已经有的类别的主名和id。

labels.yaml 文件可以通过建立软链接的方式,在多个 mir repo 之间共享。

用户需要事先准备三个数据集:

  1. 训练集 dataset-training,带标注,用于初始模型的训练;

  2. 验证集 dataset-val,带标注,用于训练过程中模型的验证;

  3. 挖掘集 dataset-mining,这是一个比较大的待挖掘的数据集。

用户通过下述命令导入这三个数据集:

$ cd ~/mir-demo-repo
$ mir import --index-file /path/to/training-dataset-index.tsv \ # 数据集index.tsv路径
             --gt-dir /path/to/training-dataset-annotation-dir \ # 标注路径
             --gen-dir ~/ymir-assets \ # 资源存储路径
             --unknown-types-strategy stop \ # 未知类别处理策略,可以从 stop, ignore, add 中选择
             --anno-type det-box \ # 标注类别,可以从 det-box, seg-poly, seg-mask 中选择
             --dst-rev 'dataset-training@import' # 结果分支及操作任务名称
$ mir checkout master
$ mir import --index-file /path/to/val-dataset-index.tsv \
             --gt-dir /path/to/val-dataset-annotation-dir \
             --gen-dir ~/ymir-assets \
             --unknown-types-strategy stop \
             --anno-type det-box \
             --dst-rev 'dataset-val@import'
$ mir checkout master
$ mir import --index-file /path/to/mining-dataset-index.tsv \
             --gt-dir /path/to/mining-dataset-annotation-dir \
             --gen-dir ~/ymir-assets \
             --unknown-types-strategy stop \
             --anno-type det-box \
             --dst-rev 'dataset-mining@import'
  • 注:将可选参数 --gt-dir 指向 ground truth 目录,并将可选参数 --pred-dir 指向 prediction 目录,可以将 prediction 和 ground truth 结果导入同一个数据集。

任务全部执行成功以后,可以通过以下命令:

$ git branch

查看当前 mir repo 的分支情况,现在用户应该可以看到此 repo 有四个分支:master, dataset-training, dataset-val, dataset-mining,并且当前 repo 位于分支dataset-mining上。

用户也可以通过以下命令查看任何一个分支的摘要信息:

$ mir show --src-rev dataset-mining

3 合并及筛选

训练模型需要训练集和验证集,通过以下命令将 dataset-training 和 dataset-val 合成一个:

$ mir merge --src-revs tr:dataset-training@import;va:dataset-val@import \ # 待合并分支
            --dst-rev tr-va@merged \ # 结果分支及操作任务名称
            -s host # 策略:依据主体分支解决冲突

合并完成后,可以看到当前 repo 位于 tr-va 分支下,可以使用 mir show 命令查看合并以后的分支状态:

$ mir show --src-revs HEAD # HEAD指代当前分支,也可以用tr-va这个具体的分支名称代替

假设合并之前的 dataset-training 和 dataset-val 分别有2000和1510张图像,合并后的分支中有2000张图像作为训练集,1510张图像作为验证集。 假设我们只想训练识别人和猫的模型,我们首先从这个大数据集里面筛选出现人或猫的资源:

$ mir filter --src-revs tr-va@merged \
             --dst-rev tr-va@filtered \
             -p 'person;cat'

4 训练第一个模型

首先从 dockerhub 上拉取训练镜像和挖掘镜像:

$ docker pull youdaoyzbx/ymir-executor:ymir1.3.0-yolov5-cu111-tmi

并使用以下命令开始训练过程:

$ mir train -w /tmp/ymir/training/train-0 \
            --media-location ~/ymir-assets \ # import时的资源存储路径
            --model-location ~/ymir-models \ # 训练完成后的模型存储路径
            --task-config-file ~/training-config.yaml \ # 训练参数配置文件,到训练镜像中获取
            --src-revs tr-va@filtered \
            --dst-rev training-0@trained \
            --executor youdaoyzbx/ymir-executor:ymir1.3.0-yolov5-cu111-tmi # 训练镜像

模型训练完成后,系统会输出模型id,用户可以在~/ymir-models中看到本次训练好的模型打包文件。

在模型的训练过程中,训练镜像会产生多个中间模型,这些中间模型的名称会在训练完成时显示,YMIR 最终记录的,是本次训练过程中产生的所有中间模型的集合。

5 挖掘

上述模型是基于一个小批量数据集训练得到的,通过挖掘,可以从一个大数据集中得到对于下一步训练模型最为有效的资源。 用户使用下述命令完成挖掘过程:

$ mir mining --src-revs dataset-mining@import \ # 导入的挖掘分支
             --dst-rev mining-0@mining \ # 挖掘的结果分支
             -w /tmp/ymir/mining/mining-0 \ # 本次任务的临时工作目录
             --topk 200 \ # 挖掘结果的图片数量
             --model-location ~/ymir-models \
             --media-location ~/ymir-assets \
             --model-hash <hash>@<inter-model-name> \ # 上一步训练出来的模型id,以及想要用于推理的中间模型名称
             --asset-cache-dir /tmp/ymir/cache \ # 资源缓存
             --task-config-file ~/mining-config.yaml \ # 挖掘参数配置文件,到挖掘镜像中获取
             --executor youdaoyzbx/ymir-executor:ymir1.3.0-yolov5-cu111-tmi # 挖掘镜像
  • 注:mir mining 中如果添加了 --add-prediction 参数,即可以同时在结果数据集中生成模型的推理结果。

6 标注

现在,系统已经挖掘出了对于模型训练最有效的200张图像,这些图像被保存在分支mining中,接下来的任务是将这些资源导出,送给标注人员进行标注。 用户可以通过下述命令完成导出过程:

$ mir export --asset-dir /tmp/ymir/export/export-0/assets \ # 资源导出目录
             --pred-dir /tmp/ymir/export/export-0/annotations \ # 导出标注目录
             --media-location ~/ymir-assets \ # 资源存储目录
             --src-revs mining-0@mining \
             --asset-format raw \ # 导出原图
             --anno-format none # 不导出标注
$ find /tmp/ymir/export/export-0/assets > /tmp/ymir/export/export-0/index.tsv

导出完成后,可以在/tmp/ymir/export/export-0/assets位置看到导出的图片,用户可以将这些图片送去标注,标注需要按VOC格式保存,假设保存路径仍然为/tmp/ymir/export/export-0/annotations。 标注完成后,用户可以使用与4.2.2中的导入命令类似的方式导入数据:

$ mir import --index-file /tmp/ymir/export/export-0/index.tsv
             --gt-dir /tmp/ymir/export/export-0/annotations \ # 标注路径
             --gen-dir ~/ymir-assets \ # 资源存储路径
             --unknown-types-strategy stop \
             --anno-type det-box \
             --dst-rev 'labeled-0@import' # 结果分支及操作任务名称

7 合并

现在的工作空间的分支labeled-0中已经包含了挖掘出来的200张新的训练图像,可以通过前述的merge将其和原来的训练集合并在一起:

$ mir merge --src-revs tr-va@filtered;tr:labeled-0@import \ # 待合并分支
            --dst-rev tr-va-1@merged \ # 结果分支及操作任务名称
            -s host # 策略:依据主体分支解决冲突

8 训练第二个模型

现在在分支tr-va-1上,已经包含了前一次训练所用的训练集和验证集,也包含了后来通过数据挖掘得出的新的200张训练集加人工标注,可以通过以下命令在此集合上训练一个新的模型出来:

$ mir train -w /tmp/ymir/training/train-1 \ # 每个不同的训练和挖掘任务都用不同的工作目录
            --media-location ~/ymir-assets \
            --model-location ~/ymir-models \
            --task-config-file ~/training-config.yaml \ # 训练参数配置文件,到训练镜像中获取
            --src-revs tr-va-1@merged \ # 使用合成以后的分支
            --dst-rev training-1@trained \
            --executor youdaoyzbx/ymir-executor:ymir1.3.0-yolov5-cu111-tmi