glucv.data.pascal_voc.detection.VOCDetection 无法使用dataloader


#1

https://gluon-cv.mxnet.io/build/examples_datasets/pascal_voc.html#sphx-glr-build-examples-datasets-pascal-voc-py

根据以上链接 copy了下面的代码

from gluoncv import data, utils
from matplotlib import pyplot as plt
from mxnet.gluon import data as gdata

train_dataset = data.VOCDetection(splits=[(2007, 'trainval')])
print('Num of training images:', len(train_dataset))

可以确认 train_dataset没有任何问题 因为label 和 image 全都可以按照链接里的步骤plot的出来
train_dataset 的 type是 gluoncv.data.pascal_voc.detection.VOCDetection

现在尝试用 dataloader 生成 iterator

train_dataset = data.VOCDetection(splits=[(2007, 'trainval')])
print('Num of training images:', len(train_dataset))
print(type(train_dataset))
batch_size = 32
num_workers=1
train_loader = gdata.DataLoader(train_dataset,
                                batch_size=batch_size,
                                num_workers=num_workers, 
                                shuffle=True,
                                last_batch="rollover")

for img, label in train_loader:
    print(f'img: {img.shape}')
    print(f'label: {label.shape}')
    break

报错如下:

Traceback (most recent call last):
  File "/opt/conda/lib/python3.6/multiprocessing/pool.py", line 119, in worker
    result = (True, func(*args, **kwds))
  File "/opt/conda/lib/python3.6/site-packages/mxnet/gluon/data/dataloader.py", line 400, in _worker_fn
    batch = batchify_fn([_worker_dataset[i] for i in samples])
  File "/opt/conda/lib/python3.6/site-packages/mxnet/gluon/data/dataloader.py", line 147, in default_mp_batchify_fn
    return [default_mp_batchify_fn(i) for i in data]
  File "/opt/conda/lib/python3.6/site-packages/mxnet/gluon/data/dataloader.py", line 147, in <listcomp>
    return [default_mp_batchify_fn(i) for i in data]
  File "/opt/conda/lib/python3.6/site-packages/mxnet/gluon/data/dataloader.py", line 151, in default_mp_batchify_fn
    ctx=context.Context('cpu_shared', 0))
  File "/opt/conda/lib/python3.6/site-packages/mxnet/ndarray/utils.py", line 146, in array
    return _array(source_array, ctx=ctx, dtype=dtype)
  File "/opt/conda/lib/python3.6/site-packages/mxnet/ndarray/ndarray.py", line 2504, in array
    arr = empty(source_array.shape, ctx, dtype)
  File "/opt/conda/lib/python3.6/site-packages/mxnet/ndarray/ndarray.py", line 3955, in empty
    return NDArray(handle=_new_alloc_handle(shape, ctx, False, dtype))
  File "/opt/conda/lib/python3.6/site-packages/mxnet/ndarray/ndarray.py", line 140, in _new_alloc_handle
    ctypes.c_int(int(_DTYPE_NP_TO_MX[np.dtype(dtype).type])),
KeyError: <class 'numpy.object_'>
"""

The above exception was the direct cause of the following exception:

#2

简而言之, 就是楼主贴的代码里没有采用相应的 batchify_fn, 代码使用了默认的 default_batchify_fn, 也就是简单的将 VOCDetection 类返回的大小为 (M, 6) 的二维数组 Stack 起来, 但是不同图像因为含有的目标数量不同, M 的大小是不同的, 而 Stack 函数只能堆叠相同大小的二维数组, 所以出了问题.

楼主可以看一下 Gluon-CV 的 SSD 代码是怎么处理的. https://github.com/dmlc/gluon-cv/blob/master/scripts/detection/ssd/train_ssd.py