yolov7训练自己的数据集(一)

一、安装环境:

1、创建虚拟环境
conda create -n yolov7 python=3.7 -y
conda activate yolov7
#退出环境
conda deactivate
2、下载源码:
https://github.com/WongKinYiu/yolov7
3、下载权重

方法一:百度网盘下载https://pan.baidu.com/s/1DbG5bI_Sm1U62poE9yb5dQ
提取码:cvss
方法二:官网下载(速度很慢不推荐)
打开官网后往下划找到Testing
yolov7官网:https://github.com/WongKinYiu/yolov7

4、安装依赖
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

安装依赖有时候会装不上pytorch(默认CPU),需要手动安装:

CPU版本 conda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch  

GPU版本:pip3 install torch==1.9.0+cu111 torchvision==0.10.0+cu111 torchaudio==0.9.0 -f https://download.pytorch.org/whl/torch_stable.html

二、yolov7训练自己数据集

一.配置训练的相关文件

总共有两个文件需要配置,一个是/yolov7/cfg/training/yolov7.yaml,这个文件是有关模型的配置文件;一个是/yolov7/data/coco.yaml,这个是数据集的配置文件。

1.第一步,复制yolov7.yaml文件到相同的路径下,然后重命名,我们重命名为yolov7-xxx.yaml(起一个你想要的名字)然后打开

2.复制coco.yaml文件到相同的路径下,然后重命名,我们命名为xxx.yaml。(起一个你喜欢的名字)打开后进行更改

3.正式训练
此时我们在yolov7文件夹路径下cmd,并且激活虚拟环境,输入指令

conda activate yolov7

激活环境后输入

python train.py --weights yolov7x.pt --cfg cfg/training/yolov7-xxx.yaml --data data/xxx.yaml --batch-size 8 --epoch 300 --device 0
注意一定要将xxx改为自己的文件名称
这里我们使用gpu进行训练若用cpu去掉 --device 0 即可

对参数解释

–cfg 接受模型配置的参数
–data 接收数据配置的参数
–device 0 训练类型,我是一块GPU 所以用0
–batch-size 8 GPU内存大小决定
–epoch 训练次数,建议300
–weights 训练的权重

4.使用自己的权重
跟detect一样,进入虚拟环境输入权重路径和图片路径就ok了,指令如下
我是把best.pt直接拉到了yolov7文件夹路径下面,你们刚刚训练出来的在runs/train/circle/weights/best.pt
命令如下

python detect.py --weights best.pt --source xxx --device 0

三、ubutun中安装YOLOV7 GPU环境的问题:

1、Pytorch-gpu版本需要单独安装(代码见上面)

2、数据集如果已经跑过一遍了,再跑的时候删掉cache文件

四、自建数据集

1、Win10中安装labelimg

1.下载labelImg

github地址:
https://github.com/tzutalin/labelImg

下载第三方库 (要安装的库)
labelImg的使用需要以下库的支持:PyQt5、PyQt5_tools、lxml

cmd下分别输入:pip3 install PyQt5 pip3 install PyQt5_tools pip3 install lxml 完成库的安装

2.安装PyQt,在官网下载吧,否则pip install 要等好久
下载后直接安装, 输入命令 :pip install XXX.whl
https://pypi.org/project/PyQt5/5.11.3/#files

3.安装PyQtTool,同样在官网下载
下载后直接安装, 输入命令 :pip install XXX.whl
https://pypi.org/project/pyqt5-tools/#files

4.安装lxml,命令:pip install lxml,这个库特别小,可以这样直接pip安装

5.cmd进入解压后的文件路径。如果没有改名的话就是labelImg-master。
执行命令:Pyrcc5 -o resources.py resources.qrc ,这句命令的功能是把Qt文件格式转为Python格式。

6.运行成功后再次输入: python labelImg.py
这时可能出现no module named libs.resources这样的错误提醒

7.将生成的resources.py拷贝到同级的libs目录下

8.成功运行。

2、数据集划分

由于打标签的时候直接生成了yolo格式,所以以下代码直接将图片和标签对应分成训练集、验证集、测试集

'''
Descripttion: split_img.py
version: 1.0
Author: UniDome
Date: 2022-04-20 16:28:45
LastEditors: UniDome
LastEditTime: 2022-04-20 16:39:56
'''
import os, shutil, random
from tqdm import tqdm

