• YOLOv5从训练到移植


    一、图像采集和标注

    • 图像采集

    覆盖所有的数据目标,不同场景(视角、光照、可能的干扰)、距离、运动、背景等,用深度和广度摄像头都行。

    若兼顾效率和准确率,可以用迁移学习思路训练,则不同场景下采集的图像数据量可以适当降低,但避免场景单一问题。

    • 图像标注

    可以看LabelImg安装与使用

    二、YOLOv5模型训练

    1、YOLOv5深度网络下载

    下载地址:YOLOv5模型

    2、安装环境依赖库

    安装命令语句 

    pip install -r requirements.txt

     或者

    按照requirements.txt文件里依赖库的顺序,分别用pip install安装对应的包

    3、准备数据集

    把图像数据集和标定数据复制到yolov5/InsectImg/RawInsect文件夹下, 创建一个YOLOLabels文件夹,主要将Pascal VOC标注模式生成的.xml文件转换为.txt格式。

    完整代码

    1. import xml.etree.ElementTree as ET
    2. import pickle
    3. import os
    4. from os import listdir, getcwd
    5. from os.path import join
    6. import random
    7. from shutil import copyfile
    8. classes = ['aedes', 'aegypti','albiceps','albopictus','americana','australasiae','bazini','cheopis','coquillett', 'culex','cuprina',
    9. 'fabricius','fuliginosa','gblattella','melanura', 'musca','pattoni','rhombifolia','sericata','sorbens','wiedemann']
    10. TRAIN_RATIO = 80
    11. def clear_hidden_files(path):
    12. dir_list = os.listdir(path)
    13. for i in dir_list:
    14. abspath = os.path.join(os.path.abspath(path), i)
    15. if os.path.isfile(abspath):
    16. if i.startswith("._"):
    17. os.remove(abspath)
    18. else:
    19. clear_hidden_files(abspath)
    20. def convert(size, box):
    21. dw = 1. / size[0]
    22. dh = 1. / size[1]
    23. x = (box[0] + box[1]) / 2.0
    24. y = (box[2] + box[3]) / 2.0
    25. w = box[1] - box[0]
    26. h = box[3] - box[2]
    27. x = x * dw
    28. w = w * dw
    29. y = y * dh
    30. h = h * dh
    31. return (x, y, w, h)
    32. def convert_annotation(image_id):
    33. in_file = open('InsectImg/RawInsect/Annotations/%s.xml' % image_id)
    34. out_file = open('InsectImg/RawInsect/YOLOLabels/%s.txt' % image_id, 'w')
    35. tree = ET.parse(in_file)
    36. root = tree.getroot()
    37. size = root.find('size')
    38. w = int(size.find('width').text)
    39. h = int(size.find('height').text)
    40. for obj in root.iter('object'):
    41. difficult = obj.find('difficult').text
    42. cls = obj.find('name').text
    43. if cls not in classes or int(difficult) == 1:
    44. continue
    45. cls_id = classes.index(cls)
    46. xmlbox = obj.find('bndbox')
    47. b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
    48. float(xmlbox.find('ymax').text))
    49. bb = convert((w, h), b)
    50. out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
    51. in_file.close()
    52. out_file.close()
    53. wd = os.getcwd()
    54. wd = os.getcwd()
    55. data_base_dir = os.path.join(wd, "InsectImg/")
    56. if not os.path.isdir(data_base_dir):
    57. os.mkdir(data_base_dir)
    58. work_sapce_dir = os.path.join(data_base_dir, "RawInsect/")
    59. if not os.path.isdir(work_sapce_dir):
    60. os.mkdir(work_sapce_dir)
    61. annotation_dir = os.path.join(work_sapce_dir, "Annotations/")
    62. if not os.path.isdir(annotation_dir):
    63. os.mkdir(annotation_dir)
    64. clear_hidden_files(annotation_dir)
    65. image_dir = os.path.join(work_sapce_dir, "JPEGImages/")
    66. if not os.path.isdir(image_dir):
    67. os.mkdir(image_dir)
    68. clear_hidden_files(image_dir)
    69. yolo_labels_dir = os.path.join(work_sapce_dir, "YOLOLabels/")
    70. if not os.path.isdir(yolo_labels_dir):
    71. os.mkdir(yolo_labels_dir)
    72. clear_hidden_files(yolo_labels_dir)
    73. yolov5_images_dir = os.path.join(data_base_dir, "images/")
    74. if not os.path.isdir(yolov5_images_dir):
    75. os.mkdir(yolov5_images_dir)
    76. clear_hidden_files(yolov5_images_dir)
    77. yolov5_labels_dir = os.path.join(data_base_dir, "labels/")
    78. if not os.path.isdir(yolov5_labels_dir):
    79. os.mkdir(yolov5_labels_dir)
    80. clear_hidden_files(yolov5_labels_dir)
    81. yolov5_images_train_dir = os.path.join(yolov5_images_dir, "train/")
    82. if not os.path.isdir(yolov5_images_train_dir):
    83. os.mkdir(yolov5_images_train_dir)
    84. clear_hidden_files(yolov5_images_train_dir)
    85. yolov5_images_test_dir = os.path.join(yolov5_images_dir, "val/")
    86. if not os.path.isdir(yolov5_images_test_dir):
    87. os.mkdir(yolov5_images_test_dir)
    88. clear_hidden_files(yolov5_images_test_dir)
    89. yolov5_labels_train_dir = os.path.join(yolov5_labels_dir, "train/")
    90. if not os.path.isdir(yolov5_labels_train_dir):
    91. os.mkdir(yolov5_labels_train_dir)
    92. clear_hidden_files(yolov5_labels_train_dir)
    93. yolov5_labels_test_dir = os.path.join(yolov5_labels_dir, "val/")
    94. if not os.path.isdir(yolov5_labels_test_dir):
    95. os.mkdir(yolov5_labels_test_dir)
    96. clear_hidden_files(yolov5_labels_test_dir)
    97. train_file = open(os.path.join(wd, "yolov5_train.txt"), 'w')
    98. test_file = open(os.path.join(wd, "yolov5_val.txt"), 'w')
    99. train_file.close()
    100. test_file.close()
    101. train_file = open(os.path.join(wd, "yolov5_train.txt"), 'a')
    102. test_file = open(os.path.join(wd, "yolov5_val.txt"), 'a')
    103. list_imgs = os.listdir(image_dir) # list image files
    104. prob = random.randint(1, 100)
    105. print("Probability: %d" % prob)
    106. for i in range(0, len(list_imgs)):
    107. path = os.path.join(image_dir, list_imgs[i])
    108. if os.path.isfile(path):
    109. image_path = image_dir + list_imgs[i]
    110. voc_path = list_imgs[i]
    111. (nameWithoutExtention, extention) = os.path.splitext(os.path.basename(image_path))
    112. (voc_nameWithoutExtention, voc_extention) = os.path.splitext(os.path.basename(voc_path))
    113. annotation_name = nameWithoutExtention + '.xml'
    114. annotation_path = os.path.join(annotation_dir, annotation_name)
    115. label_name = nameWithoutExtention + '.txt'
    116. label_path = os.path.join(yolo_labels_dir, label_name)
    117. prob = random.randint(1, 100)
    118. print("Probability: %d" % prob)
    119. if (prob < TRAIN_RATIO): # train dataset
    120. if os.path.exists(annotation_path):
    121. train_file.write(image_path + '\n')
    122. convert_annotation(nameWithoutExtention) # convert label
    123. copyfile(image_path, yolov5_images_train_dir + voc_path)
    124. copyfile(label_path, yolov5_labels_train_dir + label_name)
    125. else: # test dataset
    126. if os.path.exists(annotation_path):
    127. test_file.write(image_path + '\n')
    128. convert_annotation(nameWithoutExtention) # convert label
    129. copyfile(image_path, yolov5_images_test_dir + voc_path)
    130. copyfile(label_path, yolov5_labels_test_dir + label_name)
    131. train_file.close()
    132. test_file.close()
    • 修改class类别标签名
    • 修改TRAIN_RATIO,划分训练数据集和验证数据集比例8:2
    • 修改文件路径

    第一处:

    1. in_file = open('InsectImg/RawInsect/Annotations/%s.xml' % image_id)
    2. out_file = open('InsectImg/RawInsect/YOLOLabels/%s.txt' % image_id, 'w')

    第二处:

    1. data_base_dir = os.path.join(wd, "InsectImg/")
    2. if not os.path.isdir(data_base_dir):
    3. os.mkdir(data_base_dir)
    4. work_sapce_dir = os.path.join(data_base_dir, "RawInsect/")

     4、配置YOLOv5数据环境

    data文件夹下,仿照coco.yaml,创建insect.yaml文件

    • 修改train训练数据集路径
    • 修改val验证数据集路径
    • 修改nc类别数
    • 修改names列表标签名

     在models文件夹下,仿照yolov5l.yaml,创建yolov5l_insect.yaml文件

    • 修改nc类别数

    weights文件夹下,存放从GitHub上下载的yolov5l6.pt

    注意:如果YOLOv5系列有n、s、m、l、x,models文件夹下创建什么类型的模型,weights文件夹下要存放相应的训练好的模型pt文件。

    5、修改train.py参数

    一般情况下,需要修改参数: 

    • 修改 --weights路径
    • 修改--cfg配置模型路径
    • 修改--data图像数据路径
    • 根据电脑GPU核,设置--batch-size
    • 根据n、s、m、l、x,设置--imgsz,YOLOv5l输入图像大小设置为640
    • 一般--resume设置为False,如果因电脑重启导致训练中断,可以设置为True,接着上一次的结果继续训练
    • epochs一般300,也可以根据训练情况调整

    其他参数可以根据情况自动设置

    6、运行train.py 进行模型训练

    训练模型结果保存在路径

    E:\Code\Python\yolov5\runs\train\exp

    该路径下的weights文件夹生成了last.pt和best.pt两个文件,选择best.pt作为移植模型。

    三、YOLOv5模型移植

    1、修改export.py文件

    • 修改--data,为自己数据的.yaml文件
    • 修改--weights,为上一步YOLOv5l训练得到best.pt最佳路径
    • 修改--imgsz,一般设置为320
    • 修改--include,根据实际案例,可以选择tflite/onnx/pb等。

    运行export.py导出量化后的模型

    2、量化后模型移植终端

    配置终端环境,调用量化后的模型。

  • 相关阅读:
    数据结构——链表
    数据治理-组织触点
    asp毕业设计——基于asp+sqlserver的工厂设备管理系统设计与实现(毕业论文+程序源码)——工厂设备管理系统
    NOIP-2023模拟题
    ArcGIS Pro和ArcGIS有什么区别和联系,优势有哪些?
    Chrome扩展程序开发随记
    java学习——异常处理机制
    MES系统防呆措施之具体场景学习
    运营干货:虾皮店铺装修怎么做?
    [PAT-Advanced] A1054. The Dominant Color (20)
  • 原文地址:https://blog.csdn.net/miao0967020148/article/details/130859792