关于人工智能:炼丹侠YOLOV5配置训练实战

46次阅读

共计 7505 个字符,预计需要花费 19 分钟才能阅读完成。

一、NVIDIA 驱动装置与更新
首先查看电脑的显卡版本,步骤为:此电脑右击–> 治理–> 设施管理器–> 显示适配器。就能够看到电脑显卡的版本了。如图,能够看到我的是一块 NVIDIA GeForce 1660Ti 显卡。

有显卡驱动的,能够间接在桌面右键,找到英伟达驱动控制面板关上就好了。

装置(更新)好了显卡驱动当前。咱们按下 win+ R 组合键,关上 cmd 命令窗口。输出如下的命令。
nvidia-smi
失去如下图的信息图

二、Pytorch 环境装置
按下开始键(win 键),关上 anaconda 的终端。创立虚拟环境 conda create -n 环境名字(英文)python=x.x(python 版本),如下,我就是创立了一个名字叫 pytorch,python 是 3.8 版本的环境。
conda create -n pytorch python=3.8
在 base 环境中执行如上的命令,就会创立一个新的虚拟环境,这个虚拟环境会装置一些根底的包,如下图所示。询问是否装置的时候,输出 y。就能够创立环境了。
当装置好了当前,执行 conda env list 这个命令,就能够看到比一开始多了一个 pytorch 这个环境。当初咱们能够在这个环境外面装置深度学习框架和一些 Python 包了。
Conda env list

执行如下命令,激活这个环境。conda activate 虚拟环境名称
conda activate pytorch
装置 pytorch-gup 版的环境,因为 pytorch 的官网在国外,下载相干的环境包是比较慢的,所以咱们给环境换源。在 pytorch 环境下执行如下的命名给环境换清华源。

而后关上 pytorch 的官网,因为结尾咱们通过驱动检测到我的显卡为 NVIDIA GeForce 1660Ti,最高反对 cuda11.6 版本,所以咱们抉择 cuda11.7 版本的 cuda,而后将上面红色框框中的内容复制下来,肯定不要把前面的 -c pytorch -c conda-forge 也复制下来,因为这样运行就是还是在国外源下载,这样就会很慢。

将复制的内容粘贴到 pytorch 环境下的终端,运行就能够了

三、验证 CUDA 和 cudnn 版本
在代码中增加 print(torch.cuda.is_available)查看以后 pytorch 的 gpu 是否正确配置,若后果为 True 则代表配置胜利

四、VOC 标签格局转 yolo 格局并划分训练集和测试集
咱们常常从网上获取一些指标检测的数据集资源标签的格局都是 VOC(xml 格局)的,而 yolov5 训练所须要的文件格式是 yolo(txt 格局)的,这里就须要对 xml 格局的标签文件转换为 txt 文件。同时训练本人的 yolov5 检测模型的时候,数据集须要划分为训练集和验证集。这里提供了一份代码将 xml 格局的标注文件转换为 txt 格局的标注文件,并按比例划分为训练集和验证集。先上代码再解说代码的注意事项。

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
import random
from shutil import copyfile
 
classes = ["hat", "person"]
#classes=["ball"]
 
TRAIN_RATIO = 80
 
def clear_hidden_files(path):
    dir_list = os.listdir(path)
    for i in dir_list:
        abspath = os.path.join(os.path.abspath(path), i)
        if os.path.isfile(abspath):
            if i.startswith("._"):
                os.remove(abspath)
        else:
            clear_hidden_files(abspath)
 
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)
 
def convert_annotation(image_id):
    in_file = open('VOCdevkit/VOC2007/Annotations/%s.xml' %image_id)
    out_file = open('VOCdevkit/VOC2007/YOLOLabels/%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')
    in_file.close()
    out_file.close()
wd = os.getcwd()
wd = os.getcwd()
data_base_dir = os.path.join(wd, "VOCdevkit/")
if not os.path.isdir(data_base_dir):
    os.mkdir(data_base_dir)
work_sapce_dir = os.path.join(data_base_dir, "VOC2007/")
if not os.path.isdir(work_sapce_dir):
    os.mkdir(work_sapce_dir)
annotation_dir = os.path.join(work_sapce_dir, "Annotations/")
if not os.path.isdir(annotation_dir):
        os.mkdir(annotation_dir)
