yolov5训练自己的数据

yolo v5 训练自己的数据集

2022年5月18日 家有一亩三分地

准备数据

yolo测试数据集合格式

  1. 文件夹形式

    数据需要包含图像和标签(images&labels),对应目录需要有训练集和验证集(train&val),test可以没有。标签数据文件名要与图像数据一致,并且在对应的文件夹下。具体显示如下

  • XXXX
    • images
      • train
      • val
    • labels
      • train
      • val
  1. 文本记录方式

    xxx

  • 标签格式采用txt形式,记录锚点的中心位置,及宽、高。宽高采用归一化后的数据。

准备自己的数据

实验采用 vco-2007数据集合。voc数据集包含了大量的样本及铆框。为了训练方便,假定我们只识别汽车、摩托车和自行车。这时我们就需要手动制作数据集。

  • voc数据集介绍

    1. vco数据集的标签在Annotations中,采用xml方式存储的

    undefined图像数据在JEPGImages中

    undefined类别测试数据在ImageSets中

  • 自作数据集
    参考https://www.it610.com/article/1467270294388432896.htm

    1. 创建数据采用python脚本

      import xml.etree.ElementTree as ET
      import pickle
      import os
      from os import listdir, getcwd
      from os.path import join
      import random
      from shutil import copyfile
      
      # 根据自己的数据标签修改
      classes=["car", "motorbike", "bicycle"]
      
      
      def clear_hidden_files(path):
          dir_list = os.listdir(path)    
          for i in dir_list:
              abspath = os.path.join(os.path.abspath(path), i)
              if os.path.isfile(abspath):
                  if i.startswith("._"):
                      os.remove(abspath)
              else:
                  clear_hidden_files(abspath)
      
      def convert(size, box):
          dw = 1./size[0]
          dh = 1./size[1]
          x = (box[0] + box[1])/2.0
          y = (box[2] + box[3])/2.0
          w = box[1] - box[0]
          h = box[3] - box[2]
          x = x*dw
          w = w*dw
          y = y*dh
          h = h*dh
          return (x,y,w,h)
      
      def convert_annotation(image_id):
          in_file = open('VOCdevkit/VOC2007/Annotations/%s.xml' %image_id)
          out_file = open('VOCdevkit/VOC2007/YOLOLabels/%s.txt' %image_id, 'w')
          tree=ET.parse(in_file)
          root = tree.getroot()
          size = root.find('size')
          w = int(size.find('width').text)
          h = int(size.find('height').text)
      
          i =0
          for obj in root.iter('object'):
              difficult = obj.find('difficult').text
              cls = obj.find('name').text
              if cls not in classes or int(difficult) == 1:
                  continue
              cls_id = classes.index(cls)
              xmlbox = obj.find('bndbox')
              b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
              bb = convert((w,h), b)
              out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
              i = i+1
          in_file.close()
          out_file.close()
          return i
      
      wd = os.getcwd()
      wd = os.getcwd()
      data_base_dir = os.path.join(wd, "VOCdevkit/")
      if not os.path.isdir(data_base_dir):
          os.mkdir(data_base_dir)
      work_sapce_dir = os.path.join(data_base_dir, "VOC2007/")
      if not os.path.isdir(work_sapce_dir):
          os.mkdir(work_sapce_dir)
      annotation_dir = os.path.join(work_sapce_dir, "Annotations/")
      if not os.path.isdir(annotation_dir):
              os.mkdir(annotation_dir)
      clear_hidden_files(annotation_dir)
      image_dir = os.path.join(work_sapce_dir, "JPEGImages/")
      if not os.path.isdir(image_dir):
              os.mkdir(image_dir)
      clear_hidden_files(image_dir)
      yolo_labels_dir = os.path.join(work_sapce_dir, "YOLOLabels/")
      if not os.path.isdir(yolo_labels_dir):
              os.mkdir(yolo_labels_dir)
      clear_hidden_files(yolo_labels_dir)
      yolov5_images_dir = os.path.join(data_base_dir, "images/")
      if not os.path.isdir(yolov5_images_dir):
              os.mkdir(yolov5_images_dir)
      clear_hidden_files(yolov5_images_dir)
      yolov5_labels_dir = os.path.join(data_base_dir, "labels/")
      if not os.path.isdir(yolov5_labels_dir):
              os.mkdir(yolov5_labels_dir)
      clear_hidden_files(yolov5_labels_dir)
      yolov5_images_train_dir = os.path.join(yolov5_images_dir, "train/")
      if not os.path.isdir(yolov5_images_train_dir):
              os.mkdir(yolov5_images_train_dir)
      clear_hidden_files(yolov5_images_train_dir)
      yolov5_images_test_dir = os.path.join(yolov5_images_dir, "val/")
      if not os.path.isdir(yolov5_images_test_dir):
              os.mkdir(yolov5_images_test_dir)
      clear_hidden_files(yolov5_images_test_dir)
      yolov5_labels_train_dir = os.path.join(yolov5_labels_dir, "train/")
      if not os.path.isdir(yolov5_labels_train_dir):
              os.mkdir(yolov5_labels_train_dir)
      clear_hidden_files(yolov5_labels_train_dir)
      yolov5_labels_test_dir = os.path.join(yolov5_labels_dir, "val/")
      if not os.path.isdir(yolov5_labels_test_dir):
              os.mkdir(yolov5_labels_test_dir)
      clear_hidden_files(yolov5_labels_test_dir)
      
      train_file = open(os.path.join(wd, "yolov5_train.txt"), 'w')
      test_file = open(os.path.join(wd, "yolov5_val.txt"), 'w')
      train_file.close()
      test_file.close()
      train_file = open(os.path.join(wd, "yolov5_train.txt"), 'a')
      test_file = open(os.path.join(wd, "yolov5_val.txt"), 'a')
      list_imgs = os.listdir(image_dir) # list image files
      probo = random.randint(1, 100)
      print("Probobility: %d" % probo)
      for i in range(0,len(list_imgs)):
          path = os.path.join(image_dir,list_imgs[i])
          if os.path.isfile(path):
              image_path = image_dir + list_imgs[i]
              voc_path = list_imgs[i]
              (nameWithoutExtention, extention) = os.path.splitext(os.path.basename(image_path))
              (voc_nameWithoutExtention, voc_extention) = os.path.splitext(os.path.basename(voc_path))
              annotation_name = nameWithoutExtention + '.xml'
              annotation_path = os.path.join(annotation_dir, annotation_name)
              label_name = nameWithoutExtention + '.txt'
              label_path = os.path.join(yolo_labels_dir, label_name)
          probo = random.randint(1, 100)
          print("Probobility: %d" % probo)
          if(probo < 80): # train dataset
              if os.path.exists(annotation_path):
                  i = convert_annotation(nameWithoutExtention) # convert label
                  if(i>0):
                      train_file.write(yolov5_images_train_dir + voc_path + '\n')
                      copyfile(image_path, yolov5_images_train_dir + voc_path)
                      copyfile(label_path, yolov5_labels_train_dir + label_name)
          else: # test dataset
              if os.path.exists(annotation_path):
                  i = convert_annotation(nameWithoutExtention) # convert label
                  if(i>0):
                      test_file.write(yolov5_images_train_dir + voc_path + '\n')
                      copyfile(image_path, yolov5_images_test_dir + voc_path)
                      copyfile(label_path, yolov5_labels_test_dir + label_name)
      train_file.close()
      test_file.close()
      
      

      程序将自动创建images和labels文件夹集数据

    2. 设置yolo 训练yaml文件

      在*/yolov5/data/*文件夹下创建一个myvoc.yaml文件,设置刚刚生成的数据路径

      
      # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
      path: D:/BaiduNetdiskDownload/VOC2007/pascal-voc-2007/VOCdevkit/VOC2007/VOCdevkit # dataset root dir
      train: images/train  # train images (relative to 'path') 118287 images
      val: images/val  # val images (relative to 'path') 5000 images
      test: images/test  # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794
      
      # Classes
      nc: 3  # 修改种类
      names: ['car', 'motorbike', 'bicycle']  # 类别名称
      
    3. 修改训练迁移模型及参数

      在**/yolov5/models**问价夹下拷贝yolov5s.yaml更改名称new_train.yaml,并设置样本类别数。根据采用不同的网络需要根据不同的yaml生成测试文件

      # YOLOv5 🚀 by Ultralytics, GPL-3.0 license
      
      # Parameters
      nc: 3  # 样本类数
      depth_multiple: 0.33  # model depth multiple
      width_multiple: 0.50  # layer channel multiple
      anchors:
        - [10,13, 16,30, 33,23]  # P3/8
        - [30,61, 62,45, 59,119]  # P4/16
        - [116,90, 156,198, 373,326]  # P5/32
      
      

