目标检测学习笔记(一)——YoloV4环境配置及代码实现

2024-02-07 04:08

本文主要是介绍目标检测学习笔记(一)——YoloV4环境配置及代码实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
      • 环境配置
      • 参考
  • 一、yoloV3算法原理及实现
    • yolov3 算法原理
    • 主干提取网络 Darknet53 介绍
      • 残差网络
      • Darknet53
    • 预测部分
    • 训练部分
    • 其他参考
  • 二、YoloV4 算法原理
    • YOLOV4改进的部分
    • 主干特征提取网络Backbone
  • 三、YoloV4 算法程序实现
    • 1 训练及预测步骤
      • 训练 P10
        • VOC2007文件夹 和 voc2yolo4.py
        • voc_annotation.py
        • train.py
      • 预测 P11
        • yolo.py 代码修改
        • predict.py 预测
      • 说明
        • train.py 参数说明P12
        • count_anchors P13
        • 马赛克数据增强 P14
        • 利用CIOU计算 回归损失 P15
        • LOSS计算过程 P16
    • 2 绘图
        • 计算map并绘图
          • **什么是AP**
        • 绘制loss曲线
          • SummaryWriter()
          • writer.add_graph()
          • writer.add_scalar()
          • tensorboard --logdir =
        • 问题及解决方案
    • 3 相关应用
      • 通过snap7与西门子PLC通信
  • 四、相关问题

前言

环境配置

windows下的torch=1.2.0环境配置

查看有哪些 虚拟环境 :conda info --env

Anaconda+Pycharm环境下的PyTorch配置方法

参考

yolov3参考:

YOLOv3 深入理解

视频学习链接:

视频地址:Pytorch 搭建自己的YOLO3目标检测平台(Bubbliiiing 深度学习 教程)

博客地址:睿智的目标检测26——Pytorch搭建yolo3目标检测平台

源码地址


一、yoloV3算法原理及实现

参考:

睿智的目标检测26——Pytorch搭建yolo3目标检测平台

ResNet50 、 残差网络

神经网络学习小记录20——ResNet50模型的复现详解

昇腾

基于Atlas 200 DK的原版YOLOv3(基于Darknet-53)实现v

yolov3 算法原理

实现代码darknet.py yolo3.py

img

主干提取网络 Darknet53 介绍

YoloV3所使用的主干特征提取网络为Darknet53,它具有两个重要特点:

1、Darknet53具有一个重要特点是使用了残差网络Residual,Darknet53中的残差卷积就是首先进行一次卷积核大小为3X3、步长为2的卷积,该卷积会压缩输入进来的特征层的宽和高,此时我们可以获得一个特征层,我们将该特征层命名为layer。之后我们再对该特征层进行一次1X1的卷积和一次3X3的卷积,并把这个结果加上layer,此时我们便构成了残差结构。通过不断的1X1卷积和3X3卷积以及残差边的叠加,我们便大幅度的加深了网络。

残差网络的特点容易优化,并且能够通过增加相当的深度来提高准确率。其内部的残差块使用了跳跃连接,缓解了在深度神经网络中增加深度带来的梯度消失问题。

img

2、Darknet53的每一个卷积部分使用了特有的DarknetConv2D结构,每一次卷积的时候进行l2正则化,完成卷积后进行BatchNormalization标准化LeakyReLU

普通的ReLU是将所有的负值都设为零,Leaky ReLU则是给所有负值赋予一个非零斜率。以数学的方式我们可以表示为:

img

残差网络

参考:[神经网络学习小记录20——ResNet50模型的复现详解]((66条消息) 神经网络学习小记录20——ResNet50模型的复现详解_Bubbliiiing的学习小课堂-CSDN博客)

Residual net(残差网络):

将靠前若干层的某一层数据 输出直接 跳过多层 引入到后面数据层的输入部分。
意味着 后面的特征层的内容会有一部分由其前面的 某一层线性贡献。

其结构如下:

img

