问题描述
在mmdetection中,pipeline是一个非常重要的步骤,它负责对原始的图像进行一系列的处理,完成一系列的操作,最终提供给深度神经网络。
我在看mmdetection源代码的时候,尤其在阅读pipeline代码的时候,发现类的实例方法返回的都是results。而results是从哪里来的呢?此外,pipeline中的预处理方法是在何处调用的呢?
带着这些问题,我看到了一篇不错的博客,里面回答了我的一些困惑,我在它的基础上进行了一些总结,形成了自己的内容。
版本与环境
mmcv (0.2.16)
mmdet (1.0rc0+unknown)
torch (1.4.0)
torchvision (0.5.0)
CUDA 10.1
我的总结归纳
首先,我们要明确2个不同的对象:dataset和dataloader。在tools/train.py中,先进行的是build_dataset然后是build_dataloader。需要注意的是输入图像resize等图像预处理工作和pipeline都是在build_dataset阶段完成的,相反build_dataloader阶段做的事儿很少(mmdet/datasets/loader/build_loader.py)。
经过我仔细的研究和思考,我个人认为在dataset阶段并没有真正的开始处理数据,而是走了一遍pipeline的流程,“走了个过场”;在dataloader阶段,根据之前的流程,按照配置文件的imgs_per_gpu
和workers_per_gpu
参数真正地进行图像读入,预处理等操作。此外,在dataset阶段,其实是相当于build,将代码中的类实例化,即执行__init__
方法;而在dataloader阶段,其实是执行类的实例的__call__
方法。
在研究pipeline之前,需要先研究mmdet/datasets/coco.py,我之前就是漏了这一个部分,直接去研究pipeline了。这部分内容在博客中有详细介绍,省略不表。
本文主要讲2个内容,一个是pipeline是从哪里开始加载的(mmdet/datasets/custom.py第82行和mmdet/datasets/pipelines/compose.py第24行 ),还有一个是results是从哪里诞生的(mmdet/datasets/custom.py第140行)
pipeline是从哪里开始加载的
对于COCO数据集(mmdet/datasets/coco.py),其定义的类是CoCoDataset
,继承自CustomDataset
。因此,mmdetection在实例化CoCoDataset
前,已经实例化了CustomDataset
类。需要说明的是,CustomDataset
类继承自torch.utils.data中的Dataset
类。对于Dataset
类,最重要的就是__len__
和__getitem__
这两个实例方法。这篇博客对Pytorch中的Dataset和Dataloader介绍得比较详细。
class Dataset(object)