Ubuntu16.04 搭建YOLOv5及训练自己的数据集

具体参考:(如果侵权,速删)
1.https://blog.csdn.net/u013171226/article/details/115064641
2.https://blog.csdn.net/qq_45646174/article/details/112913012
3.https://zhuanlan.zhihu.com/p/156835045?from_voters_page=true
4.https://blog.csdn.net/weixin_48695781/article/details/121677849
5.https://blog.csdn.net/didiaopao/article/details/119954291
6.https://blog.csdn.net/m0_53392188/article/details/119334634

环境:

Nvidia RTX 3060
Ubuntu 16.04
CUDA 11.1
cuDNN 8.2.0
torch 1.10.1+cu111
torchvision 0.11.2+cu111

如果不是从头开始,退出并删除虚拟环境

source deactivate //退出虚拟环境
conda remove -n yolov5 --all //删除虚拟环境
conda env list //查看虚拟环境列表

一.搭建YOLOv5深度学习环境

1.使用conda创建YOLOv5需要的环境
conda create -n yolov5 python=3.7  //yolov5是虚拟环境的名字
source activate yolov5
2.然后下载YOLOv5工程
git clone https://github.com/ultralytics/yolov5  

yolov5-1.png

如果出现问题:fatal: unable to access 'https://github.com/ultralytics/yolov5/': gnutls_handshake() failed: The TLS connection was non-properly terminated.
参考:https://www.jianshu.com/p/b38ef810fe24
如果出现问题:fatal: remote error:
The unauthenticated git protocol on port 9418 is no longer supported.
Please see https://github.blog/2021-09-01-improving-git-protocol-security-github/ for more information.
参考:https://www.jianshu.com/p/b38ef810fe24

3.安装依赖
cd yolov5

(1)可以使用pip命令安装

pip install -r requirements.txt  

(2)pytorch也可自行安装,注意pytorch和cuda版本需对应,官网地址:https://pytorch.org/get-started/previous-versions/
对应关系如下:

55pytorchCUDA.png

本文选择使用官网命令进行安装,torch 1.10.1+cu111,torchvision 0.11.2+cu111

pip install torch==1.10.1+cu111 torchvision==0.11.2+cu111 torchaudio==0.10.1 -f https://download.pytorch.org/whl/torch_stable.html
yolov5-15.png

二.准备自己的数据集

1.标注文件

用labelimg标注自己的数据集,利用labelimg标注数据的时候,注意选择生成的txt格式为yolo格式


image.png

按照下图格式创建数据集
文件夹下:images + labels
其中images文件夹中存放图片,labels文件夹中存放标签txt


yolov5-3.png
2.创建一个split_train_val.py文件,代码内容如下:
# coding:utf-8

import os
import random
import argparse

parser = argparse.ArgumentParser()
#xml文件的地址,根据自己的数据进行修改 xml一般存放在Annotations下
parser.add_argument('--xml_path', default='/home/slave110/yolov5/eddy316/labels', type=str, help='input xml label path')
#数据集的划分,地址选择自己数据下的ImageSets/Main
parser.add_argument('--txt_path', default='/home/slave110/yolov5/demo1', type=str, help='output txt label path')
opt = parser.parse_args()

trainval_percent = 1.0
train_percent = 0.6
xmlfilepath = opt.xml_path
txtsavepath = opt.txt_path
total_xml = os.listdir(xmlfilepath)
if not os.path.exists(txtsavepath):
    os.makedirs(txtsavepath)

num = len(total_xml)
list_index = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list_index, tv)
train = random.sample(trainval, tr)

file_trainval = open(txtsavepath + '/trainval.txt', 'w')
file_test = open(txtsavepath + '/test.txt', 'w')
file_train = open(txtsavepath + '/train.txt', 'w')
file_val = open(txtsavepath + '/val.txt', 'w')

for i in list_index:
    name = total_xml[i][:-4] + '\n'
    if i in trainval:
        file_trainval.write(name)
        if i in train:
            file_train.write(name)
        else:
            file_val.write(name)
    else:
        file_test.write(name)