深度残差网络的设计是为了 克服由于 网络深度加深而产生的学习效率变低准确率无法有效提升的问题。

Darknet53

Darknet53 除了最开始的卷积块 Conv2D ,其他都是由残差网络构成的残差块Residual Block

img

PS:该图有一些小问题,宽高最小的特征层在经过Conv2D Block 5L的处理后,它的shape按照代码应该为(batch_size,13,13,512),而非图中的(batch_size,13,13,1024)。

  • 主干特征提取网络:提取特征

image-20210524153545354

输入是一个416x416x3——>进行下采样,宽高会不断的被压缩,在不断卷积之后 ,通道数(channel数/kernel的数目)由 3 逐渐增多,变为 1024。——>可以获得一堆特征层,用来表示输入进来图片的特征。

  • 下采样:

image-20201011092837904

52,52,256
26,26,512    会和  13,13,1024  层的上采样得到的特征层  进行堆叠,构建特征金字塔
13,13,1024   进行5次卷积的操作,会有两个方向的前进,即  分类预测  和  回归预测
  • 路径一:分类预测 和 回归预测的结果

image-20201011092845960

13×13×75 = 13×13×3×25 = 13×13×3×(20+1+4) 13,13(把输入的图片划分成13 × 13的网格,每个网格上面存在 3 个先验框),75   -> 13,13,3(3个先验框,它是预先标注在图片上的,用以检测物体)×25(25分为20+1+4)   ->   
13,13,3,20(框内部物体属于某一个类的概率,总共20个类)+1(判别是否有物体)+4(先验框的调整参数,4个参数确定一个框)

13×13×3×(20+1+4) 的理解:预测的结果判断各个网格(13)的 先验框(3)里 是否真的包含物体(1),然后判断物体的种类(20),然后对先验框进行 中心 和 宽高的调整(4),使其变成 预测框

  • 路径二:卷积后上采样

上采样会使得特征层宽高得到扩张, 会和 【26,26,512】 特征层进行堆叠,该过程就是在构建特征金字塔,利用特征金字塔可以进行多尺度特征融合,提取出更有效地特征。

image-20210524163713965

image-20201011093650791

26,26,512    会和  13,13,1024  上采样得到的特征层进行堆叠,构建特征金字塔
然后进行5次卷积  
得到:26,26,75  ——>   
分解:26,26,3x25   ——>   26x26x3x(20+1+4)26x26x3x(20+1+4)理解同路径一:13×13×3×(20+1+4)
  • 路径三:

同理:

image-20201011094134564

预测部分

参考

神经网络学习小记录27——数据预处理

睿智的目标检测26——Pytorch搭建yolo3目标检测平台_Bubbliiiing的学习小课堂-CSDN博客

步骤:

从特征获取预则结果

预则结果的解码

在原图上进行绘制

训练部分

计算loss所需参数

pred是什么

target是什么

loss的计算过程

其他参考

yolo系列之yolo v3【深度解析】

img

DBL: 如图1左下角所示,也就是代码中的Darknetconv2d_BN_Leaky,是yolo_v3的基本组件。就是卷积+BN+Leaky relu。对于v3来说,BN和leaky relu已经是和卷积层不可分离的部分了(最后一层卷积除外),共同构成了最小组件。

深度学习 BN 、LeakyReLU算法原理

resn:n代表数字,有res1,res2, … ,res8等等,表示这个res_block里含有多少个res_unit。这是yolo_v3的大组件,yolo_v3开始借鉴了ResNet的残差结构,使用这种结构可以让网络结构更深(从v2的darknet-19上升到v3的darknet-53,前者没有残差结构)。对于res_block的解释,可以在图1的右下角直观看到,其基本组件也是DBL。

concat:张量拼接。将darknet中间层和后面的某一层的上采样进行拼接。拼接的操作和残差层add的操作是不一样的,拼接会扩充张量的维度,而add只是直接相加不会导致张量维度的改变。

DBL

