YOLOv5训练个人数据集总结

17 篇文章 0 订阅
5 篇文章 0 订阅

已记录一下自己的代码在GPU服务器端跑的时候流程和遇到的问题以及解决方法。

需要具备部分基础知识。

声明

国际惯例,写在前面

-----------------------------------------------------------------------------------------------

声明:本文章仅供个人学习之用,由于作者能力有限,相关观点和信息仅供参考。

如有侵权请联系。

欢迎各位读者老爷提问和交流。

我们的目标是星辰大海!

1. 准备情况

因为公司原因,通知xshell和xftp没有版权,不让用了。如何解决远程登录到服务器上成为了第一个问题。

01. 通过vscode实现远程连接服务器

(1)安装remote插件。

安装 Remote Development插件,会自动安装这么多个。

 (2)连接到服务器

 

点击这里的加号,被水印挡住了,或者按按下shift+ctrl+p,输入Remote-SSH: Connect to Host。

输入你要远程访问的IP地址

 你可以每次都输入密码,或者自行配置

Host代表连接的名称(自定义)

HostName是服务器的地址

IdentityFile是免密登录需要的 是本地id_rsa文件的路径

User是登录服务器的用户名

Port是端口号

IdentitiesOnly也是免密登录值为yes 

 

02. 通过安装anaconda来安装虚拟环境

(1)下载anaconda

# 切换root用户,输入密码
su root
# 进入root目录,安装脚本存放路径
cd /root
# 下载anaconda安装脚本(本教程采用清华源)
wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2020.07-Linux-x86_64.sh
# 安装anaconda
bash Anaconda3-2020.07-Linux-x86_64.sh

# Please, press ENTER to continue -> 回车继续
# 阅读协议,同意按回车(跳过ctrl+c)
# Do you accept the license terms? [yes|no] -> 同意协议输入yes回车
# Anaconda3 will now be installed into this location -> 选择安装路径(本文安装/usr/local/anaconda3),等待安装
# by running conda init? [yes|no] -> 是否添加系统环境,输入yes回车
# 待安装结束

# 刷新当前用户环境(激活环境)
source ~/.bashrc



#添加国内源
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --set show_channel_urls yes

## 新建虚拟环境
conda create -n python36 python=3.6.5
# 删除虚拟环境
conda remove -n python36 --all

# 查看所有环境
conda env list
# 激活虚拟环境
conda activate python36
# 退出当前虚拟环境
conda deactivate python36

一定要记得最后一句,刷新

(2)使用conda安装requirement.txt,pip报错

$ git clone https://github.com/ultralytics/yolov5
$ cd yolov5
$ pip3 install -r requirements.txt

while read requirement; do conda install --yes $requirement || pip install $requirement; done < requirements.txt

03.训练自己数据集过程

(1)自己的数据集有几类,要和yaml文件中对应起来,我这里使用的是yolov5s,2类

(2) 照抄一个yaml文件,修改一下,需要按照自己的数据类型具体修改。

在data路径下,新建一个自己的xxx.yaml

需要修改的东西非常少,就是训练集,测试集,测试类别,类别名称。

但是需要注意的是,train:后面有个空格,跟的是你的数据的路径,注意,这里知道文件夹,当时看csdn看到一个写到train.txt的我一度以为我有问题

 在这里我产生了问题,

我获取到的数据比较干净,在Annotations中是已经标注好的v5.txt格式 ,JPEGImages里面是原图片。

注意细节:

├── data
│   ├── Annotations  进行 detection 任务时的标签文件,xml 形式,文件名与图片名一一对应
│   ├── images  存放 .jpg 格式的图片文件
│   ├── ImageSets  存放的是分类和检测的数据集分割文件,包含train.txt, val.txt,trainval.txt,test.txt
│   ├── labels  存放label标注信息的txt文件,与图片一一对应


├── ImageSets(train,val,test建议按照8:1:1比例划分)
│   ├── train.txt  写着用于训练的图片名称
│   ├── val.txt  写着用于验证的图片名称
│   ├── trainval.txt  train与val的合集
│   ├── test.txt  写着用于测试的图片名称

 

yolov5使用的是txt格式,每个图像对应一个txt文件,文件每一行为一个目标的信息,包括class,x_center,y_center,width,height格式。