def split_img(img_path, label_path, split_list):
    try :   # 创建数据集文件夹
        Data = '../DataSet'
        os.mkdir(Data)

        train_img_dir = Data + '/images/train'
        val_img_dir = Data + '/images/val'
        test_img_dir = Data + '/images/test'

        train_label_dir = Data + '/labels/train'
        val_label_dir = Data + '/labels/val'
        test_label_dir = Data + '/labels/test'

        # 创建文件夹
        os.makedirs(train_img_dir)
        os.makedirs(train_label_dir)
        os.makedirs(val_img_dir)
        os.makedirs(val_label_dir)
        os.makedirs(test_img_dir)
        os.makedirs(test_label_dir)

    except:
        print('文件目录已存在')

    train, val, test = split_list
    all_img = os.listdir(img_path)
    all_img_path = [os.path.join(img_path, img) for img in all_img]

    train_img = random.sample(all_img_path, int(train * len(all_img_path)))
    train_img_copy = [os.path.join(train_img_dir, img.split('\\')[-1]) for img in train_img]
    train_label = [toLabelPath(img, label_path) for img in train_img]
    train_label_copy = [os.path.join(train_label_dir, label.split('\\')[-1]) for label in train_label]
    for i in tqdm(range(len(train_img)), desc='train ', ncols=80, unit='img'):
        _copy(train_img[i], train_img_dir)
        _copy(train_label[i], train_label_dir)
        all_img_path.remove(train_img[i])
    val_img = random.sample(all_img_path, int(val / (val + test) * len(all_img_path)))
    val_label = [toLabelPath(img, label_path) for img in val_img]
    for i in tqdm(range(len(val_img)), desc='val ', ncols=80, unit='img'):
        _copy(val_img[i], val_img_dir)
        _copy(val_label[i], val_label_dir)
        all_img_path.remove(val_img[i])
    test_img = all_img_path
    test_label = [toLabelPath(img, label_path) for img in test_img]
    for i in tqdm(range(len(test_img)), desc='test ', ncols=80, unit='img'):
        _copy(test_img[i], test_img_dir)
        _copy(test_label[i], test_label_dir)


def _copy(from_path, to_path):
    shutil.copy(from_path, to_path)

def toLabelPath(img_path, label_path):
    img = img_path.split('\\')[-1]
    label = img.split('.jpg')[0] + '.txt'
    return os.path.join(label_path, label)

def main():
    img_path = r'F:\Yolov7\datasets\images'
    label_path = r'F:\Yolov7\datasets\Annotations'
    split_list = [0.7, 0.2, 0.1]   # 数据集划分比例[train:val:test]
    split_img(img_path, label_path, split_list)

if __name__ == '__main__':
    main()
3、数据集标注注意事项

1.1 数据集方面
1.1.1 每个类别的图像
每个类别的图像张数大于1500张

1.1.2 每个类别的实例
我们人工标注的目标框就是实例,每个类别的实例要大于10000张。

1.1.3 图像的多样性
数据集必须展现出部署环境,推荐来自一天中不同时间、不同季节、不同天气、不同光照、不同角度、不同数据源(在线抓取、本地收集、不同相机)等的图像。

1.1.4 标注的一致性
所有图像中所有类的所有实例都必须标注。部分标注将不起作用。

1.1.5 标注的精度
边框必须紧密地包围每个目标。目标和边框之间不应存在任何空。任何目标都不应缺少标签。
背景图像:背景图像是图像里没有感兴趣目标的图像,加到数据集以减少误报 (FP) 。建议约 0-10% 的背景图像,以帮助减少 FP(COCO数据集有1000张背景图像供参考,占总数的 1%)。

1.2 模型选择
更大的模型,如YOLOv5x,在几乎所有情况下都会产生更好的结果,但参数更多,运行速度也更慢。对于移动应用推荐YOLOv5s/m;对于云或桌面应用,推荐YOLOv5l/x。 对于所有YOLOv5系列模型全面的比较,请看这里

1.3 训练设置
在修改任何内容之前,首先使用默认设置进行训练,以建立性能baseline。
( first train with default settings to establish a performance baseline)
training.py的argparser中提供了训练设置的完整列表。

1.3.1 epochs:
从300个epoch开始。如果过早过拟合,那么可以减少epochs。如果在300个epoch后没有发生过拟合,则训练更长时间,即 600、1200 个等epoch。

1.3.2 图像大小
COCO以–img 640的原始分辨率训练,尽管由于数据集中有大量的小目标,它可以从更高分辨率(如-img 1280)的训练中受益。如果有许多小目标,则自定义数据集将从原始或更高分辨率的训练中受益。最佳推理结果是训练时设置的 --img x与推理时设置的–img x相同,例如如果–img 1280训练,则在–img 1280进行推理测试。

1.3.3 batch size
使用自己的硬件资源允许的最大Batch size。小的Batch size会产生较差的batchnorm统计,应该避免。

1.3.4 超参数
默认超参数位于hpy.scratch.yaml中。建议先使用默认超参数进行训练,然后再考虑修改任何参数。一般来说,增加augmentation超参数将减少和延迟过度拟合,从而允许更长的训练时间和更高的最终mAP。减少loss component gain 超参数(如hyp[‘obj’])将有助于减少对特定loss component的过度拟合。