二维卷积操作(DarknetConv2D)

归一化(BatchNormalization)

非线性激活函数(LeakyReLU)

backbone

整个v3结构里面,是**没有池化层和全连接层**的(下采样层也叫池化层:池化层理解、卷积层与池化层、CNN 入门讲解:什么是全连接层)。

前向传播过程中,张量的尺寸变换是通过改变 卷积核 的步长来实现的,比如stride=(2, 2),这就等于将图像边长缩小了一半(即面积缩小到原来的1/4)。在yolo_v2中,要经历5次缩小,会将特征图缩小到原输入尺寸的1 / 2 5 1/2^51/25,即1/32。输入为416x416,则输出为13x13(416/32=13)。

yolo_v3也和v2一样,backbone都会将输出特征图缩小到输入的1/32。所以,通常都要求输入图片是32的倍数。可以对比v2和v3的backbone看看:(DarkNet-19 与 DarkNet-53)


二、YoloV4 算法原理

参见:睿智的目标检测30——Pytorch搭建YoloV4目标检测平台

YOLOV4改进的部分

1、主干特征提取网络:DarkNet53 => CSPDarkNet53

2、特征金字塔:SPP,PAN

3、分类回归层:YOLOv3(未改变)

4、训练用到的小技巧:Mosaic数据增强、Label Smoothing平滑、CIOU、学习率余弦退火衰减

5、激活函数:使用Mish激活函数

主干特征提取网络Backbone

当输入是416x416时,特征结构如下:

img

三、YoloV4 算法程序实现

1 训练及预测步骤

训练 P10

VOC2007文件夹 和 voc2yolo4.py

image-20201103200444770

Annotations 存放标签文件

JPEGimages 存放对应图片文件

ImageSets —》 train.txt 存放图片去掉后缀的名字,由

运行voc2yolo4.py程序自动生成的:

image-20201103201812605

voc_annotation.py
  • 修改classes为自己要检测的对象

image-20201103202956749

  • 运行该py文件,得到:

image-20201103202205130

训练的时候,只需要调用2007_train.txt,即可获取 图片 位置信息 和 图片 内部的信息。

image-20201103202255354

注:文件修改路径后,2007_train.txt也要重新生成:

image-20201104093532869

train.py
  • 选择 输入图片尺寸:

    image-20201103203755313

  • 是否使用 余弦退火衰减

  • 是否使用 mosaic 数据增强方法

image-20201028171534745

  • 是否使用 平滑标签

image-20201028171659395

  • 训练自己的 数据集 需要修改 txt文件,输入自己要检测的类

image-20201103205018007

  • 预训练 模型会保存一些比较好的权重,加快训练效率

image-20201028171923388

点击训练,生成.pth文件,保存至logs文件夹中

预测 P11

把训练好的文件放入 model_data文件夹

yolo.py 代码修改

image-20201028172340898

修改 model_path -----》 自己训练好的权值文件,在log文件夹中

修改classes_path -----》 要分的类,在model_data文件夹中

image-20210518091708171

可以在416 与 608 之间进行修改

置信度修改

根据电脑 是否有显卡 设置 是否使用CUDA

predict.py 预测

点击运行

说明

train.py 参数说明P12

image-20201028173313606

image-20201028173145772

2007_train.txt 图片 绝对路径 + 目标信息

image-20201028173338122

image-20201028173450668

anchors_path 指向先验框,对于 yolov4 模型,总共有9个大小先验框,每个网格上默认有三个先验框

image-20201028173654906

训练集和验证集划分

count_anchors P13

如何为自己的yolo模型计算合适的先验框

运行根目录kmeans_for_anchors.py,进行聚类,求先验框

image-20201028174542964

K聚类算法流程:

睿智的目标检测1——IOU的概念与python实例

将框划分进9个聚类中:1 - IOU(重合程度:交的面积/并的面积) 获得 偏移程度,即 所有的框 距离这 9 个聚类中心的距离,再根据这个距离 对所有的 框 进行划分,划分成9个区域。