格式如下:

那么问题来了。

很多朋友的数据都是标准的xml格式。

第一步,我们需要把xml转换成txt

xml2txt.py

# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join

#import shutil

sets = ['train', 'test', 'val']

#classes = ['1', '2', '3', '4', '5']

'''
classes = ['asamu', 'baishikele', 'baokuangli', 'aoliao', 'bingqilinniunai', 'chapai', 'fenda', 'guolicheng', 
            'haoliyou', 'heweidao', 'hongniu', 'hongniu2', 'hongshaoniurou', 'kafei', 'kaomo_gali', 'kaomo_jiaoyan', 
            'kaomo_shaokao', 'kaomo_xiangcon', 'kele', 'laotansuancai', 'liaomian', 'lingdukele', 'maidong', 'mangguoxiaolao', 
            'moliqingcha', 'niunai', 'qinningshui', 'quchenshixiangcao', 'rousongbing', 'suanlafen', 'tangdaren', 'wangzainiunai', 
            'weic', 'weitanai', 'weitaningmeng', 'wulongcha', 'xuebi', 'xuebi2', 'yingyangkuaixian', 'yuanqishui', 'xuebi-b', 'kebike', 
            'tangdaren3', 'chacui', 'heweidao2', 'youyanggudong', 'baishikele-2', 'heweidao3', 'yibao', 'kele-b', 'AD', 'jianjiao', 'yezhi', 
            'libaojian', 'nongfushanquan', 'weitanaiditang', 'ufo', 'zihaiguo', 'nfc', 'yitengyuan', 'xianglaniurou', 'gudasao', 'buding', 
            'ufo2', 'damaicha', 'chapai2', 'tangdaren2', 'suanlaniurou', 'bingtangxueli', 'weitaningmeng-bottle', 'liziyuan', 'yousuanru', 
            'rancha-1', 'rancha-2', 'wanglaoji', 'weitanai2', 'qingdaowangzi-1', 'qingdaowangzi-2', 'binghongcha', 'aerbeisi', 'lujikafei',
            'kele-b-2', 'anmuxi', 'xianguolao', 'haitai', 'youlemei', 'weiweidounai', 'jindian', '3jia2', 'meiniye', 'rusuanjunqishui',
            'taipingshuda', 'yida', 'haochidian', 'wuhounaicha', 'baicha', 'lingdukele-b', 'jianlibao', 'lujiaoxiang', '3+2-2', 
            'luxiangniurou', 'dongpeng', 'dongpeng-b', 'xianxiayuban', 'niudufen', 'zaocanmofang', 'wanglaoji-c', 'mengniu', 
            'mengniuzaocan', 'guolicheng2', 'daofandian1', 'daofandian2', 'daofandian3', 'daofandian4', 'yingyingquqi', 'lefuqiu']
'''
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)
    
path = 'your path'# /a/Annotations  这里就是路径到a

def convert_annotation(image_id):
    in_file = open(path+'Annotations/%s.xml' % (image_id))
    #print(111,in_file)
    out_file = open(path+'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'):
        #try:
            #difficult = obj.find('difficult').text
        #except AttributeError:
        #    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')
        
wd = getcwd()
print(wd)
for image_set in sets:
    if not os.path.exists(path+'labels/'):
        os.makedirs(path+'labels/')
    image_ids = open(path+'ImageSets/Main/%s.txt' % (image_set)).read().strip().split()
    #print(111,image_ids)
    list_file = open(path+'%s.txt' % (image_set), 'w')
    for image_id in image_ids:
        list_file.write(path+'images/%s.jpg\n' % (image_id))

        convert_annotation(image_id)
    list_file.close()


 第二步,把一个整个的数据集进行切割,比如你有100张数据,80张用来训练,20张用来测试。

# -*- coding: utf-8 -*-
import os
import random
trainval_percent = 0.2
train_percent = 0.8
xmlfilepath = 'hat_data/Annotations'
txtsavepath = 'hat_data/ImageSets/Main/'
total_xml = os.listdir(xmlfilepath)
num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)

