湖南网站建设公司磐石网络,商业网站策划书模板范文,网站和二级目录权重,高手做网站1.Yolov5算法原理和网络结构 YOLOv5按照网络深度和网络宽度的大小#xff0c;可以分为YO-LOv5s、YOLOv5m、YOLOv5l、YOLOv5x。本文使用YOLOv5s#xff0c;它的网络结构最为小巧#xff0c;同时图像推理速度最快达0.007s。YO-LOv5的网络结构主要由四部分组成#xff0c;分别…1.Yolov5算法原理和网络结构 YOLOv5按照网络深度和网络宽度的大小可以分为YO-LOv5s、YOLOv5m、YOLOv5l、YOLOv5x。本文使用YOLOv5s它的网络结构最为小巧同时图像推理速度最快达0.007s。YO-LOv5的网络结构主要由四部分组成分别是Input、Backbone、Neck、Head其网络结构图如图所示。 Yolov5网络结构图
1.1Input端 Input使用了Mosaic数据增强、自适应锚框计算、图片尺寸处理。Mosaic数据增强把4张图片采用随机缩放、随机裁剪、随机排布的方式进行拼接,极大地丰富了检测数据集尤其是增加了很多小目标让网络结构的鲁棒性更好。在YOLOv5算法中不同的数据集会设定不同初始长宽的锚框,在训练数据的时候在初始锚框的基础上得到预测框把它和真实框比较算出两者差距反向更新迭代更新网络结构参数自适应锚框计算可以得到最佳锚框值。在目标检测算法中要训练图片的尺寸都不相同要把原始图片统一缩放到一个固定尺寸再输入到网络中进行训练本文图片的尺寸为608×608×3。
1.2Backone Backbone包含Focus、CSP和SPP。Focus不存在于其他YOLO算法中主要是用来进行切片操作例如608×608×3的图像在Focus结构中进行切片操作后变成304×304×12大小,在进行32个卷集核的卷积操作成为304×304×32的特征图。YOLOv4中只有一种CSP结构而YOLOv5中有两种CSP1x和CSP2x它们分别应用于Backbone和Neck中YOLOv4的CSP结构只存在Backbone中CSP结构如图1所示,其中CSP1x的x表示CSP1中有x个Resunit残差组件CSP2x的x表示CSP2中有2x个CBL,x影响着网络结构的深度。在Backbone中采用SPP空间向量金字塔池化对特征图做最大池化将不同尺度的特征图拼接在一起。
1Focus结构 Focus结构中关键的是切片操作切片操作演示过程将4×4×3的特征图经过切片处理变成2×2×12的特征图。将608×608×3的三通道图像输进Focus结构经过切片操作先变成304×304×12的特征图之后经过使用32个卷积核的卷积操作最终变成304×304×32的特征图。需要注意的是YOLOv5s网络结构中的Focus结构使用了32个卷积核进行卷积操作而其他三种网络结构使用的卷积核数量有所增加。 Focus结构图
2CSP结构 YOLOv5中有两种结构的CSP,CSP1X结构在Backbone主干网络中另一种CSP2X结构在Neck中。对于Backbone的主干网络结构CSP模块中的卷积核大小都是3*3步进值为2假如输入的图像尺寸是608*608那么它的特征图变化的规律是608*608-304*304-152*152-76*76-38*38-19*19最终得到了一个19*19大小的特征图。 使用CSP模块的优点1.增强网络的学习能力使得训练出来的模型既能保持轻量化又能有较高的准确性。2.降低计算瓶颈。3.降低内存成本。 CSP结构图
3SPP结构 SPP结构详细介绍https://www.cnblogs.com/zongfa/p/9076311.html SPP结构图
1.3Neck Neck中采用了FPNPAN的结构FPN是自上而下的利用上采样的方式对信息进行传递融合获得预测的特征图。PAN采用自底向上的特征金字塔。具体结构如图所示。 FPNPAN结构图
1.4Prediction Prediction包括Bounding box损失函数和非极大值抑制(NMS)。YOLOv5中使用GIOULoss作为损失函数有效解决了边界框不重合时问题。在目标检测预测结果处理阶段针对出现的众多目标框的筛选采用加权NMS操作获得最优目标框。
GIOU_Loss损失函数目标检测算法的损失函数一般由Classificition Loss分类损失函数以及Bounding Box Regeression Loss回归损失函数两大部分组成。回归损失函数在近几年的发展过程是Smooth L1 Loss-IOULoss(2016)-GIOULoss(2019)-DIOULoss(2020)-CIOULoss(2020。 IOU_Loss图 图是IOULoss可以看出黄色框是预测框蓝色框是真实框。假设预测框和真实框的交集为A并集为B,IOU定义为交集A除以并集B,IOU的Loss为 IOU的Loss比较简单但存在两个问题。 问题1预测框和真实框不相交的情况如图(a状态1所示此时IOU为0无法反应出预测框和真实框距离的远近此时损失函数不能求导IOULoss损失函数无法优化预测框和真实框不相交的情况 特殊状态的IOU_Loss图 问题2当预测框和真实框大小相同IOU也可能会相同如上图(b)(c的状态2和状态3的情况所示此时IOULoss损失函数也不能区分这两种情况的不同。因此使用GIOU_Loss来进行改进。 GIOU_Loss图 如上图是GIOULoss黄色框是预测框蓝色框是真实框令预测框和真实框的最小外接矩形为集合C差集定义为集合C和并集B的差则GIOULoss为 GIOULoss损失函数提高了衡量相交尺度的方式减少了单纯IOULoss时的不足。
2.实验及结果
2.1实验数据集及实验环境
2.1.1数据集 数据集采用Kaggle上的Face Mask Detection数据集一共853张图片划分为三个类一种是戴口罩的一种是不戴口罩的还有一种是没有戴好口罩的。数据集链接https://www.kaggle.com/andrewmvd/face-mask-detection 数据集展示 下载下来后这些数据集还不能直接使用。因为yolov5不支持xml文件处理而是支持txt文件。所以首先将这些数据按照下图这样的目录格式整理好 然后运行下面的代码将该数据集转换成Yolov5能够使用的数据集
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 copyfileclasses [with_mask, without_mask,mask_weared_incorrect]
# classes[ball]TRAIN_RATIO 80def 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.0y (box[2] box[3]) / 2.0w box[1] - box[0]h box[3] - box[2]x x * dww w * dwy y * dhh h * dhreturn (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).textcls obj.find(name).textif cls not in classes or int(difficult) 1:continuecls_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 filesprob 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 .xmlannotation_path os.path.join(annotation_dir, annotation_name)label_name nameWithoutExtention .txtlabel_path os.path.join(yolo_labels_dir, label_name)prob random.randint(1, 100)print(Probability: %d % prob)if (prob TRAIN_RATIO): # train datasetif os.path.exists(annotation_path):train_file.write(image_path \n)convert_annotation(nameWithoutExtention) # convert labelcopyfile(image_path, yolov5_images_train_dir voc_path)copyfile(label_path, yolov5_labels_train_dir label_name)else: # test datasetif os.path.exists(annotation_path):test_file.write(image_path \n)convert_annotation(nameWithoutExtention) # convert labelcopyfile(image_path, yolov5_images_test_dir voc_path)copyfile(label_path, yolov5_labels_test_dir label_name)
train_file.close()
test_file.close()运行完上面的代码后会生成下面的目录格式 可以看到通过运行上面的代码在VOCdevkit目录下生成了images和lables文件夹这两个文件夹下又有train和val文件夹这个就是需要的数据集了。其中train对应的就是训练集val对应的就是测试集。
2.2.2数据集标注 因为数据集中已经给定了标注好的xml文件这里就不再进行标注。数据集标注主要是通过labelimg进行标注。
2.2.3实验环境 实验环境采用Ubuntu 20.04.2双路Intel 4110CPU64G内存RTX2080Ti显卡Anaconda3进行实验。
2.2Yolov5网络训练 一般为了缩短网络的训练时间并达到更好的精度我们一般加载预训练权重进行网络的训练。而yolov5的5.0版本给我们提供了几个预训练权重我们可以对应我们不同的需求选择不同的版本的预训练权重。通过如下的图可以获得权重的名字和大小信息可以预料的到预训练权重越大训练出来的精度就会相对来说越高但是其检测的速度就会越慢。预训练权重可以通过这个网址进行下载本次训练自己的数据集用的预训练权重为yolov5s.pt。 我们先将Yolov5通过git将代码pull到本地可以看到如下的目录格式 然后我们将下载好的Yolov5.pt模型文件放在Yolov5的根目录下。将数据集文件也放在Yolov5根目录下 现在来对代码的整体目录做一个介绍
├── data主要是存放一些超参数的配置文件这些文件yaml文件是用来配置训练集和测试集还有验证集的路径的其中还包括目标检测的种类数和种类的名称还有一些官方提供测试的图片。如果是训练自己的数据集的话那么就需要修改其中的yaml文件。但是自己的数据集不建议放在这个路径下面而是建议把数据集放到yolov5项目的同级目录下面。
├── models里面主要是一些网络构建的配置文件和函数其中包含了该项目的四个不同的版本分别为是s、m、l、x。从名字就可以看出这几个版本的大小。他们的检测测度分别都是从快到慢但是精确度分别是从低到高。这就是所谓的鱼和熊掌不可兼得。如果训练自己的数据集的话就需要修改这里面相对应的yaml文件来训练自己模型。
├── utils存放的是工具类的函数里面有loss函数metrics函数plots函数等等。
├── weights放置训练好的权重参数。
├── detect.py利用训练好的权重参数进行目标检测可以进行图像、视频和摄像头的检测。
├── train.py训练自己的数据集的函数。
├── test.py测试训练的结果的函数。
├──requirements.txt这是一个文本文件里面写着使用yolov5项目的环境依赖包的一些版本可以利用该文本导入相应版本的包。 然后我们修改models/yolov5s.yaml文件将nc改成3因为我们是个3分类问题。并且在data目录下创建一个biaoqing.yaml文件其内容为
train: Mask_Datas/images/train # train images (relative to path) 128 images
val: Mask_Datas/images/val # val images (relative to path) 128 images# Classes
nc: 3 # number of classes
names: [with_mask, without_mask, mask_weared_incorrect] # class names里面指定了训练集和测试集的路径以及分类的内容。 然后我们修改Yolov5根目录下的train.py文件修改超参数如下图。其中—weights指定了预训练权重--cfg指定预训练权重的配置文件--data指定数据集的配置文件。还有一些参数比如—epochs指定了训练的轮数默认是300轮可以根据需要进行修改。还有--batch-size指定一次读取多少张照片一般都是指定8的倍数张。根据自己的电脑性能进行修改。 修改完上面的参数后我们将代码上传到了运行环境如下 通过requirements.txt安装了所需要的库。直接运行python train.py即可开始进行训练下面是训练图 经过200轮训练后我们生成了一个best.pt也就是在这200轮训练得出来的最后的权重文件。
2.3实验结果与分析 我们查看results.png文件如下图 训练过程中随着迭代次数增加各种数值变化如上图所示图中各个数值的含义如下
GIo U数值越接近0目标框画的越准确。
Objectness数值越接近0对目标检测得越准确。
Classification数值越接近0目标分类越准确。
Precision准确率即标出的正确目标个数除以标出的目标总个数越接近1准确率越高。
Recall召回率即标出的正确目标个数除以需要标出的目标总个数越接近1准确率越高。
m AP0.5和m AP0.5:0.95:AP是用Precision和Recall作为两坐标轴作图后围成的面积越接近1准确率越高。 置信度图 P-R图 混淆矩阵 实验效果