对 9 个区域中的框 取平均,重新作为聚类中心,进行下一轮循环,直到聚类中心 不再改变为止。

注:原始先验框 基于coco数据集,适用性很高,可以不用进行替换

马赛克数据增强 P14

睿智的目标检测28——YoloV4当中的Mosaic数据增强方法

image-20201028211054025

利用CIOU计算 回归损失 P15

yolo_training.py

利用 CIOU 对BBox回归损失进行优化

image-20201028211648453

LOSS计算过程 P16

yolo_training.py

LOSS计算过程:

YOLOLoss forward

image-20201028212120682

image-20201028212921242

先验框中是否有物体,

先验框中物体的种类

get_target

真实框 先验框

功能:对真实框做出判断,找到对应的网格点,找到对应的先验框,帮助我们获得网络应该有的预测结果 。

get_target

功能:帮助我们找到应该忽略哪些副样本,并且获得网络的预测框。

返回 noobj_mask 副样本

​ pred_boxes 网络解码后的预测框

2 绘图

计算map并绘图

参考:

睿智的目标检测20——利用mAP计算目标检测精确度_Bubbliiiing的学习小课堂-CSDN博客_睿智的目标检测

检测精度mAP和pr曲线计算参考视频

什么是AP

AP事实上指的是,利用不同的Precision和Recall的点的组合,画出来的曲线下面的面积。
如下面这幅图所示。

img

当我们取不同的置信度,可以获得不同的Precision和不同的Recall,当我们取得置信度够密集的时候,就可以获得非常多的Precision和Recall。

此时Precision和Recall可以在图片上画出一条线,这条线下部分的面积就是某个类的AP值。mAP就是所有的类的AP值求平均。

依次运行:

get_gt_txt.py detection-results:指的是预测结果的txt。

get_dr_txt.py ground-truth:指的是真实框的txt。

get_map.py

绘制loss曲线

参考:

Pytorch Tensorboard可视化工具(Bubbliiiing 深度学习 教程)_哔哩哔哩_bilibili

(75条消息) 神经网络学习小记录49——Pytorch当中Tensorboard的使用_Bubbliiiing的学习小课堂-CSDN博客

SummaryWriter()

这个函数用于创建一个tensorboard文件,其中常用参数有:

  • log_dir:tensorboard文件的存放路径
  • flush_secs:表示写入tensorboard文件的时间间隔

调用方式如下:

writer = SummaryWriter(log_dir='logs',flush_secs=60)
writer.add_graph()

这个函数用于在tensorboard中创建Graphs,Graphs中存放了网络结构,其中常用参数有:

  • model:pytorch模型
  • input_to_model:pytorch模型的输入
if Cuda:graph_inputs = torch.from_numpy(np.random.rand(1,3,input_shape[0],input_shape[1])).type(torch.FloatTensor).cuda()
else:graph_inputs = torch.from_numpy(np.random.rand(1,3,input_shape[0],input_shape[1])).type(torch.FloatTensor)
writer.add_graph(model, (graph_inputs,))
writer.add_scalar()

这个函数用于在tensorboard中加入loss,其中常用参数有:

  • tag:标签,如下图所示的Train_loss

  • scalar_value:标签的值

  • global_step:标签的x轴坐标
    在这里插入图片描述
    调用方式如下:

    writer.add_scalar('Train_loss', loss, (epoch*epoch_size + iteration))
    
tensorboard --logdir =

在完成tensorboard文件的生成后,可在命令行调用该文件,tensorboard网址。
具体代码如下:

tensorboard --logdir=D:\Study\Collection\Tensorboard-pytorch\logs
问题及解决方案

问题1:No module named 'past’

pip3 install future

问题2:No module named 'tensorboard.summary.writer

pip --default-timeout=100 install tensorboard==1.14.0 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

image-20210616103144387