file_trainval.close()
file_train.close()
file_val.close()
file_test.close()

运行代码

python split_train_val.py

然后新建的demo1文件夹中会生成四个txt文件


yolov5-5.png

不知道为什么我标注的图片是从1始


yolov5-7.png

所以写了个小程序,将每一行的第一列减1,在写入新的文件夹中

import os

path = '/home/slave110/yolov5/eddy316/labels' 
path_result = r'/home/slave110/yolov5/eddy316/labels111'


for name in os.listdir(path):
   print(path + name)
   f = open(path + '/' + name, 'r')
   result = open(path_result + '/' + name,'w')
   while 1:
      line = f.readline()
      if not line:
         break
      values = line.split(' ');
      first = int(values[0]) - 1
      new_1 = str(first) + ' ' + values[1] + ' ' + values[2] + ' ' + values[3] + ' ' + values[4] 
      result.write(new_1)
   f.close()
   result.close()

处理之后如下所示:


yolov5-8.png
3.创建voc_label.py文件,将训练集、验证集、测试集生成label标签(训练中要用到),同时将数据集路径导入txt文件中,代码内容如下:
# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import os
from os import getcwd

sets = ['train', 'val']
classes = ["Repelling Focus", "Attracting Focus" , "Center" , "Saddle Point"]   # 改成自己的类别
abs_path = os.getcwd()
print(abs_path)

#def convert(size, box):
 #   dw = 1. / (size[0])
 #   dh = 1. / (size[1])
 #   x = (box[0] + box[1]) / 2.0 - 1
 #   y = (box[2] + box[3]) / 2.0 - 1
 #   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('/home/slave110/yolov5/eddy316/%s.xml' % (image_id), encoding='UTF-8')
    out_file = open('/home/trainingai/zyang/yolov5/paper_data/labels/%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)
    for obj in root.iter('object'):
        # difficult = obj.find('difficult').text
        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))
        b1, b2, b3, b4 = b
        # 标注越界修正
        if b2 > w:
            b2 = w
        if b4 > h:
            b4 = h
        b = (b1, b2, b3, b4)
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')

wd = getcwd()
for image_set in sets:
    if not os.path.exists('home/slave110/yolov5/eddy316/labels/'):
        os.makedirs('home/slave110/yolov5/eddy316/labels/')
    image_ids = open('/home/slave110/yolov5/demo1/%s.txt' % (image_set)).read().strip().split()
    list_file = open('/home/slave110/yolov5/txt/%s.txt' % (image_set), 'w')
    for image_id in image_ids:
        list_file.write(abs_path + '/eddy316/images/%s.bmp\n' % (image_id)) //注意:图片格式
        #convert_annotation(image_id)
    list_file.close()

新建文件夹txt,执行命令:

python voc_label.py 

文件夹中会出现三个txt,其中test.txt是我手动加的


yolov5-9.png

txt中的内容如下:


yolov5-10.png
3.配置文件
1)数据集的配置

在yolov5目录下的data文件夹下新建一个ab.yaml文件(可以自定义命名),用来存放训练集和验证集的划分文件(train.txt和val.txt),这两个文件是通过运行voc_label.py代码生成的,然后是目标的类别数目和具体类别列表,ab.yaml内容如下:

train: /home/slave110/yolov5/txt/train.txt
val: /home/slave110/yolov5/txt/val.txt

#number of classes 
nc: 4

#class names
names: ['Repelling Focus', 'Attracting Focus', 'Center', 'Saddle Point']
2)修改/model/yolov5s.yaml

将 nc : 80 改成 nc : 4

训练命令:python train.py --img 1000 --batch 4 --epoch 100 --data data/ab.yaml --cfg models/yolov5s.yaml --weights yolov5s.pt --device '0'

python train.py --img 640 --batch 4 --epoch 300 --data data/ab.yaml --cfg models/yolov5s.yaml --weights yolov5s.pt --device '0'     # 0号GPU

你可能感兴趣的:(Ubuntu16.04 搭建YOLOv5及训练自己的数据集)