原文链接:https://blog.csdn.net/flyfish1986/article/details/120704968

4、图片文件爬取
import re
import requests
from urllib import error
from bs4 import BeautifulSoup
import os

num = 0
numPicture = 0
file = ''
List = []


def Find(url):
    global List
    print('正在检测图片总数,请稍等.....')
    t = 0
    i = 1
    s = 0
    while t < 5000:
        Url = url + str(t)
        try:
            Result = requests.get(Url, timeout=7)
        except BaseException:
            t = t + 60
            continue
        else:
            result = Result.text
            pic_url = re.findall('"objURL":"(.*?)",', result, re.S)  # 先利用正则表达式找到图片url
            s += len(pic_url)
            if len(pic_url) == 0:
                break
            else:
                List.append(pic_url)
                t = t + 60
    return s


def recommend(url):
    Re = []
    try:
        html = requests.get(url)
    except error.HTTPError as e:
        return
    else:
        html.encoding = 'utf-8'
        bsObj = BeautifulSoup(html.text, 'html.parser')
        div = bsObj.find('div', id='topRS')
        if div is not None:
            listA = div.findAll('a')
            for i in listA:
                if i is not None:
                    Re.append(i.get_text())
        return Re


def dowmloadPicture(html, keyword):
    global num
    # t =0
    pic_url = re.findall('"objURL":"(.*?)",', html, re.S)  # 先利用正则表达式找到图片url
    print('找到关键词:' + keyword + '的图片,即将开始下载图片...')
    for each in pic_url:
        print('正在下载第' + str(num + 1) + '张图片,图片地址:' + str(each))
        try:
            if each is not None:
                pic = requests.get(each, timeout=7)
            else:
                continue
        except BaseException:
            print('错误,当前图片无法下载')
            continue
        else:
            string = file + r'\\' + keyword + '_' + str(num) + '.jpg'
            fp = open(string, 'wb')
            fp.write(pic.content)
            fp.close()
            num += 1
        if num >= numPicture:
            return


if __name__ == '__main__':  # 主函数入口
    word = input("请输入搜索关键词(可以是人名,地名等): ")
    # add = 'http://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=%E5%BC%A0%E5%A4%A9%E7%88%B1&pn=120'
    url = 'http://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=' + word + '&pn='
    tot = Find(url)
    Recommend = recommend(url)  # 记录相关推荐
    print('经过检测%s类图片共有%d张' % (word, tot))
    numPicture = int(input('请输入想要下载的图片数量 '))
    file = input('请建立一个存储图片的文件夹,输入文件夹名称即可')
    y = os.path.exists(file)
    if y == 1:
        print('该文件已存在,请重新输入')
        file = input('请建立一个存储图片的文件夹,)输入文件夹名称即可')
        os.mkdir(file)
    else:
        os.mkdir(file)
    t = 0
    tmp = url
    while t < numPicture:
        try:
            url = tmp + str(t)
            result = requests.get(url, timeout=10)
            print(url)
        except error.HTTPError as e:
            print('网络错误,请调整网络后重试')
            t = t + 60
        else:
            dowmloadPicture(result.text, word)
            t = t + 60

    print('当前搜索结束,感谢使用')
    print('猜你喜欢')
    for re in Recommend:
        print(re, end='  ')
5、图片批量重命名
# -*- coding:utf8 -*-

import os

class BatchRename():
    def __init__(self):
        self.path = 'E:/DaChuang/爬数据代码/bike'  #表示需要命名处理的文件夹目录,复制地址后注意反斜杠

    def rename(self):
        filelist = os.listdir(self.path)   #获取文件路径
        total_num = len(filelist)  #获取文件长度(文件夹下图片个数)
        print("图片数量 %d", total_num)
        i = 1  #表示文件的命名是从1开始的
        for item in filelist:
            if item.endswith('.jpg') or item.endswith('.png'):  #初始的图片的格式为jpg格式的(或者源文件是png格式及其他格式,后面的转换格式就可以调整为自己需要的格式即可,我习惯转成.jpg)
                src = os.path.join(os.path.abspath(self.path), item)
                dst = os.path.join(os.path.abspath(self.path), 'bike'+'000' + format(str(i), '0>4s') + '.jpg')#处理后的格式也为jpg格式的,当然这里可以改成png格式
                # 这种情况下的命名格式为000xxxx.jpg形式,可以自主定义想要的格式
                try:
                    os.rename(src, dst)
                    print ('converting %s to %s ...' % (src, dst))
                    i = i + 1
                except:
                    continue
        print ('total %d to rename & converted %d jpgs' % (total_num, i))

if __name__ == '__main__':
    demo = BatchRename()
    demo.rename()
  • 30
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值