detectron2训练自己的数据集_YOLO(v3)PyTorch版 训练自己的数据集
Yolo v3比Frcnn好調(diào)試多了……就是數(shù)據(jù)集準(zhǔn)備比較麻煩…… 但是好Debug,linux和win10差別不大……
代碼鏈接(cpu版本):
https://github.com/eriklindernoren/PyTorch-YOLOv3/issues/340?github.com這個(gè)代碼……作者說(shuō)的太草率了……data怎么準(zhǔn)備都沒說(shuō)清……好歹issue里面有大神解答,給了傻瓜版教程,運(yùn)行他的幾個(gè)腳本就好了,data文件夾就準(zhǔn)備好啦!
data文件準(zhǔn)備,按照這個(gè)
FLyingLSJ/PyTorch-YOLOv3-master?github.com雖然這個(gè)作者是用它來(lái)訓(xùn)練coco數(shù)據(jù)集,但是data整個(gè)是個(gè)四不像……不用json不用xml用txt……所以訓(xùn)練自己的比較麻煩…… 準(zhǔn)備好data,還有修改config/yolov3.cfg文件。
參考鏈接:
超詳細(xì)教程:YOLO_V3(yolov3)訓(xùn)練自己的數(shù)據(jù)_網(wǎng)絡(luò)_qq_21578849的博客-CSDN博客?blog.csdn.net打開yolov3.cfg文件后,搜索yolo,共有三處yolo,下面以一處的修改作為示例。
[convolutional] #緊挨著[yolo]上面的[convolutional] size=1 stride=1 pad=1 filters=21 #filters=3*(你的class種類數(shù)+5) activation=linear [yolo] mask = 6,7,8 anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 classes=2 #修改classes num=9 jitter=.3 ignore_thresh = .7 truth_thresh = 1 random=0 #顯存大的寫1 反之0除此之外,cfg中的其他參數(shù)可以參考這個(gè)鏈接來(lái)進(jìn)行修改,比如可以修改一些數(shù)據(jù)增強(qiáng)的參數(shù),如果想要接著上次訓(xùn)練的weight繼續(xù)訓(xùn)練,就參考這個(gè)鏈接進(jìn)行微調(diào)(但是我使用的代碼不支持clear操作,只能使用第二種方法)。
然后開始訓(xùn)練吧!個(gè)人感覺yolov3學(xué)的效果不是很好,frcnn訓(xùn)練了十輪能達(dá)到的效果,yolov3可能要80輪左右,開始前幾十輪mAP很低就多加幾輪試試,issue里面提到這個(gè)代碼訓(xùn)練100輪,coco也達(dá)不到作者所說(shuō)的mAP……所以……慎重……男票用這個(gè)幫我把自己的數(shù)據(jù)集跑到了92%左右的mAP,效果還是很好的。 準(zhǔn)備數(shù)據(jù)集的那個(gè)代碼有些bug調(diào)不出來(lái),所以還是使用第一個(gè)的代碼吧。 記錄一下用過(guò)的腳本之 voc的xml轉(zhuǎn)化為coco的json
import os import json import xml.etree.ElementTree as ET import numpy as np import cv2def _isArrayLike(obj):return hasattr(obj, '__iter__') and hasattr(obj, '__len__')class voc2coco:def __init__(self, devkit_path=None, year=None):# self.classes = ('__background__',# 'aeroplane', 'bicycle', 'bird', 'boat',# 'bottle', 'bus', 'car', 'cat', 'chair',# 'cow', 'diningtable', 'dog', 'horse',# 'motorbike', 'person', 'pottedplant',# 'sheep', 'sofa', 'train', 'tvmonitor')self.classes = ('none','ll', 'rr') #寫你自己的classself.num_classes = len(self.classes)assert 'VOCdevkit' in devkit_path, 'VOC地址不存在: {}'.format(devkit_path)self.data_path = os.path.join(devkit_path, 'VOC' + year)self.annotaions_path = os.path.join(self.data_path, 'Annotations')self.image_set_path = os.path.join(self.data_path, 'ImageSets')self.year = yearself.categories_to_ids_map = self._get_categories_to_ids_map()self.categories_msg = self._categories_msg_generator()def _load_annotation(self, ids=[]):ids = ids if _isArrayLike(ids) else [ids]image_msg = []annotation_msg = []annotation_id = 1for index in ids:filename = '{:0>6}'.format(index)json_file = os.path.join(self.data_path, 'Segmentation_json', filename + '.json')num=0if os.path.exists(json_file):img_file = os.path.join(self.data_path, 'JPEGImages', filename + '.jpg')im = cv2.imread(img_file)width = im.shape[1]height = im.shape[0]seg_data = json.load(open(json_file, 'r'))assert type(seg_data) == type(dict()), 'annotation file format {} not supported'.format(type(seg_data))for shape in seg_data['shapes']:seg_msg = []for point in shape['points']:seg_msg += pointone_ann_msg = {"segmentation": [seg_msg],"area": self._area_computer(shape['points']),"iscrowd": 0,"image_id": int(index),"bbox": self._points_to_mbr(shape['points']),"category_id": self.categories_to_ids_map[shape['label']],"id": annotation_id,"ignore": 0}annotation_msg.append(one_ann_msg)annotation_id += 1else:xml_file = os.path.join(self.annotaions_path, filename + '.xml')tree = ET.parse(xml_file)size = tree.find('size')objs = tree.findall('object')width = size.find('width').textheight = size.find('height').textfor obj in objs:bndbox = obj.find('bndbox')[xmin, xmax, ymin, ymax] = [int(bndbox.find('xmin').text) - 1, int(bndbox.find('xmax').text),int(bndbox.find('ymin').text) - 1, int(bndbox.find('ymax').text)]if xmin < 0:xmin = 0if ymin < 0:ymin = 0bbox = [xmin, xmax, ymin, ymax]one_ann_msg = {"segmentation": self._bbox_to_mask(bbox),"area": self._bbox_area_computer(bbox),"iscrowd": 0,"image_id": int(num),"bbox": [xmin, ymin, xmax - xmin, ymax - ymin],"category_id": self.categories_to_ids_map[obj.find('name').text],"id": annotation_id,"ignore": 0}annotation_msg.append(one_ann_msg)annotation_id += 1one_image_msg = {"file_name": filename + ".jpg","height": int(height),"width": int(width),"id": int(num)}image_msg.append(one_image_msg)num=num+1return image_msg, annotation_msgdef _bbox_to_mask(self, bbox):assert len(bbox) == 4, 'Wrong bndbox!'mask = [bbox[0], bbox[2], bbox[0], bbox[3], bbox[1], bbox[3], bbox[1], bbox[2]]return [mask]def _bbox_area_computer(self, bbox):width = bbox[1] - bbox[0]height = bbox[3] - bbox[2]return width * heightdef _save_json_file(self, filename=None, data=None):json_path = os.path.join(self.data_path, 'cocoformatJson')assert filename is not None, 'lack filename'if os.path.exists(json_path) == False:os.mkdir(json_path)if not filename.endswith('.json'):filename += '.json'assert type(data) == type(dict()), 'data format {} not supported'.format(type(data))with open(os.path.join(json_path, filename), 'w') as f:f.write(json.dumps(data))def _get_categories_to_ids_map(self):return dict(zip(self.classes, range(self.num_classes)))def _get_all_indexs(self):ids = []for root, dirs, files in os.walk(self.annotaions_path, topdown=False):for f in files:if str(f).endswith('.xml'):id = int(str(f).strip('.xml'))ids.append(id)assert ids is not None, 'There is none xml file in {}'.format(self.annotaions_path)return idsdef _get_indexs_by_image_set(self, image_set=None):if image_set is None:return self._get_all_indexs()else:image_set_path = os.path.join(self.image_set_path, 'Main', image_set + '.txt')assert os.path.exists(image_set_path), 'Path does not exist: {}'.format(image_set_path)with open(image_set_path) as f:ids = [x.strip() for x in f.readlines()]return idsdef _points_to_mbr(self, points):assert _isArrayLike(points), 'Points should be array like!'x = [point[0] for point in points]y = [point[1] for point in points]assert len(x) == len(y), 'Wrong point quantity'xmin, xmax, ymin, ymax = min(x), max(x), min(y), max(y)height = ymax - yminwidth = xmax - xminreturn [xmin, ymin, width, height]def _categories_msg_generator(self):categories_msg = []for category in self.classes:if category == 'none':continueone_categories_msg = {"supercategory": "none","id": self.categories_to_ids_map[category],"name": category}categories_msg.append(one_categories_msg)return categories_msgdef _area_computer(self, points):assert _isArrayLike(points), 'Points should be array like!'tmp_contour = []for point in points:tmp_contour.append([point])contour = np.array(tmp_contour, dtype=np.int32)area = cv2.contourArea(contour)return areadef voc_to_coco_converter(self):img_sets = ['trainval', 'test']for img_set in img_sets:ids = self._get_indexs_by_image_set(img_set)img_msg, ann_msg = self._load_annotation(ids)result_json = {"images": img_msg,"type": "instances","annotations": ann_msg,"categories": self.categories_msg}self._save_json_file('voc_' + self.year + '_' + img_set, result_json)def demo():# 轉(zhuǎn)換pascal地址是'./VOC2007/VOCdevkit/VOC2007/ImageSets/Main/trainval.txt'converter = voc2coco('D:Codingpythondata_myselfVOCdevkit2007', '2007')converter.voc_to_coco_converter()if __name__ == "__main__":demo() 超強(qiáng)干貨來(lái)襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的detectron2训练自己的数据集_YOLO(v3)PyTorch版 训练自己的数据集的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 炎龙内存:性能猛如炎龙,稳定如山
- 下一篇: 揭秘ddr4 3000内存:游戏加载速度