结合ModelArts打造基于Yolov5的垃圾分类识别模型
2020年6月参加了华为云AI算法大赛--垃圾分类识别大赛,虽然没有进入决赛,但是还是想将ModelArts在构建的模型经验分享出来,现在的开发的主流思想就是开源为王。yolov5是yolo系列的最新版本的目标检测模型,较之前的yolov3、yolov4的版本有很大的提升,官方给出的效果提升如下:
一、数据预处理
本次采用的数据集是官方提供的VOC2007格式的垃圾分类数据集。
由于yolov5需要的训练数据格式如下:
每个图像的标签文件应该可以通过在其路径名中简单地替换/images/*.jpg
为来定位/labels/*.txt
。示例图像和标签对为:
因此数据处理脚本如下:
# 运行成功后会生成如下目录结构的文件夹:
# trainval/
# -images
# -0001.jpg
# -0002.jpg
# -0003.jpg
# -labels
# -0001.txt
# -0002.txt
# -0003.txt
# 将trainval文件夹打包并命名为trainval.zip, 上传到OBS中以备使用。
import os
import codecs
import xml.etree.ElementTree as ET
from tqdm import tqdm
import shutil
import argparse
def get_classes(classes_path):
'''loads the classes'''
with codecs.open(classes_path, 'r', 'utf-8') as f:
class_names = f.readlines()
class_names = [c.strip() for c in class_names]
return class_names
def convert(size, box):
w = size[0]
h = size[1]
w_center = round((box[2] - box[0]) / w, 6)
h_center = round((box[3] - box[1]) / h, 6)
x_center = round(((box[2] + box[0]) / 2) / w, 6)
y_center = round(((box[3] + box[1]) / 2) / h, 6)
# dw = 1./(size[0])
# dh = 1./(size[1])
# x = (box[0] + box[2])/2.0 -1
# y = (box[1] + box[3])/2.0 -1
# w = box[2] - box[0]
# h = box[3] - box[1]
# x = x*dw
# w = w*dw
# y = y*dh
# h = h*dh
return x_center, y_center, w_center, h_center
#return x_center, y_center, w_center, h
def creat_label_txt(soure_datasets, new_datasets):
annotations = os.path.join(soure_datasets, 'VOC2007/Annotations')
txt_path = os.path.join(new_datasets, 'labels')
class_names = get_classes(os.path.join(soure_datasets, 'train_classes.txt'))
xmls = os.listdir(annotations)
for xml in tqdm(xmls):
txt_anno_path = os.path.join(txt_path, xml.replace('xml', 'txt'))
xml = os.path.join(annotations, xml)
tree = ET.parse(xml)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
line = ''
for obj in root.iter('object'):
cls = obj.find('name').text
if cls not in class_names:
print('name error', xml)
continue
cls_id = class_names.index(cls)
xmlbox = obj.find('bndbox')
box = [int(xmlbox.find('xmin').text), int(xmlbox.find('ymin').text),
int(xmlbox.find('xmax').text), int(xmlbox.find('ymax').text)]
if box[2] > w or box[3] > h:
print('Image with annotation error:', xml)
if box[0] < 0 or box[1] < 0:
print('Image with annotation error:', xml)
# width = round((box[2] - box[0]) / w, 6)
# height = round((box[3] - box[1]) / h, 6)
# x_center = round(((box[2] + box[0]) / 2) / w, 6)
# y_center = round(((box[3] + box[1]) / 2) / h, 6)
bbox = convert((w, h), box)
line = line + str(cls_id) + ' ' + " ".join([str(a) for a in bbox])+'\n'
with open(txt_anno_path, 'w') as f:
f.writelines(line)
sets = ["train", "valid"]
def split_trainval():
for image_set in sets:
image_indexs = open(f"./source_data/trainval/VOC2007/ImageSets/Main/{image_set}.txt").read().strip().split()
list_file = open(f"{image_set}.txt", "w")
for image_index in image_indexs:
list_file.write(f"datasets/trainval/images/{image_index}.jpg\n")
list_file.close()
def creat_new_datasets(source_datasets, new_datasets):
if not os.path.exists(source_datasets):
print('could find source datasets, please make sure if it is exist')
return
if new_datasets.endswith('trainval'):
if not os.path.exists(new_datasets):
os.makedirs(new_datasets)
os.makedirs(new_datasets + '/labels')
print('copying images......')
shutil.copytree(source_datasets + '/VOC2007/JPEGImages', new_datasets + '/images')
else:
print('最后一级目录必须为trainval,且为空文件夹')
return
print('creating txt labels:')
creat_label_txt(source_datasets, new_datasets)
split_trainval()
return
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--soure_datasets", "-sd", type=str, help="SODiC官方原始数据集解压后目录")
parser.add_argument("--new_datasets", "-nd", type=str, help="新数据集路径,以trainval结尾且为空文件夹")
opt = parser.parse_args()
# creat_new_datasets(opt.soure_datasets, opt.new_datasets)
soure_datasets = r'./source_data/trainval'
new_datasets = r'./trainval'
creat_new_datasets(soure_datasets, new_datasets)
数据处理完后,就符合yolov5的训练输入格式了。
2、创建数据data/coco128.yaml Dataset.yaml
三、选择模型和模型参数
由于yolov5提供5个不同的参数模型选择,我直接上效果最好的yolov5x模型参数。
4、开始训练模型
直接利用train.py开始训练,训练参数如下:
这里选择了预训练模型yolov5x.pt,如果不想从预训练,从头开始训练,去掉这个参数即可,开启multi_scale可以增加准确度。
python train.py --data ./data/coco128.yaml --cfg ./models/yolov5x.yaml --weights weights/yolov5x.pt --multi-scale
训练过程如下:
我训练了120batch,最后能有
mAP@0.5最后能达到0.78.
训练过程的图片的识别效果如下:
5、通过modelarts推理代码部署。推理代码如下:
根据ModelArts的模型要求,导入模型
在测试集上的mAP@0.5 能达到 0.76,yolov5的表现没有让人失望。
以上就是基于yolov5的modelarts垃圾分类模型。欢迎大家拍砖。
参考:
- 点赞
- 收藏
- 关注作者
评论(0)