训练

执行测试命令

(yolov5-gpu) D:\ptwork\git\yolov5>python train.py --data data\myvoc.yaml  --cfg models\new_train.yaml --weights weights\yolov5s.pt --epochs 10 --batch-size 32 --device 0

测试

(yolov5-gpu) D:\ptwork\git\yolov5>python detect.py --weights  .\runs\train\exp23\weights\best.pt --source L:\001.jpg  --imgsz 5408
detect: weights=['.\\runs\\train\\exp23\\weights\\best.pt'], source=L:\001.jpg, data=data\coco128.yaml, imgsz=[5408, 5408], conf_thres=0.25, iou_thres=0.45, max_det=1000, device=, view_img=False, save_txt=False, save_conf=False, save_crop=False, nosave=False, classes=None, agnostic_nms=False, augment=False, visualize=False, update=False, project=runs\detect, name=exp, exist_ok=False, line_thickness=3, hide_labels=False, hide_conf=False, half=False, dnn=False
YOLOv5  v6.1-191-gd29df68 Python-3.9.0 torch-1.10.1 CUDA:0 (NVIDIA GeForce RTX 2080, 8192MiB)

Fusing layers...
new_train summary: 213 layers, 7018216 parameters, 0 gradients
image 1/1 L:\001.jpg: 3680x5408 26 cars, 2 motorbikes, 1 bicycle, Done. (0.153s)
Speed: 29.0ms pre-process, 153.0ms inference, 7.0ms NMS per image at shape (1, 3, 5408, 5408)
Results saved to runs\detect\exp12

runs\detect\exp12文件夹下查看结果

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2022年5月19日 上午11:53
下一篇 2022年5月19日

相关推荐