描述
对于普通的图像分类,label只用表示图片的类别就行,而目标检测,不仅仅包括了类别的判断,还包含了类别的位置信息。所以在神经网络的构造上和数据的读取上都大不相同。
深度学习框架选用
MxNet Gluon,经过个人的对比,对于单GPU或CPU,MxNet的速度和内存占用要远优于TensorFlow,个人认为TensorFlow的优势则在于分布式和多GPU上。
选用生成方式
MxNet对于读取数据集的方式也有多种。
1、生成lst,直接读取
2、生成rec文件,读取rec文件
3、使用目前新出的gluoncv的方式读取,据说这种方式是最快的。
(下面我们只使用简单的第一种方式进行读取)
读取xml文件生成lst文件
lst文件格式:
format:0 4 5(4,5为label的大小,表示训练图片中最多可以容纳4个标签物) 640(width) 480(height) 1(class) 0.1 0.2 0.8 0.9(xmin, ymin, xmax, ymax) 2 0.5 0.3 0.6 0.8 data/xxx.jpg
import os
import mxnet as mx
import numpy as np
import matplotlib.pyplot as plt
import xml.dom.minidom # 处理xml数据
ddd = {'sign1':0,'sign2':1,'sign3':2,'sign4':3,'sign5':4}
# 首先定义一个读取xml文件的函数:
def xmlDecode(path):
annotation = xml.dom.minidom.parse(path)
size = annotation.getElementsByTagName('size')[0]
width = size.getElementsByTagName('width')[0].firstChild.data
height = size.getElementsByTagName('height')[0].firstChild.data
obj = annotation.getElementsByTagName('object')[0]
cla = ddd[obj.getElementsByTagName('name')[0].firstChild.data] # 类别
bndbox = obj.getElementsByTagName('bndbox')[0] # 坐标
x1 = bndbox.getElementsByTagName('xmin')[0].firstChild.data
x2 = bndbox.getElementsByTagName('xmax')[0].firstChild.data
y1 = bndbox.getElementsByTagName('ymin')[0].firstChild.data
y2 = bndbox.getElementsByTagName('ymax')[0].firstChild.data
width = int(width)
height = int(height)
x1 = int(x1)
x2 = int(x2)
y1 = int(y1)
y2 = int(y2)
result = [cla, (width, height), (x1, y1), (x2, y2)]
return result
# 定义保存数据和标签文件夹路径
path = './VOCtemplate/VOC2012/Annotations/'
# 假设图片名和对应的标签名称一致,这里直接替换xml为jpg
# TODO:read xml and write as lst file, jpg name as path + xml name
# format:0 4 5 640(width) 480(height) 1(class) 0.1 0.2 0.8 0.9(xmin, ymin, xmax, ymax) 2 0.5 0.3 0.6 0.8 data/xxx.jpg
names = os.listdir(path)
lst = []
i = 0
path2 = './'
f = open(path2 + 'train.lst', 'w')
for name in names:
if name.endswith('.xml'):
result = xmlDecode(path + name)
img_name = name.replace('xml', 'jpg')
lst_tmp = str(i)+'\t4'+'\t5'+'\t'+str(result[1][0])+'\t'+str(result[1][1])+'\t'\
+str(result[0])+'\t'\
+str(result[2][0]/result[1][0])+'\t'+str(result[2][1]/result[1][1])+'\t'\
+str(result[3][0]/result[1][0])+'\t'+str(result[3][1]/result[1][1])+'\t'\
+img_name+'\n'
# print(lst_tmp)
f.write(lst_tmp)
i += 1
f.close()
# 运行结束就可以在path对应文件夹下看到lst文件了。
# reference
# https://blog.youkuaiyun.com/u010642383/article/details/80426971
# https://discuss.mxnet.io/t/imagedetiter-label-shape-mismatch/200
# https://github.com/leocvml/mxnet-im2rec_tutorial/
# https://discuss.gluon.ai/t/topic/4143/18
# 数据增强:https://zhuanlan.zhihu.com/p/30547553
#要是数据集格式错误,会报错类似这样的信息,注意检查最后空行/class位置等。
#--> 681 label_shape = self._estimate_label_shape()
#--> 702 label = self._parse_label(label)
lst文件查看
使用image.ImageDetIter()函数来读取图片及标签。(文件名:load_my_data.py)
from mxnet import image
path = './VOCtemplate/VOC2012/Annotations/'
def load_my_data(batch_size, edge_size=256): # edge_size:输出图像的宽和高。
train_iter = image.ImageDetIter(batch_size=batch_size, data_shape=(3, edge_size, edge_size), path_imglist='train.lst', path_root=path)
return train_iter#, val_iter
batch_size,edge_size = 4,256
train_data=load_my_data(batch_size,edge_size)
batch = train_data.next()
print(batch.data[0].shape)
print(batch.label[0].shape)
输出
下一篇、构造神经网络与训练