一. 前言
因为自己的研究方向也是深度学习方向,而且平时闲的时候还喜欢玩会cf火线等枪战游戏,就想着找一个大模型做一个对游戏敌人的识别的功能,一切实现之后就想把自己的心得写出来,我打算分俩个教程分别细述整个学习以及操作的过程,教程一主要包括了yolov5的基本使用,制作并训练自己的数据集,第二个教程包括对yolov5添加或修改部分代码以达到实现完整功能的目的
提示:看这篇文章需要会一些虚拟环境的基础操作以及python的基本操作,如果对虚拟环境不了解,对cudnn和cuda不了解可以看下面这篇文章 ==》https://blog.csdn.net/calmdownn/article/details/130609866
二. 制作数据集
2.1 下载labelImg 和 所需配置库
进入aconda虚拟环境中之后下载下面三个库文件
pip install PyQt5 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
pip install pyqt5-tools -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
pip install lxml -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
labelImg : 到github上将labelImg压缩包下载下来,我用的是1.8.1的版本 ==》labelImg下载地址
2.2 进入虚拟环境编译resources.py文件之后启动labelImg
进入虚拟环境之后切换到(cd)下载之后的labelImg文件夹目录,执行以下命令将qt文件转化为.py
pyrcc5 -o resources.py resources.qrc
(我的python版本是3.8),最后运行labelImg.py的python文件,打开labelImg
python labelImg.py
注意:可能会爆出以下错误,提示在libs文件中找不到resources文件
解决方法:将resources.py文件转移到libs文件夹中
打开之后如下:
点击PascalVoc按钮,将其切换成yolo格式,open就是打开你原始图片的文件夹,open dir 就是打开你的目标图片文件夹(推荐这个),change save Dir就是改变你的保存路径
下面是它的快捷键:
2.3 使用labelImg
添加原图片,按w进行拉框,拉框之后为其命名即可
我这里是画了一个头和一个身子
全部画完之后按住 ctrl + s 进行保存,你就能在原先设置的存储路径中看见一个.txt的文件了
打开txt文件之后如下,0和1分别代表头部类和身体类,四个数值分别代表你画框的左上角坐标和右下角坐标
到这制作数据集的步骤就结束了,下面开始下载并使用yolov5模型
三. yolov5的下载与使用
3.1 官网下载yolov5
进入github,选择版本然后下载,我下载的版本是7.0版本 ==》yolov5下载地址
下载完打开如下:
3.2 配置yolov5的所需虚拟环境
基本的虚拟环境创建
注意事项:
1).确定你的显卡驱动版本,下载对应的cuda和cudnn,是为了能够使用gpu版本的pytorch,比如我的电脑显卡是1060,所对应的cuda和cudnn版本分别就是10.2和7.6.5版本
显卡与cuda和cudnn的对应关系以及虚拟环境的知识可以看下面这篇文章 == 》Anaconda/jupyter notebook安装使用tensorflow-gpu_jupyter notebook安装tensorflow_calmdownn的博客-CSDN博客
2).注意pytorch的版本,yolov5的官网有声明,至少pytorch要大于1.7.0版本,所以我下载的是1.8.1版本
conda install cudatoolkit=10.2 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/win-64/
conda install cudnn=7.6.5 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/win-64/
conda install pytorch==1.8.1 torchvision==0.9.1 torchaudio==0.8.1 cudatoolkit=10.2 -c pytorch
pytorch对应的工具包下载地址 == 》https://pytorch.org/get-started/previous-versions/
比如你要下载1.8.1版本的gpu的pytorch,就可以 ctrl + f 全局搜索,找到linux和windows的下载,然后找准你对应的cuda版本下载就可以了
建议:最好先看看官网支持的cuda有什么版本,然后根据你的显卡再去选择cuda会更省力一些
3)测试pytorch的gpu版本是否可以使用
进入虚拟环境,运行python之后,导入import,执行下面语句判断gpu版本是否可用,如果结果为true就代表成功了
print(torch.cuda.is_available())
4)其他包的安装
剩余其他工具包的安装就比较简单了,一键自动安装即可,命令如下
注意:使用这个命令的前提还是要进入虚拟环境之后,通过cd切换到yolov5文件目录下才能执行
pip install -r requirements.txt
下面就是requirements.txt的位置和内容
3.3 测试yolov5运行
- 下载yolov5s.pt文件,放进根目录中,网址 ==》 https://github.com/ultralytics/yolov5/releases
进入网站往下翻,看到assets配置,点击展开全部assets,找到yolov5s.pt文件下载下来
将yolov5s.pt文件放入根目录下面
- 打开pycharm或者其他的编辑软件导入yolov5这个文件夹,这里只用pycharm举例了,将pycharm切换到你创建的虚拟环境,如果没有的自己add添加一下自己的虚拟环境,如果不会的查一下,这里就不多说了
- 更改参数
打开detect.py的文件,在根目录下可以找到
找到下面画红线的几行参数,yolov5-7.0版本在212行开始,将你们的代码图片中画红线的地方改成同样的代码,我简单说下一些属性的功能
weights : 代表权重,yolov5s.pt也就是官方已经训练好的权重,经过很多数据集锻炼出来的,有一些基本的类识别功能,我们以后就是在这个权重上继续训练的,也就是站在巨人的肩膀前进
source : 代表来源,这个来源可以是图片,视频,屏幕等,这里测试用的就是yolov5里面自带的照片,大家可以照着路径找一下这个图片
data : 代表数据配置文件,.yaml文件里面包含了训练集,实验集,测试集路径,还包含了识别的所有类别名称集合,无论是训练还是测试都会用到
device : 设备名称,如果你只有一个显卡默认改为0即可,如果你有多个显卡可以写成 0,1,2这个形式
view-img,save-txt 等,这些都是一些不太重要的属性,也就是是否弹出预测图片,是否生成txt文件等等
- 运行
上面都准备好之后就可以运行detect.py文件了
运行成功之后提示如下,运行之后的结果图片会自动保存到runs\detect\exp文件夹之下
3.4 利用yolov5测试自己的数据
- 构建自己的数据文件目录
创建一个mydata文件夹,mydata文件夹下面有俩个子文件夹,分为images,labels,里面又分为三个文件夹,测试集,训练集,验证集,images文件保存的就是原图片,labels文件保存的是.txt文件,里面有类别和坐标,忘了的看2.3,我们要将数据分成三类,我写了一个小脚本用来将所有的数据集分类
下面就是我写的数据集分类脚本部分:
使用方式:只需要更改source_folder_jpg(你的所有图片地址),source_folder_txt(l图片对应的.txt文件地址),destination_folder(你想要生成的目标文件夹地址) ,split_ratio_val(验证集的比例),split_radio_test(测试集的比例)
运行之前文件夹图片如下:
运行之后文件夹图片如下:
mydata文件夹就已经包含了yolov5数据集的整体格式了,直接将它移动到data根目录下就行了,忘了放到什么位置的看3.4的第一步就知道了
脚本代码:
import os
import shutil
import random
def random_split_files(source_folder_jpg,source_folder_txt,destination_folder,split_val=0.3,split_test=0.3):
# yolov5的文件夹格式
mydata_folder = os.path.join(destination_folder, 'mydata') # mydata文件夹
images_folder = os.path.join(mydata_folder,'images') # images文件夹
labels_folder = os.path.join(mydata_folder, 'labels') # lables文件夹
img_train_folder = os.path.join(images_folder,'train') # img_train文件夹
img_val_folder = os.path.join(images_folder, 'val') # img_val文件夹
img_test_folder = os.path.join(images_folder,'test') # img_test文件夹
lbs_train_folder = os.path.join(labels_folder, 'train') # label_train文件夹
lbs_val_folder = os.path.join(labels_folder, 'val') # label_val文件夹
lbs_test_folder = os.path.join(labels_folder, 'test') # label_test文件夹
# 放入列表中
folder_list = []
folder_list.append(img_train_folder)
folder_list.append(img_val_folder)
folder_list.append(img_test_folder)
folder_list.append(lbs_train_folder)
folder_list.append(lbs_val_folder)
folder_list.append(lbs_test_folder)
# 判断文件夹是否存在
for forder_name in folder_list:
if os.path.exists(forder_name) == False:
os.makedirs(forder_name)
pass
# 打开数据集的照片以及txt文件
files_jpg = os.listdir(source_folder_jpg)
files_txt = os.listdir(source_folder_txt)
# 打乱照片顺序
random.shuffle(files_jpg)
# 三数据数量
num_files_val = int(len(files_jpg) * split_val)
num_files_test = int(len(files_jpg) * split_test)
num_files_train = int(len(files_jpg) - num_files_test - num_files_val)
# 判断数量是否符合
if num_files_train <= 0:
print("验证集和和测试集数量比例不对!")
return
files_train = files_jpg[:num_files_train]
files_val = files_jpg[num_files_train:num_files_train + num_files_val]
files_test = files_jpg[num_files_train + num_files_val:]
for filename_train in files_train:
# print(filename)
filename_txt = filename_train.replace(".jpg",".txt")
source_path_jpg = os.path.join(source_folder_jpg, filename_train)
source_path_txt = os.path.join(source_folder_txt, filename_txt)
destination_path_jpg = os.path.join(img_train_folder, filename_train)
destination_path_txt = os.path.join(lbs_train_folder, filename_txt)
shutil.copy(source_path_jpg, destination_path_jpg)
shutil.copy(source_path_txt, destination_path_txt)
print("训练集jpg,txt文件传送完毕")
for filename_val in files_val:
filename_txt = filename_val.replace(".jpg", ".txt")
source_path_jpg = os.path.join(source_folder_jpg, filename_val)
source_path_txt = os.path.join(source_folder_txt, filename_txt)
destination_path_jpg = os.path.join(img_val_folder, filename_val)
destination_path_txt = os.path.join(lbs_val_folder, filename_txt)
shutil.copy(source_path_jpg, destination_path_jpg)
shutil.copy(source_path_txt, destination_path_txt)
print("验证集jpg,txt文件传送完毕")
for filename_test in files_test:
filename_txt = filename_test.replace(".jpg", ".txt")
source_path_jpg = os.path.join(source_folder_jpg, filename_test)
source_path_txt = os.path.join(source_folder_txt, filename_txt)
destination_path_jpg = os.path.join(img_test_folder, filename_test)
destination_path_txt = os.path.join(lbs_test_folder, filename_txt)
shutil.copy(source_path_jpg, destination_path_jpg)
shutil.copy(source_path_txt, destination_path_txt)
print("测试集jpg,txt文件传送完毕")
if __name__ == "__main__":
source_folder_jpg = "D:\lableimg1.8\csdn\dataset_pic" # 原图片地址
source_folder_txt = "D:\lableimg1.8\csdn\dataset_txt" # 原图片txt地址
destination_folder = "D:\lableimg1.8\csdn" # 目标地址
split_ratio_val = 0.2 # 验证集分割比例
split_ratio_test = 0.2 # 测试集分割比例
random_split_files(source_folder_jpg, source_folder_txt, destination_folder, split_ratio_val,split_ratio_test)
- 创建自己的.yaml文件
在data根目录下新建一个.yaml文件,我的就是crossFire.yaml了,里面包含了训练集,测试集,验证集的地址,如果和我一样结构就不用改了,如果不一样自行改就行了,这个文件里面还包含了训练的类别
train: data/mydata/images/train # train images (relative to 'path') 128 images
val: data/mydata/images/val # val images (relative to 'path') 128 images
test: data/mydata/images/test # test images (optional)
names:
0: body
1: head
- train.py文件配置
注意:下面画红线的都是需要改的,其他属性可以和我一样,主要是batch-size,epoch,workers,最好根据自己电脑情况来改变
属性介绍:
weights:权重,我们正常就用yolov5s.pt就行了,和上面detect.py预测文件一样
cfg:我们用的模型的配置文件,因为我们用的yolov5s,所以这里就用yolov5s.yaml文件,在models文件的根目录下就能看见
data:数据集的配置文件,和上面detect.py预测文件一样,上面自己创建的.yaml文件
epochs:迭代次数,这里建议300-600次之间较好,多了可能会高方差过拟合,少了可能会高偏差欠拟合
batch-size:块训练大小,这个数量大小根据显卡情况来定就行,比如我的1060 3G显存每次只能设定为8,如果大于8我的显存就会爆,会提示out of memory,这里建议2倍递增即可,比如选择 2/4/8/16/32/64 等
batch-size扩展(可以不用看): batch-size其实就是将一大块训练的数据集随机分成多个小块去进行训练,这样模型可以根据每一块训练结束后的loss损失值去调整权重,更好的适应下一块的训练,这样在图像上表现出来的就是Loss会稳步上升,比不用batch-size更加稳定,而且更加节省内存资源,总体循环次数会多出batch-size - 1次
device:选择显卡,如果你只有一张显卡默认0就行了,如果你有多张,就可以写成0,1,2等
workers: 数据预处理时候所用的cpu线程数量,如果电脑不太行,就默认0就可以了,我的1060 3G就只设置的为0,多线程也比较吃显存,因为训练的时候gpu吃的比较多,所以cpu做一些比如预处理的操作之后会等待gpu的操作完成再继续,所以用多线程就会把cpu利用的更充分一点,我租服务器的时候workers设置的就为8,3080ti显卡12G
- 运行train.py文件
上面都准备好就可以运行了,运行图片如下:
3.5 训练结果使用
- 训练结果储存位置:
训练结束之后可以在runs/train/exp(exp1就代表第一次训练文件夹,exp2代表第二次)/weights下找到best.pt,和last.pt文件,best.pt文件就代表训练过程中取某一次循环中loss代价函数最低的一次权重,也就是效果最好的一次,last.pt文件就是最后一次循环的权重文件
- 利用best.pt文件进行预测操作
对没错,你费劲千辛万苦就是为了得到这个best.pt文件,将detect.py文件中的权重路径换成你训练得到的best.pt文件路径(更改weights属性,忘了的看3.3的第三小步,detect.py文件配置那块),source属性换成你想要预测的照片/视频的地址,data属性换成你自己写的.yaml文件,下面地方都可以根据情况更改
- 预测
预测之后的存储地址就在runs/detect/exp(第几次预测后面就是数字几),如果你想更改存储的地址可以找到project属性进行更改,目录结构如下:
下面这张图片就是我随便从训练集里选出来的一张图片,咱们看看效果
结果图如下:
四. 材料与总结
4.1 材料
如果想要敌我数据集或者整个项目的可以邮箱联系我(874302104@qq.com),因为百度云上传大项目需要vip才可,大概有16000千张不同人物不同地点标注好的敌我标注
4.2 总结
yolov5的基础到这就结束了,下一篇我将讲述如何进行时时监控屏幕以及自动进行瞄准,如果有什么困难和不懂的也可以邮箱联系我哦!
版权归原作者 calmdownn 所有, 如有侵权,请联系我们删除。