• yolov5训练模型


    目录

    划分数据集 

    生成数据集路径txt文件(xml转txt) 

     编写配置文件

    data

    cfg

    训练模型

     训练可视化

    报错

    运行在远程服务器

    检测目标(查看效果)


    划分数据集 

    split_train_val.py

    1. import os
    2. import random
    3. import argparse
    4. parser = argparse.ArgumentParser()
    5. # 标注文件的地址,根据自己的标注文件所在的位置进行修改
    6. parser.add_argument('--label_path', default='/data/test/txt', type=str, help='input label path')
    7. # 数据集的划分输出地址,可以自己定
    8. parser.add_argument('--save_path', default='imageSets/Path', type=str, help='output txt label path')
    9. opt = parser.parse_args()
    10. train_val_percent = 0.95 # 训练集和验证集所占比例,剩下的部分就是测试集。
    11. train_percent = 8 / 9 # 训练集所占比例,可自己进行调整
    12. label_file_path = opt.label_path
    13. txt_save_path = opt.save_path
    14. total_label = os.listdir(label_file_path)
    15. if not os.path.exists(txt_save_path):
    16. os.makedirs(txt_save_path)
    17. num = len(total_label)
    18. list_index = range(num)
    19. tv = int(num * train_val_percent)
    20. tr = int(tv * train_percent)
    21. trainval = random.sample(list_index, tv)
    22. train = random.sample(trainval, tr)
    23. file_trainval = open(txt_save_path + '/trainval.txt', 'w')
    24. file_test = open(txt_save_path + '/test.txt', 'w')
    25. file_train = open(txt_save_path + '/train.txt', 'w')
    26. file_val = open(txt_save_path + '/val.txt', 'w')
    27. for i in list_index:
    28. name = total_label[i][:-4] + '\n'
    29. if i in trainval:
    30. file_trainval.write(name)
    31. if i in train:
    32. file_train.write(name)
    33. else:
    34. file_val.write(name)
    35. else:
    36. file_test.write(name)
    37. file_trainval.close()
    38. file_train.close()
    39. file_val.close()
    40. file_test.close()

     终端输入以下命令:

    python3 split_train_val.py

    (Tips:如果运行失败,将python3修改成python)

    例:train.txt

    生成数据集路径txt文件(xml转txt) 

    1. # -*- coding: utf-8 -*-
    2. import xml.etree.ElementTree as ET
    3. import os
    4. from os import getcwd
    5. sets = ['train', 'val', 'test']
    6. classes = ["test"] # 改成自己的类别
    7. abs_path = os.getcwd()
    8. print(abs_path)
    9. def convert(size, box):
    10. dw = 1. / (size[0])
    11. dh = 1. / (size[1])
    12. x = (box[0] + box[1]) / 2.0 - 1
    13. y = (box[2] + box[3]) / 2.0 - 1
    14. w = box[1] - box[0]
    15. h = box[3] - box[2]
    16. x = x * dw
    17. w = w * dw
    18. y = y * dh
    19. h = h * dh
    20. return x, y, w, h
    21. def convert_annotation(image_ID):
    22. in_file = open('D:/dataSet/marking/%s.xml' % image_ID, encoding='UTF-8')
    23. out_file = open('D:/dataSet/labels/%s.txt' % image_ID, 'w')
    24. tree = ET.parse(in_file)
    25. root = tree.getroot()
    26. size = root.find('size')
    27. w = int(size.find('width').text)
    28. h = int(size.find('height').text)
    29. for obj in root.iter('object'):
    30. difficult = obj.find('difficult').text
    31. # difficult = obj.find('Difficult').text
    32. cls = obj.find('name').text
    33. if cls not in classes or int(difficult) == 1:
    34. continue
    35. cls_id = classes.index(cls)
    36. xmlbox = obj.find('bndbox')
    37. b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
    38. float(xmlbox.find('ymax').text))
    39. b1, b2, b3, b4 = b
    40. # 标注越界修正
    41. if b2 > w:
    42. b2 = w
    43. if b4 > h:
    44. b4 = h
    45. b = (b1, b2, b3, b4)
    46. bb = convert((w, h), b)
    47. out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
    48. wd = getcwd()
    49. for image_set in sets:
    50. image_ids = open('imageSets/Main/%s.txt' % image_set).read().strip().split()
    51. if not os.path.exists('imageSets/dataSet_path/'):
    52. os.makedirs('imageSets/dataSet_path/')
    53. list_file = open('imageSets/dataSet_path/%s.txt' % image_set, 'w')
    54. # 这行路径不需更改,这是相对路径
    55. for image_id in image_ids:
    56. list_file.write('/data/basketball/images/%s.jpg\n' % image_id)
    57. # convert_annotation(image_id) # 如果是xml标注文件转txt文件就删除最左边的#号
    58. list_file.close()

    (Tips:yolov5中txt标注文件夹应命名为labels,并与图片所在文件夹images处于同级目录)

    运行效果: 

     编写配置文件

    data

    在yolov5/data目录下新建xxxx.yaml(自己命名,例如:test.yaml),内容模板如下:

    1. train: /test/imageSets/dataSet_path/train.txt
    2. val: /test/ly01/imageSets/dataSet_path/val.txt
    3. # test: /test/imageSets/dataSet_path/test.txt
    4. # number of classes
    5. nc: 1
    6. # class names
    7. names: ["test"] # 自己的类别

    (Tips:从这里可以看出,我们只告诉了yolov5图片路径,因为yolov5会去与images同级目录下的labels寻找标注txt文件) 

    cfg

    在yolov5/models目录下新建xxxx.yaml(自己命名,例如yolov5t.yaml),内容根据希望训练的模型而变,例如我希望训练成像yolov5s.pt一样的模型,那就复制yolov5s.yaml中的内容到新建的yaml文件中,然后将nc(标注类别数目)修改成和上面一样的大小。

    1. # YOLOv5 🚀 by Ultralytics, GPL-3.0 license
    2. # Parameters
    3. nc: 1 # number of classes
    4. depth_multiple: 0.33 # model depth multiple
    5. width_multiple: 0.50 # layer channel multiple
    6. anchors:
    7. - [10,13, 16,30, 33,23] # P3/8
    8. - [30,61, 62,45, 59,119] # P4/16
    9. - [116,90, 156,198, 373,326] # P5/32
    10. # YOLOv5 v6.0 backbone
    11. backbone:
    12. # [from, number, module, args]
    13. [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2
    14. [-1, 1, Conv, [128, 3, 2]], # 1-P2/4
    15. [-1, 3, C3, [128]],
    16. [-1, 1, Conv, [256, 3, 2]], # 3-P3/8
    17. [-1, 6, C3, [256]],
    18. [-1, 1, Conv, [512, 3, 2]], # 5-P4/16
    19. [-1, 9, C3, [512]],
    20. [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
    21. [-1, 3, C3, [1024]],
    22. [-1, 1, SPPF, [1024, 5]], # 9
    23. ]
    24. # YOLOv5 v6.0 head
    25. head:
    26. [[-1, 1, Conv, [512, 1, 1]],
    27. [-1, 1, nn.Upsample, [None, 2, 'nearest']],
    28. [[-1, 6], 1, Concat, [1]], # cat backbone P4
    29. [-1, 3, C3, [512, False]], # 13
    30. [-1, 1, Conv, [256, 1, 1]],
    31. [-1, 1, nn.Upsample, [None, 2, 'nearest']],
    32. [[-1, 4], 1, Concat, [1]], # cat backbone P3
    33. [-1, 3, C3, [256, False]], # 17 (P3/8-small)
    34. [-1, 1, Conv, [256, 3, 2]],
    35. [[-1, 14], 1, Concat, [1]], # cat head P4
    36. [-1, 3, C3, [512, False]], # 20 (P4/16-medium)
    37. [-1, 1, Conv, [512, 3, 2]],
    38. [[-1, 10], 1, Concat, [1]], # cat head P5
    39. [-1, 3, C3, [1024, False]], # 23 (P5/32-large)
    40. [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
    41. ]

    训练模型

    做完前面的准备工作以后就可以开始训练模型了,我们使用yolov5目录下的train.py进行训练,train.py有许多参数,其中比较重要的有以下几个:

    1. weights: 权重文件的路径
    2. cfg: 存储模型结构的配置文件,也就是之前创建的yolov5t.yaml
    3. data: 存储训练、测试数据的文件,也就是之前创建的test.yaml
    4. epochs: 迭代次数,在训练过程中数据集将进行这么多次迭代
    5. batch-size: “看完”多少张图片以后才进行一次权重更新
    6. img-size: 输入图片宽高
    7. device: 使用GPU还是CPU进行训练
    8. workers: 线程数
    9. resume: 使用最近保存的模型开始训练

    还有一些其他参数,可以看每个参数里面的help知道是什么作用,每个参数有默认值。 

     终端进入yolov5项目文件夹,根据自己的需要参数修改训练命令,例如:

    python3 train.py --weights runs/train/exp2/weights/last.pt  --cfg models/yolov5t.yaml  --data data/test.yaml --epoch 200 --batch-size 8 --img 1280   --device 1 --workers 2

     训练可视化

    终端进入yolov5项目文件夹,输入:

    tensorboard --logdir=runs
    

    报错

    如果出现报错,应该是字体没找到,下载以后放在项目根目录就行

     运行效果:

     然后在浏览器打开网址就行

    运行在远程服务器

     自己的电脑上与远程服务器就行一个链接就行,和jupyternotebook一样,终端输入:

    1. # 模板
    2. ssh -N -f -L localhost:port1:localhost:port2 username@IP
    3. # 说明
    4. # port1: 自己电脑上随便一个空闲端口就行
    5. # port2: 之前在ubuntu服务启动notebook的端口,记着的那个
    6. # username: ubuntu用户名
    7. # IP: ubuntu服务器IP,公网IP或者私网IP
    8. # 示例: ssh -N -f -L localhost:8888:localhost:8888 hhh@198.162.1.1

    然后在自己的电脑上访问localhost:port1即可

    检测目标(查看效果)

    在yolov5/data/images目录下存放要检测的图像或视频,然后终端进入项目根目录,输入命令:

    python3 detect.py --weights runs/train/exp/weights/best.pt

    --weights后的路径根据实际情况修改

    参考:YOLOv5训练自己的数据集(超详细完整版)_深度学习菜鸟的博客-CSDN博客_yolov5

  • 相关阅读:
    Android shape与selector标签使用
    万字长文:我眼中区块链各赛道正在演进的技术趋势
    管理类联考——英语二——阅读篇——题材:教育
    国内chatgpt写作软件,chatgpt国内使用
    Go 语言结构体验证详解:validate 标签与自定义规则
    宋浩高等数学笔记(一)函数与极限
    (四)DDD之“架构”——没有规矩,不成方圆
    人机交互中的数字与文字
    大数据(二)大数据架构发展史
    TiDB 社区智慧合集丨TiDB 相关 SQL 脚本大全
  • 原文地址:https://blog.csdn.net/weixin_52470573/article/details/127707526