clear_hidden_files(annotation_dir)
image_dir = os.path.join(work_sapce_dir, "JPEGImages/")
if not os.path.isdir(image_dir):
        os.mkdir(image_dir)
clear_hidden_files(image_dir)
yolo_labels_dir = os.path.join(work_sapce_dir, "YOLOLabels/")
if not os.path.isdir(yolo_labels_dir):
        os.mkdir(yolo_labels_dir)
clear_hidden_files(yolo_labels_dir)
yolov5_images_dir = os.path.join(data_base_dir, "images/")
if not os.path.isdir(yolov5_images_dir):
        os.mkdir(yolov5_images_dir)
clear_hidden_files(yolov5_images_dir)
yolov5_labels_dir = os.path.join(data_base_dir, "labels/")
if not os.path.isdir(yolov5_labels_dir):
        os.mkdir(yolov5_labels_dir)
clear_hidden_files(yolov5_labels_dir)
yolov5_images_train_dir = os.path.join(yolov5_images_dir, "train/")
if not os.path.isdir(yolov5_images_train_dir):
        os.mkdir(yolov5_images_train_dir)
clear_hidden_files(yolov5_images_train_dir)
yolov5_images_test_dir = os.path.join(yolov5_images_dir, "val/")
if not os.path.isdir(yolov5_images_test_dir):
        os.mkdir(yolov5_images_test_dir)
clear_hidden_files(yolov5_images_test_dir)
yolov5_labels_train_dir = os.path.join(yolov5_labels_dir, "train/")
if not os.path.isdir(yolov5_labels_train_dir):
        os.mkdir(yolov5_labels_train_dir)
clear_hidden_files(yolov5_labels_train_dir)
yolov5_labels_test_dir = os.path.join(yolov5_labels_dir, "val/")
if not os.path.isdir(yolov5_labels_test_dir):
        os.mkdir(yolov5_labels_test_dir)
clear_hidden_files(yolov5_labels_test_dir)
 
train_file = open(os.path.join(wd, "yolov5_train.txt"), 'w')
test_file = open(os.path.join(wd, "yolov5_val.txt"), 'w')
train_file.close()
test_file.close()
train_file = open(os.path.join(wd, "yolov5_train.txt"), 'a')
test_file = open(os.path.join(wd, "yolov5_val.txt"), 'a')
list_imgs = os.listdir(image_dir) # list image files
prob = random.randint(1, 100)
print("Probability: %d" % prob)
for i in range(0,len(list_imgs)):
    path = os.path.join(image_dir,list_imgs[i])
    if os.path.isfile(path):
        image_path = image_dir + list_imgs[i]
        voc_path = list_imgs[i]
        (nameWithoutExtention, extention) = os.path.splitext(os.path.basename(image_path))
        (voc_nameWithoutExtention, voc_extention) = os.path.splitext(os.path.basename(voc_path))
        annotation_name = nameWithoutExtention + '.xml'
        annotation_path = os.path.join(annotation_dir, annotation_name)
        label_name = nameWithoutExtention + '.txt'
        label_path = os.path.join(yolo_labels_dir, label_name)
    prob = random.randint(1, 100)
    print("Probability: %d" % prob)
    if(prob < TRAIN_RATIO): # train dataset
        if os.path.exists(annotation_path):
            train_file.write(image_path + '\n')
            convert_annotation(nameWithoutExtention) # convert label
            copyfile(image_path, yolov5_images_train_dir + voc_path)
            copyfile(label_path, yolov5_labels_train_dir + label_name)
    else: # test dataset
        if os.path.exists(annotation_path):
            test_file.write(image_path + '\n')
            convert_annotation(nameWithoutExtention) # convert label
            copyfile(image_path, yolov5_images_test_dir + voc_path)
            copyfile(label_path, yolov5_labels_test_dir + label_name)
train_file.close()
test_file.close()

首先数据集的格局构造必须严格依照如图的款式来,因为代码曾经将文件名写死了。其实这样也好,因为对立就会标准。

Annotations 外面寄存着 xml 格局的标签文件,JPEGImages 外面寄存着照片数据文件。特地要留神的是,classes 外面必须正确填写 xml 外面曾经标注好的类,要不然生成的 txt 的文件是不对的。TRAIN_RATIO 是训练集和验证集的比例,当等于 80 的时候,阐明划分 80% 给训练集,20% 给验证集。

将代码和数据在同一目录下运行,失去如下的后果

