目录
一、前言
基于yolov5的最新版本的配置教程,我没有学过深度学习,这是在做视觉项目的学习记录过程。记录我配置的过程和报错,让读者能直接使用,如果想深度了解可以去网上查看大神的讲解。
一些安装包我上传到网盘里,放在文章最后。
如果有什么错误,还请在评论区指正。
需要工具
windows 11
yolov5源码包
pycharm编译器
cuda+cudnn+pytorch安装包
数据集
二、环境配置
1.下载Anaconda
官方网址:https://www.anaconda.com/download
选择对应的系统,下载最新版即可。
根据提示一步一步安装,或者可以去网上找找安装教程,这里就不做赘述。
创建一个yolov5的虚拟环境
conda create -n yolov5 python=3.9
2. 安装cuda与cudnn
查看自己电脑适合的版本
a.打开NVIDIA控制面板
b.查看系统信息
c.点击组件,查看版本
或者可以在终端输入
nvidia-smi
这里我的版本是11.7,下载的版本第一这个就行,后面我下载的是11.6。
如果没有显卡驱动可以去官网https://www.nvidia.cn/geforce/drivers/下载,选择适合自己电脑的显卡驱动即可。
安装cuda
官方网址:https://developer.nvidia.com/cuda-toolkit-archive
选择11.6 Download即可
根据教程安装即可,可以网上找一下,作者是以前安装过了,所以不太记得具体步骤了。
安装cudnn
官方网址:https://developer.nvidia.com/rdp/cudnn-archive
注册一个nvidia账号,有一个邮箱就行
我找的是8.6版本,只要对应11.x就行
这里我推荐这个博客
作者当时就是按这个安装的
3.安装Pytorch
官方网址:https://pytorch.org/get-started/locally/
找到对应的11.6版本
在yolov5虚拟环境下输入代码
conda install pytorch==1.13.1 torchvision==0.14.1 torchaudio==0.13.1 pytorch-cuda=11.6 -c pytorch -c nvidia
这里如果torch和torchvision下载很慢可以离线下载(安装包我放最后)
或者去网址下载https://download.pytorch.org/whl/torch_stable.html
找到对应版本
需要下载三个包torch,torchvision,torchaudio
都下载最高版本即可,前面cu开头的是GPU版本,cpu开头的是CPU版本,后面的cp对应的是python版本,win对应windows系统
在安装包所在路径打开终端,进入yolov5虚拟环境,输入
pip install torch-1.13.1%2Bcu116-cp39-cp39-win_amd64.whl //这里要输入全名
三个包都要下载,安装完后在python解释器输入import torch没有报错即可
import torch
print(torch.cuda.is_available())
三、yolov5项目环境配置
1.pycharm配置
官网下载pycharm社区版即可
打开解释器配置,点击添加解释器
点击现有
找到Anaconda路径envs/yolov5/python.exe
2.下载yolov5
a.下载
github网址:GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite
终端输入
git clone https://github.com/ultralytics/yolov5.git
如果windows没有git,可以去官网Git (git-scm.com)进行安装
下载依赖
打开yolov5项目下的requirements.txt
对已经下载的torch和torchvision进行注释
在yolov5虚拟环境下安装依赖
进入yolov5文件夹下打开终端
输入
activate yolov5
进入训练环境
再次输入
pip install -r requirements.txt
b.测试
在pycharm打开yolov5项目,运行detect.py
他会自己下载yolov5s.pt官方权重,等待运行结束。
在runs\detect\exp下生成检测后的图片
配置结束
四、yolov5训练过程
制作数据集
终端pip下载labelimg
pip install labelimg
可以查看一下我写的教程,在资源里下载一下(资源里也有图片截取的教程,这里就不多说了)
labelimg使用方法也很简单,在View中打开自动保存,open dir打开图片所在路径文件夹,change save dir改变标注文件保存路径。下面红框处可以改变标注类型,这里VOC就会生成xml文件,切换成YOLO就会生成txt文件。
快捷键w标注,a d切换图片
训练准备
在yolov5同级目录下创建datasets文件夹,里面存放数据集
这个datasets文件放在哪里都可以,我这里放一起方便找。这里的文件随意命名,只要文件路径写对即可。
a.VOC数据集
配置数据集文件夹
在datasets里创建myvoc文件夹,创建如下文件
Annotations:存放所有的xml文件
images:存放所有图片
ImageSets内有Main文件夹,其下有四个txt文件(训练集和验证集)
labels:存放转换后的txt文件
在myvoc下创建两个python文件
xml2voc.py,将所有数据集按比例划分成训练集和验证集
import os
import random
trainval_percent = 1 # trainval数据集占所有数据的比例
train_percent = 0.85 # train数据集占trainval数据的比例
xmlfilepath = 'Annotations/'
txtsavepath = '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:
ftrain.write(name)
else:
fval.write(name)
else:
ftest.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest .close()
voc_label.py 将xml类型转换成txt类型
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
sets=[ ('train'), ('val'), ('test')]
classes = ["class"] #你的类名称
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('Annotations/%s.xml'%(image_id))
out_file = open('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
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()
for image_set in sets:
if not os.path.exists('labels/'):
os.makedirs('labels/')
image_ids = open('ImageSets/Main/%s.txt'%(image_set)).read().strip().split()
list_file = open('%s.txt'%( image_set ), 'w')
for image_id in image_ids:
list_file.write('%s\images\%s.jpg\n'%(wd, image_id))
convert_annotation( image_id)
list_file.close()
#os.system("cat 2007_train.txt 2007_val.txt 2012_train.txt 2012_val.txt > train.txt")
#os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt")
这里两个文件是我当时配置darknet时的两个,这里借过来用一下
先运行xml2voc.py,再运行voc_label.py会在ImageSet\Main内生成那四个文件,在同级目录生成test.txt,train.txt,val.txt三个文件,train.txt内有每张图片的绝对路径。
最后myvoc里成下图
cache文件是后面训练时自己生成的,先不用管
配置yaml文件
在yolov5项目下的data内创建voc.yaml(源码本身具有VOC.yaml,覆盖就行,或者换个名字)
path: ../datasets/myvoc
train: train.txt
val: val.txt
test: test.txt
nc: 1
names: ['class']
nc为类的数量
下面是类的名称
b.TXT数据集
配置数据集文件夹
和上面差不多,在dataset下创建mytxt,再创建三个文件夹
这里可以把txt标注文件直接放在labels内
创建两份python文件
make_txt.py 划分训练集和验证集
import os
import random
trainval_percent = 0.99
train_percent = 0.90
txtfilepath = 'labels'
txtsavepath = 'ImageSets/Main/'
total_xml = os.listdir(txtfilepath)
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:
ftrain.write(name)
else:
fval.write(name)
else:
ftest.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()
txt_label.py 遍历所有图片,生成绝对路径的txt文件
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
sets = ['train', 'test', 'val']
classes = ['circle']
wd = getcwd()
for image_set in sets:
# 先找labels文件夹如果不存在则创建
if not os.path.exists('labels/'):
os.makedirs('labels/')
# 读取在ImageSets/Main 中的train、test..等文件的内容
# 包含对应的文件名称
image_ids = open('ImageSets/Main/%s.txt' % (image_set)).read().strip().split()
# 打开对应的train.txt 文件对其进行写入准备
list_file = open('%s.txt' % (image_set), 'w')
# 将对应的文件_id以及全路径写进去并换行
for image_id in image_ids:
list_file.write('%s\images/%s.jpg\n' % (wd, image_id))
# 关闭文件
list_file.close()
先运行make_txt.py,后运行txt_lable.py
配置yaml文件
在yolov5\data下创建txt.yaml
path: ../datasets/mytxt
train: train.txt
val: val.txt
test: test.txt
nc: 1
names: ['class']
对于两种我更喜欢VOC类,因为如果你的数据类太多,对于txt形式后面会出现类错乱的情况(和标注时类出现的顺序有关,因为在文件夹中会有一个classes.txt文件,里面有类的名字和顺序,如果你后面关闭labelimg,再重新打开标注,会错乱的,作者有过这种经历)很难解决,而voc就不会。
整体结构如下图
开始训练
打开train.py
修改对应的yaml文件
epochs是训练的轮数 正常为200-300次
batch-size是一次训练时放入的数量(电脑内存不够的调小一点)4的倍数
运行train.py
开始训练了,训练完成会在runs\train\exp内生成两个权重,best.pt和lase.pt效果最好的和最后一次保存数据的。
测试过程
把所有的权重放在weights文件夹下(自己创建的文件夹)
打开detect.py
第一个参数时权重文件,第二个时需要检测的图片路径,第三个是训练时对应的yaml文件
官方默认时检测图片的,如果想检测视频,就像图片中添加一行代码,并且在data下创建一个video文件夹,里面放入想检测的视频。
parser.add_argument('--source', type=str, default='data/video', help='source') # file/folder, 0 for webcam
运行detect.py
检测视频是一帧一帧检测的,所以比较慢。生成的视频会在runs\detect\exp1下。
五、自动生成标注文件
对于yolov5,官方自带了标注代码,在detect.py 中
首先改变两个参数
第一个是权重,为刚刚自己训练好的
第二个为yaml文件,修改对应即可
权重文件为自己训练好的,修改yaml文件
进入yolov5文件夹下,在终端中输入
python detect.py --save-txt
会在runs\detect\exp下生成lables文件夹,里面有对应的txt标注文件。
将所有文件提取出来,再用labelImg进行修正。
这样可以节省大量时间,只标注一两百张图片进行训练,然后再用训练出的权重去标注,对于只有一个类的项目来说非常方便。
这里会生成txt文件,我这里有把txt转换成xml文件的代码,如有需要私信我。
六、问题报错
yolov5训练时报错 OSError: [WinError 1455] 页面文件太小,无法完成操作。
这个是电脑内存不足造成的,可以减小训练时的batch_size
或者增加电脑虚拟内存
打开高级系统设置
点击设置,找到高级
点击更改
我的虚拟环境是下载D盘的, 所以改变的是D盘大小,这个会占用你硬盘空间,所以确保你的硬盘还留有空的位置。
2.训练时出现如下警告
COMET WARNING: Unknown error exporting current conda environment
COMET WARNING: Unknown error retrieving Conda package as an explicit file
COMET WARNING: Unknown error retrieving Conda information
解决方法:在对应的虚拟环境下卸载comet_ml
pip uninstall comet_ml
3.问题
OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized.
方法:在utils/general.py中添加
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
要在 import os 后添加
4. 问题
omp: error #15: initializing libiomp5md.dll, but found libiomp5md.dll already initialized.
在对应的虚拟环境文件夹下搜索libiomp5md.dll
上图没错, 如果在D:\Anaconda3\envs\yolov5\Library\lib下出现该文件,删除即可。
只有Library\lib路径下的删除即可。
有其他报错可以评论区提出,共同学习。
总结
对于一些简单的物品识别,yolo识别还是很好用的,动手很重要,这些过程还是要自己亲手尝试一遍,一遍一遍的解决报错,才能真正有收获。本人在Ubuntu18.04和20.04也配置过yolov5,相比于windows,linux系统更简单一些。前面的过程一样,后面的代码移植过去就可以直接用了。
本人也是个小白,如果有问题还请指正。
链接:https://pan.baidu.com/s/1PPOlrnLiUNpvaOlvrx_27g
提取码:HHHH
里面有cuda11.6,cudnn和torch安装包