ftrainval = open(txtsavepath+'trainval.txt', 'w')
ftest = open(txtsavepath+'test.txt', 'w')
ftrain = open(txtsavepath+'train.txt', 'w')
fval = open(txtsavepath+'val.txt', 'w')
for i in list:
    name = total_xml[i][:-4] + '\n'
    if i in trainval:
        ftrainval.write(name)
        if i in train:
            ftest.write(name)
        else:
            fval.write(name)
    else:
        ftrain.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()



 这样会生成几个文件

 第三步,按照文件把文件进行划分,

在yolov5中标准对应的是images和labels,你可以修改成自己的文件名字,但是那样子你得在/data/dataset.py中进行修改代码,反正都可以,

# -*- coding: utf-8 -*-
import os
import shutil


def locate(path):
    temp = []

    with open(path+'val.txt','rb') as f:
        #r = f.readlines()
        for line in f.readlines():
            #print(str(line.strip()).split("'")[1])
            temp.append(str(line.strip()).split("'")[1])
    return temp    
        



def object_save(path,pic,pic_save): 
    temp = locate(path)
    #print(temp)
    if not os.path.exists(pic_save+'val'):
        os.makedirs(pic_save+'val')
    if not os.path.exists(pic_save+'train'):
        os.makedirs(pic_save+'train') 
    for i in os.listdir(pic):
        if i[:-4] in temp:
            print(i)
            shutil.copyfile(pic+i,pic_save+'val/'+i)  
        else:
            shutil.copyfile(pic+i,pic_save+'train/'+i)
            
if __name__ == '__main__':
   ImageSets_path = './ImageSets/Main/'
   pic_path = './JPEGImages/'
   pic_save_path = './images/'
   object_save(ImageSets_path,pic_path,pic_save_path)
   
   labels_path = './Annotations/'
   labels_save_path = './labels/'
   object_save(ImageSets_path,labels_path,labels_save_path)
    

(3)修改train.py

 (4)python train.py

各种BUG

1.AssertionError: train: No labels in images/train.cache. Can not train without labels. See https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data

查了网上很多资料,出现这个问题都在数据格式转换上面,我再三检查,我没什么问题。

改来改去,把yaml中路径换成了绝对路径,可以了。

老人,地铁,手机

 

 

 

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO系列是基于深度学习的端到端实时目标检测方法。 PyTorch版的YOLOv5轻量而性能高,更加灵活和易用,当前非常流行。 本课程将手把手地教大家使用labelImg标注和使用YOLOv5训练自己的数据集。课程实战分为两个项目:单目标检测(足球目标检测)和多目标检测(足球和梅西同时检测)。 本课程的YOLOv5使用ultralytics/yolov5,在Windows系统上做项目演示。包括:安装YOLOv5、标注自己的数据集、准备自己的数据集、修改配置文件、使用wandb训练可视化工具、训练自己的数据集、测试训练出的网络模型和性能统计。 希望学习Ubuntu上演示的同学,请前往 《YOLOv5(PyTorch)实战:训练自己的数据集(Ubuntu)》课程链接:https://edu.csdn.net/course/detail/30793  本人推出了有关YOLOv5目标检测的系列课程。请持续关注该系列的其它视频课程,包括:《YOLOv5(PyTorch)目标检测实战:训练自己的数据集》Ubuntu系统 https://edu.csdn.net/course/detail/30793Windows系统 https://edu.csdn.net/course/detail/30923《YOLOv5(PyTorch)目标检测:原理与源码解析》课程链接:https://edu.csdn.net/course/detail/31428《YOLOv5目标检测实战:Flask Web部署》课程链接:https://edu.csdn.net/course/detail/31087《YOLOv5(PyTorch)目标检测实战:TensorRT加速部署》课程链接:https://edu.csdn.net/course/detail/32303《YOLOv5目标检测实战:Jetson Nano部署》课程链接:https://edu.csdn.net/course/detail/32451《YOLOv5+DeepSORT多目标跟踪与计数精讲》课程链接:https://edu.csdn.net/course/detail/32669《YOLOv5实战口罩佩戴检测》课程链接:https://edu.csdn.net/course/detail/32744《YOLOv5实战中国交通标志识别》课程链接:https://edu.csdn.net/course/detail/35209《YOLOv5实战垃圾分类目标检测》课程链接:https://edu.csdn.net/course/detail/35284       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值