在 VOCdevkit 目录下生成 images 和 labels 文件夹,文件夹下别离生成了 train 文件夹和 val 文件夹,外面别离保留着训练集的照片和 txt 格局的标签,还有验证集的照片和 txt 格局的标签。images 文件夹和 labels 文件夹就是训练 yolov5 模型所需的训练集和验证集。在 VOCdevkit/VOC2007 目录下还生成了一个 YOLOLabels 文件夹,外面寄存着所有的 txt 格局的标签文件。
至此,xml 格局的标签文件转换为 txt 格局的标签文件并划分为训练集和测试集就讲完了。
五、我的项目的克隆和必要的环境依赖
YOLOv5 的代码是开源的,因而咱们能够从 github 上克隆其源码。首先关上 yolov5 的 github 的官网(这个网站在国外关上是很慢的,而且是有的时候能失常关上,有的时候是进不去的,然而大家第一次打不开的话,肯定要多关上几次。)关上的官网界面如下,这个就是大神 glenn-jocher 开源的 yolov5 的我的项目。

这个开源的我的项目通过大家的一直的欠缺和修复曾经到了第 5 个分支,因而咱们抉择第五个版本来试验,首先点击左上角的 master 这个图标来抉择我的项目的第 5 个分支,如下图所示,而后将版本抉择好当前,点击右上角的 code 那个按键,将代码下载下来。至此整个我的项目就曾经筹备好了。

将咱们下载好的 yolov5 的代码解压,而后用一款 IDE 关上关上之后整个代码目录如下图:

当初来对代码的整体目录做一个介绍:

以上就是 yolov5 我的项目代码的整体介绍。咱们训练和测试本人的数据集根本就是利用到如上的代码。
六、环境的装置和依赖的装置
关上 requirements.txt 这个文件,能够看到外面有很多的依赖库和其对应的版本要求。咱们关上 pycharm 的命令终端,在中输出如下的命令,就能够装置了。
pip install -r requirements.txt
至此,深度学习的环境和依赖包就都完结了。
七、训练本人的模型
预训练模型和数据集都筹备好了,就能够开始训练本人的 yolov5 指标检测模型了,训练指标检测模型须要批改两个 yaml 文件中的参数。一个是 data 目录下的相应的 yaml 文件,一个是 model 目录文件下的相应的 yaml 文件。批改 data 目录下的相应的 yaml 文件。找到目录下的 voc.yaml 文件,将该文件复制一份,将复制的文件重命名,最好和我的项目相干,这样不便前面操作。我这里批改为 hat.yaml。(这个名字是轻易起的)

关上这个文件夹批改其中的参数,首先将箭头 1 中的那一行代码正文掉(我曾经正文掉了),如果不正文这行代码训练的时候会报错;箭头 2 中须要将训练和测试的数据集的门路填上(最好要填绝对路径,有时候由目录构造的问题会莫名微妙的报错);箭头 3 中须要检测的类别数,我这里是辨认安全帽和人,所以这里填写 2;最初箭头 4 中填写须要辨认的类别的名字(必须是英文,否则会乱码辨认不进去)。到这里和 data 目录下的 yaml 文件就批改好了。

因为该我的项目应用的是 yolov5s.pt 这个预训练权重,所以要应用 models 目录下的 yolov5s.yaml 文件中的相应参数(因为不同的预训练权重对应着不同的网络层数,所以用错预训练权重会报错)。同上批改 data 目录下的 yaml 文件一样,咱们最好将 yolov5s.yaml 文件复制一份,而后将其重命名,我将其重命名为 yolov5_hat.yaml。

关上 yolov5_hat.yaml 文件只须要批改如图中的数字就好了,这里是辨认 12 个类别

至此,相应的配置参数就批改好了。
如果下面的数据集和两个 yaml 文件的参数都批改好了的话,就能够开始 yolov5 的训练了。首先咱们找到 train.py 这个 py 文件。

而后找到主函数的入口,这外面有模型的主要参数。模型的主要参数解析如下所示。

至此,就能够运行 train.py 函数训练本人的模型了。
八、应用炼丹侠的 A100 进行训练
关上炼丹侠官网

之后抉择时长、卡的数量和镜像之后,点击立刻创立之后跳转至控制台界面

在此处可通过 ip 和端口对服务器进行连贯,之后实现训练即可

正文完
 0