C:\ProgramData\Anaconda3\envs\python36tfgpu\lib\site-packages\tensorflow\python\framework\dtypes.py:516: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'._np_qint8 = np.dtype([("qint8", np.int8, 1)])
C:\ProgramData\Anaconda3\envs\python36tfgpu\lib\site-packages\tensorflow\python\framework\dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'._np_quint8 = np.dtype([("quint8", np.uint8, 1)])
C:\ProgramData\Anaconda3\envs\python36tfgpu\lib\site-packages\tensorflow\python\framework\dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'._np_qint16 = np.dtype([("qint16", np.int16, 1)])
C:\ProgramData\Anaconda3\envs\python36tfgpu\lib\site-packages\tensorflow\python\framework\dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'._np_quint16 = np.dtype([("quint16", np.uint16, 1)])
C:\ProgramData\Anaconda3\envs\python36tfgpu\lib\site-packages\tensorflow\python\framework\dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'._np_qint32 = np.dtype([("qint32", np.int32, 1)])
C:\ProgramData\Anaconda3\envs\python36tfgpu\lib\site-packages\tensorflow\python\framework\dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.np_resource = np.dtype([("resource", np.ubyte, 1)])
C:\ProgramData\Anaconda3\envs\python36tfgpu\lib\site-packages\tensorboard\compat\tensorflow_stub\dtypes.py:541: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'._np_qint8 = np.dtype([("qint8", np.int8, 1)])
C:\ProgramData\Anaconda3\envs\python36tfgpu\lib\site-packages\tensorboard\compat\tensorflow_stub\dtypes.py:542: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'._np_quint8 = np.dtype([("quint8", np.uint8, 1)])
C:\ProgramData\Anaconda3\envs\python36tfgpu\lib\site-packages\tensorboard\compat\tensorflow_stub\dtypes.py:543: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'._np_qint16 = np.dtype([("qint16", np.int16, 1)])
C:\ProgramData\Anaconda3\envs\python36tfgpu\lib\site-packages\tensorboard\compat\tensorflow_stub\dtypes.py:544: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'._np_quint16 = np.dtype([("quint16", np.uint16, 1)])
C:\ProgramData\Anaconda3\envs\python36tfgpu\lib\site-packages\tensorboard\compat\tensorflow_stub\dtypes.py:545: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'._np_qint32 = np.dtype([("qint32", np.int32, 1)])
C:\ProgramData\Anaconda3\envs\python36tfgpu\lib\site-packages\tensorboard\compat\tensorflow_stub\dtypes.py:550: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.np_resource = np.dtype([("resource", np.ubyte, 1)])

问题原因

Numpy版本过高

解决方法

安装低版本的Numpy即可。
执行 pip install numpy==1.16.4

3 相关应用

通过snap7与西门子PLC通信

安装snap7

pip install python-snap7

image-20201217161546775

下载snap7的动态链接文件

image-20201217162026038

四、相关问题

问题汇总

voc_annotation.py问题

AttributeError: 'NoneType' object has no attribute 'text'

(64条消息) 模型训练报错AttributeError: ‘NoneType‘ object has no attribute ‘text‘_u014479551的专栏-CSDN博客

出现了gbk什么的编码错误

UnicodeDecodeError: 'gbk' codec can't decode byte 0xa6 in position 446: illegal multibyte sequence

答:标签和路径不要使用中文,如果一定要使用中文,请注意处理的时候编码的问题,改成打开文件的encoding方式改为utf-8。


这篇关于目标检测学习笔记(一)——YoloV4环境配置及代码实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/686472

相关文章

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

SpringBoot3.4配置校验新特性的用法详解

《SpringBoot3.4配置校验新特性的用法详解》SpringBoot3.4对配置校验支持进行了全面升级,这篇文章为大家详细介绍了一下它们的具体使用,文中的示例代码讲解详细,感兴趣的小伙伴可以参考... 目录基本用法示例定义配置类配置 application.yml注入使用嵌套对象与集合元素深度校验开发

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依