质量声明:原创文章,内容质量问题请评论吐槽。如对您产生干扰,可私信删除。
主要参考:李沐等:动手学深度学习-伯克利教材



摘要: MXNet实践: 单发多框SSD模型在Pikachu数据集上实现目标检测


Pikachu数据集

简介

  • 在⽬标检测领域并没有类似MNIST或Fashion-MNIST那样的小数据集。为了快速测试模型,李沐大神在授课时合成了⼀个小的数据集–Pikachu
  • ⾸先使⽤⼀个开源的⽪卡丘3D模型⽣成1000张不同⻆度和⼤小的⽪卡丘图像, 然后在收集的每一张背景图中随机选定区域放置⼀张随机的⽪卡丘图像, 最后使⽤MXNet提供的im2rec⼯具将图像转换成⼆进制的RecordIO格式, 即完成数据集构建.
  • MXNet RecordIO格式的数据集既可以降低磁盘上的存储开销,⼜能提⾼读取效率

下载

from mxnet.gluon import utils as gutils
import os

data_dir = "/content/drive/My Drive/Colab/dataset/pikachu"
root_url = ('https://apache-mxnet.s3-accelerate.amazonaws.com/'
       'gluon/dataset/pikachu/')
dataset = {'train.rec': 'e6bcb6ffba1ac04ff8a9b1115e650af56ee969c8',
       'train.idx': 'dcf7318b2602c06428b9988470c731621716c393',
       'val.rec': 'd6c33f799b4d058e82f2cb5bd9a976f69d72d520'}
for k, v in dataset.items():
    gutils.download(root_url + k, os.path.join(data_dir, k), sha1_hash=v)

读取数据集

def load_data_pikachu(batch_size, edge_size=256): # edge_size:输出图像的宽和⾼
    data_dir = './datasets/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), # 输出图像的形状
        shuffle=True,  # 以随机顺序读取数据集
        rand_crop=1,   # 随机裁剪的概率为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

数据集格式解析

  • 查看 DataBatch, 包括data属性, label属性, … :
batch_size, edge_size = 32, 256  # edge_size:输出图像的宽和⾼
train_iter, _ = load_data_pikachu(batch_size, edge_size)
batch = train_iter.next() 
  • 查看第一个batch的第一张图像:
index = 0
img = batch.data[0][index]  # <NDArray 3x256x256 @cpu>
img = img.transpose([1,2,0]).asnumpy().astype("uint8")
plt.imshow(img), plt.axis("off")
plt.show()

  • 查看第一个batch的第一张图像的标签, 包括类别和锚框坐标 (归一化)
index = 0
label = batch.label[0][index]  # <NDArray 1x5 @cpu>
category, bbox = label[0,0].asscalar(), label[0,1:].asnumpy()
category, bbox
category, x1,y1,x2,y2 =
0.0
array([0.3624674 , 0.37951997, 0.47177574, 0.5166516 ], dtype=float32)
  • 绘制锚框 (注意缩放):
index = 0
# 图像
img = batch.data[0][index]  # <NDArray 3x256x256 @cpu>
img = img.transpose([1,2,0]).asnumpy().astype("uint8")
width,height = img.shape[1],img.shape[0]
# 标签和锚框
label = batch.label[0][index]  # <NDArray 1x5 @cpu>
category, bbox = label[0,0].asscalar(), label[0,1:].asnumpy()
bbox = bbox * [width,height,width,height]
# plt显示
fig,ax = plt.subplots(1)
ax.imshow(img)
rect = plt.Rectangle(xy=(bbox[0],bbox[1]), width=bbox[2]-bbox[0], height=bbox[3]-bbox[1], 
              fill=False, edgecolor=color, linewidth=2)
ax.add_patch(rect),ax.axis("off")
fig.show()

SSD 模型