目標檢測數據集The Object Detection Dataset
在目標檢測領域,沒有像MNIST或Fashion MNIST這樣的小數據集。為了快速測試模型,我們將組裝一個小數據集。首先,我們使用一個開源的3D Pikachu模型生成1000張不同角度和大小的Pikachu圖像。然后,我們收集一系列背景圖像,並在每個圖像上隨機放置一個Pikachu圖像。我們使用MXNet提供的im2rec工具將圖像轉換為二進制RecordIO格式[1]。這種格式可以減少數據集在磁盤上的存儲開銷,提高讀取效率。如果您想了解有關如何讀取圖像的更多信息,請參閱GluonCV工具包的文檔。
1. Downloading the Dataset
可以直接從互聯網上下載RecordIO格式的Pikachu數據集。
%matplotlib inline
from d2l import mxnet as d2l
from mxnet import gluon, image, np, npx
import os
npx.set_np()
#@save
d2l.DATA_HUB['pikachu'] = (d2l.DATA_URL + 'pikachu.zip',
'68ab1bd42143c5966785eb0d7b2839df8d570190')
2. Reading the Dataset
我們將通過創建實例imageDediter來讀取對象檢測數據集。名稱中的“Det”是指檢測。我們將隨機讀取訓練數據集。因為數據集的格式是RecordIO,所以我們需要圖像索引文件'train.idx'讀取隨機的小批量。此外,對於訓練集的每個圖像,我們將使用隨機裁剪,並要求裁剪后的圖像至少覆蓋每個對象的95%。由於裁剪是隨機的,這一要求並不總是滿足的。我們將隨機裁剪嘗試的最大次數設置為200次。如果它們都不符合要求,圖像將不會被裁剪。為了確保輸出的確定性,我們不會隨機裁剪測試數據集中的圖像。我們也不需要隨機讀取測試數據集。
#@save
def load_data_pikachu(batch_size, edge_size=256):
"""Load the pikachu dataset."""
data_dir = d2l.download_extract('pikachu')
train_iter = image.ImageDetIter(
path_imgrec=os.path.join(data_dir, 'train.rec'),
path_imgidx=os.path.join(data_dir, 'train.idx'),
batch_size=batch_size,
data_shape=(3, edge_size, edge_size), # The shape of the output image
shuffle=True, # Read the dataset in random order
rand_crop=1, # The probability of random cropping is 1
min_object_covered=0.95, max_attempts=200)
val_iter = image.ImageDetIter(
path_imgrec=os.path.join(data_dir, 'val.rec'), batch_size=batch_size,
data_shape=(3, edge_size, edge_size), shuffle=False)
return train_iter, val_iter
下面,我們閱讀一個小批量,並打印圖像和標簽的形狀。圖像的形狀與前一個實驗中相同(批量大小、通道數、高度、寬度)(batch size, number of channels, height, width)。標簽的形狀是(批量大小,m,5)(batch size, mm, 5),其中m等於數據集中單個圖像中包含的最大邊界框數。雖然小批量的計算非常高效,但它要求每個圖像包含相同數量的邊界框,以便將它們放置在同一批中。因為每個圖像可能有不同數量的邊界框,我們可以添加非法的邊界框到少於m邊界框,直到每個圖像包含m邊界框。因此,我們每次都可以讀取一小批圖像。圖像中每個邊界框的標簽由長度為5的數組表示。數組中的第一個元素是邊界框中包含的對象的類別。當值為-1時,邊界框是非法的填充邊界框。數組的其余四個元素表示x、y、邊界框左上角和 邊界框右下角的軸坐標(值范圍在0和1之間)。這里的Pikachu數據集每個圖像只有一個邊界框,因此m=1。
batch_size, edge_size = 32, 256
train_iter, _ = load_data_pikachu(batch_size, edge_size)
batch = train_iter.next()
batch.data[0].shape, batch.label[0].shape
Downloading ../data/pikachu.zip from http://d2l-data.s3-accelerate.amazonaws.com/pikachu.zip...
((32, 3, 256, 256), (32, 1, 5))
3. Demonstration
我們有十張圖片,上面有邊框。我們可以看到Pikachu的角度、大小和位置在每個圖像中都是不同的。當然,這是一個簡單的人工數據集。在實際操作中,數據通常要復雜得多。
imgs = (batch.data[0][0:10].transpose(0, 2, 3, 1)) / 255
axes = d2l.show_images(imgs, 2, 5, scale=2)
for ax, label in zip(axes, batch.label[0][0:10]):
d2l.show_bboxes(ax, [label[0][1:5] * edge_size], colors=['w'])
4. Summary
- The Pikachu dataset we synthesized can be used to test object detection models.
- The data reading for object detection is similar to that for image classification. However, after we introduce bounding boxes, the label shape and image augmentation (e.g., random cropping) are changed.