当前位置:   article > 正文

使用Bubbliiiing版本的yolov7训练自定义VOC格式的数据集_yolov7bu'b

yolov7bu'b

目录

1.下载yolov7源码

2.下载权重文件

3.制作yolo数据集

4.训练

5.测试

6.参考视频


1.下载yolov7源码

去github上打包下载,下载地址:

bubbliiiing/yolov7-pytorch: 这是一个yolov7的库,可以用于训练自己的数据集。 (github.com)

如果github打不开可以去这里下载:项目目录预览 - yolov7-pytorch - GitCode

也可以使用git clone命令克隆项目。

git clone https://github.com/bubbliiiing/yolov7-pytorch

2.下载权重文件

在readme文件里找到百度网盘下载地址下载:

下载好之后直接放在yolov7源码的model_data文件夹里就行了:

3.制作yolo数据集

项目根目录已有如下所示的文件目录:

首先将自己的图片文件放到JPEGImages文件夹中,将xml文件放到Annotations文件夹中,

然后在model_data目录下创建一个txt文件(我把它命名为cla_classes.txt)以存放类别标签名

接着使用脚本voc_annotation.py(在根目录)进行数据集的划分以及格式的转换,

我们需要修改classes_path来找到我们上一把制作的txt文件:

然后运行脚本,会生成如下几个文件:

VOCdevkit/VOC2007/ImageSets里面的4个txt文件存放的是图片的文件名:

2007_train.txt、2007_val.txt存放的是图片路径以及对应的标注信息:

脚本voc_annotation.py代码如下:

  1. import os
  2. import random
  3. import xml.etree.ElementTree as ET
  4. import numpy as np
  5. from utils.utils import get_classes
  6. #--------------------------------------------------------------------------------------------------------------------------------#
  7. # annotation_mode用于指定该文件运行时计算的内容
  8. # annotation_mode0代表整个标签处理过程,包括获得VOCdevkit/VOC2007/ImageSets里面的txt以及训练用的2007_train.txt、2007_val.txt
  9. # annotation_mode1代表获得VOCdevkit/VOC2007/ImageSets里面的txt
  10. # annotation_mode2代表获得训练用的2007_train.txt、2007_val.txt
  11. #--------------------------------------------------------------------------------------------------------------------------------#
  12. annotation_mode = 0
  13. #-------------------------------------------------------------------#
  14. # 必须要修改,用于生成2007_train.txt、2007_val.txt的目标信息
  15. # 与训练和预测所用的classes_path一致即可
  16. # 如果生成的2007_train.txt里面没有目标信息
  17. # 那么就是因为classes没有设定正确
  18. # 仅在annotation_mode02的时候有效
  19. #-------------------------------------------------------------------#
  20. classes_path = 'model_data/cls_classes.txt'
  21. #--------------------------------------------------------------------------------------------------------------------------------#
  22. # trainval_percent用于指定(训练集+验证集)与测试集的比例,默认情况下 (训练集+验证集):测试集 = 9:1
  23. # train_percent用于指定(训练集+验证集)中训练集与验证集的比例,默认情况下 训练集:验证集 = 9:1
  24. # 仅在annotation_mode01的时候有效
  25. #--------------------------------------------------------------------------------------------------------------------------------#
  26. trainval_percent = 0.9
  27. train_percent = 0.9
  28. #-------------------------------------------------------#
  29. # 指向VOC数据集所在的文件夹
  30. # 默认指向根目录下的VOC数据集
  31. #-------------------------------------------------------#
  32. VOCdevkit_path = 'VOCdevkit'
  33. VOCdevkit_sets = [('2007', 'train'), ('2007', 'val')]
  34. classes, _ = get_classes(classes_path)
  35. #-------------------------------------------------------#
  36. # 统计目标数量
  37. #-------------------------------------------------------#
  38. photo_nums = np.zeros(len(VOCdevkit_sets))
  39. nums = np.zeros(len(classes))
  40. def convert_annotation(year, image_id, list_file):
  41. in_file = open(os.path.join(VOCdevkit_path, 'VOC%s/Annotations/%s.xml'%(year, image_id)), encoding='utf-8')
  42. tree=ET.parse(in_file)
  43. root = tree.getroot()
  44. for obj in root.iter('object'):
  45. difficult = 0
  46. if obj.find('difficult')!=None:
  47. difficult = obj.find('difficult').text
  48. cls = obj.find('name').text
  49. if cls not in classes or int(difficult)==1:
  50. continue
  51. cls_id = classes.index(cls)
  52. xmlbox = obj.find('bndbox')
  53. b = (int(float(xmlbox.find('xmin').text)), int(float(xmlbox.find('ymin').text)), int(float(xmlbox.find('xmax').text)), int(float(xmlbox.find('ymax').text)))
  54. list_file.write(" " + ",".join([str(a) for a in b]) + ',' + str(cls_id))
  55. nums[classes.index(cls)] = nums[classes.index(cls)] + 1
  56. if __name__ == "__main__":
  57. random.seed(0)
  58. if " " in os.path.abspath(VOCdevkit_path):
  59. raise ValueError("数据集存放的文件夹路径与图片名称中不可以存在空格,否则会影响正常的模型训练,请注意修改。")
  60. if annotation_mode == 0 or annotation_mode == 1:
  61. print("Generate txt in ImageSets.")
  62. xmlfilepath = os.path.join(VOCdevkit_path, 'VOC2007/Annotations')
  63. saveBasePath = os.path.join(VOCdevkit_path, 'VOC2007/ImageSets/Main')
  64. temp_xml = os.listdir(xmlfilepath)
  65. total_xml = []
  66. for xml in temp_xml:
  67. if xml.endswith(".xml"):
  68. total_xml.append(xml)
  69. num = len(total_xml)
  70. list = range(num)
  71. tv = int(num*trainval_percent)
  72. tr = int(tv*train_percent)
  73. trainval= random.sample(list,tv)
  74. train = random.sample(trainval,tr)
  75. print("train and val size",tv)
  76. print("train size",tr)
  77. ftrainval = open(os.path.join(saveBasePath,'trainval.txt'), 'w')
  78. ftest = open(os.path.join(saveBasePath,'test.txt'), 'w')
  79. ftrain = open(os.path.join(saveBasePath,'train.txt'), 'w')
  80. fval = open(os.path.join(saveBasePath,'val.txt'), 'w')
  81. for i in list:
  82. name=total_xml[i][:-4]+'\n'
  83. if i in trainval:
  84. ftrainval.write(name)
  85. if i in train:
  86. ftrain.write(name)
  87. else:
  88. fval.write(name)
  89. else:
  90. ftest.write(name)
  91. ftrainval.close()
  92. ftrain.close()
  93. fval.close()
  94. ftest.close()
  95. print("Generate txt in ImageSets done.")
  96. if annotation_mode == 0 or annotation_mode == 2:
  97. print("Generate 2007_train.txt and 2007_val.txt for train.")
  98. type_index = 0
  99. for year, image_set in VOCdevkit_sets:
  100. image_ids = open(os.path.join(VOCdevkit_path, 'VOC%s/ImageSets/Main/%s.txt'%(year, image_set)), encoding='utf-8').read().strip().split()
  101. list_file = open('%s_%s.txt'%(year, image_set), 'w', encoding='utf-8')
  102. for image_id in image_ids:
  103. list_file.write('%s/VOC%s/JPEGImages/%s.jpg'%(os.path.abspath(VOCdevkit_path), year, image_id))
  104. convert_annotation(year, image_id, list_file)
  105. list_file.write('\n')
  106. photo_nums[type_index] = len(image_ids)
  107. type_index += 1
  108. list_file.close()
  109. print("Generate 2007_train.txt and 2007_val.txt for train done.")
  110. def printTable(List1, List2):
  111. for i in range(len(List1[0])):
  112. print("|", end=' ')
  113. for j in range(len(List1)):
  114. print(List1[j][i].rjust(int(List2[j])), end=' ')
  115. print("|", end=' ')
  116. print()
  117. str_nums = [str(int(x)) for x in nums]
  118. tableData = [
  119. classes, str_nums
  120. ]
  121. colWidths = [0]*len(tableData)
  122. len1 = 0
  123. for i in range(len(tableData)):
  124. for j in range(len(tableData[i])):
  125. if len(tableData[i][j]) > colWidths[i]:
  126. colWidths[i] = len(tableData[i][j])
  127. printTable(tableData, colWidths)
  128. if photo_nums[0] <= 500:
  129. print("训练集数量小于500,属于较小的数据量,请注意设置较大的训练世代(Epoch)以满足足够的梯度下降次数(Step)。")
  130. if np.sum(nums) == 0:
  131. print("在数据集中并未获得任何目标,请注意修改classes_path对应自己的数据集,并且保证标签名字正确,否则训练将会没有任何效果!")
  132. print("在数据集中并未获得任何目标,请注意修改classes_path对应自己的数据集,并且保证标签名字正确,否则训练将会没有任何效果!")
  133. print("在数据集中并未获得任何目标,请注意修改classes_path对应自己的数据集,并且保证标签名字正确,否则训练将会没有任何效果!")
  134. print("(重要的事情说三遍)。")

这里有一点需要说明,就是脚本voc_annotation.py里的annotation_mode参数,如果你没有上图的文件,即VOCdevkit/VOC2007/ImageSets里面的4个txt文件以及2007_train.txt、2007_val.txt,那么就使annotation_mode=0;如果只有2007_train.txt、2007_val.txt,那么就使annotation_mode=1;如果只有VOCdevkit/VOC2007/ImageSets里面的4个txt文件,那么就使annotation_mode=2。

4.训练

在train.py里有一个需要修改的地方,还是类别文件的路径:

其他的参数可以根据自己的需要修改。然后运行train.py即可。

5.测试

训练结束后,可以进行。训练结束后会生成最好权重文件命名为best_epoch_weights.pth:

我们使用best_epoch_weights.pth进行测试,

首先需要修改yolo.py:

接着在运行predict.py,输入待检测的图片路径即可检测:

如果出现报错:

AttributeError: 'ImageDraw' object has no attribute 'textsize'

主要原因就是最新的Pillow 10.0.0 版本已经删除了这个属性

解决方法是降低Pillow版本:

先卸载 Pillow:

pip uninstall Pillow

再安装旧版本:

pip install Pillow==9.5.0

测试结果如下:

6.参考视频

Pytorch 搭建自己的YoloV7目标检测平台(Bubbliiiing 源码详解 训练 预测)_哔哩哔哩_bilibili

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/818240
推荐阅读
相关标签
  

闽ICP备14008679号