Darknet_Yolov3模型搭建

YOLO(You only look once)是目前流行的目标检测模型之一,目前最新已经发展到V3版本了,在业界的应用也很广泛。YOLO的特点就是“快”,但由于YOLO对每个网格只预测一个物体,就容易造成漏检,对物体的尺度相对比较敏感,对于尺度变化较大的物体泛化能力较差。YOLO的基本原理是:首先对输入图像划分成7x7的网格,对每个网格预测2个边框,然后根据阈值去除可能性比较低的目标窗口,最后再使用边框合并的方式去除冗余窗口,得出检测结果,如下图:

Darknet卷积模块

Yolo系列的作者把yolo网络叫做Darknet,其实其他神经网络库都已经把卷积层写好了,直接堆叠起来即可。

darknet卷积模块是这个模型里最基本的网络单元,包括卷积层、batch norm(BN)层、激活函数,因此类型命名为
DarknetConv2D_BN_Leaky。原keras实现是卷积层加了L2正则化预防过拟合,Pytorch是把这个操作放到了Optimizer中,所以将在第三部分讲解。

用Pytorch需要注意, 如果训练的时候GPU显存不大,batch size设的很小,这时候就要考虑训练数据集的分布情况。举个例子,加入的batch
size设成了1,但数据每张图差别都很大,这会导致的网络一直在震荡,即使网络能够训练到很低的training loss,

在做预测的时候效果也不好,这主要是BN造成的。因为每批数据的统计量(均值和方差)都不同,而且差别大,这就导致网络训练学不到好的BN层的统计量。如果直接去掉BN层,会发现网络训练非常慢,所以BN层还是要加的,好在Pytorch里的BN有个接口来控制要不要记住每批训练的统计量,即track_running_stats=True,如果训练的batch size不能设特别大,就把它改成False。

卷积层、BN层说完了,激活函数Yolo里用的是0.1的LeakReLU,本实验与ReLU没什么明显的区别。

结构很简答,这部分直接上代码,不画图了。

import torch.nn as nn

import torch

class DarknetConv2D_BN_Leaky(nn.Module):

def __init__(self, numIn, numOut, ksize, stride = 1, padding = 1):super(DarknetConv2D_BN_Leaky, self).__init__()self.conv1 = nn.Conv2d(numIn, numOut,

ksize, stride, padding)#regularizer’:
l2(5e-4)

    self.bn1 = nn.BatchNorm2d(numOut)self.leakyReLU = nn.LeakyReLU(0.1)def forward(self, x):x = self.conv1(x)x = self.bn1(x)x = self.leakyReLU(x)return x

残差模块

残差模块是借鉴了ResNet,残差模块是为了保证深的模型能够得到很好的训练。残差模块ResidualBlock,对外接口有numIn, numOut, numBlock,分别控制模块的输入通道数,输出通道数(卷积核数)和残差模块的堆叠次数。下图是一个numBlock = 2 的模型,注意这里CONV是指上一部分说的Darknet卷积模块,第一个模块(D2)表示是这个卷积模块stride = 2,顺便执行了2倍降采样操作。也就是说特征每经过一个残差模块,分辨率降为原来的一半。

class ResidualBlock(nn.Module):

def __init__(self, numIn, numOut, numBlock):super(ResidualBlock, self).__init__()self.numBlock = numBlockself.dark_conv1 =

DarknetConv2D_BN_Leaky(numIn, numOut, ksize = 3, stride = 2, padding = 1)

    self.dark_conv2 = []for i in range(self.numBlock):layers = []

layers.append(DarknetConv2D_BN_Leaky(numOut, numOut//2, ksize = 1,
stride = 1, padding = 0))

layers.append(DarknetConv2D_BN_Leaky(numOut//2, numOut, ksize = 3,
stride = 1, padding = 1))

        self.dark_conv2.append(nn.Sequential(*layers))self.dark_conv2 =

nn.ModuleList(self.dark_conv2)

def forward(self, x):x = self.dark_conv1(x)for convblock in self.dark_conv2:residual = xx = self.convblock(x)x = x + residualreturn x

后端输出模块

后端输出模块是一个三次降采样(三次升采样在下一部分介绍),这三次降采样+三次升采样,类似Encoder-Decoder的FCN模型。这是为了在三种不同尺度上预测。本系列将在voc2007上训练,训练前输入图片要resize到256x256,那么这三种尺度分别是32x32,16x16,8x8。这一部分是因为图片中的目标有大有小,为了保证从不同尺度上找到最好尺度的特征图来进行预测。当然准确提升的同时,由于分辨率有提升,计算量又有一定的增加,索性这里的分辨率不大。下图所示为最后输出模块,这个模块有两个输出,一个是用作下一个模块的输入,一个是用于输出目标检测结果,即坐标、类别和目标置信度,这一部分将在下一篇详细介绍。注意红色的Conv不是DarknetConv2D_BN_Leaky,而是指普通的卷积模块。

class LastLayer(nn.Module):

def __init__(self, numIn, numOut, numOut2):super(LastLayer, self).__init__()self.dark_conv1 =

DarknetConv2D_BN_Leaky(numIn, numOut, ksize = 1, stride = 1, padding = 0)

    self.dark_conv2 =

DarknetConv2D_BN_Leaky(numOut, numOut*2, ksize = 3, stride = 1, padding = 1)

    self.dark_conv3 =

DarknetConv2D_BN_Leaky(numOut*2, numOut, ksize = 1, stride = 1, padding = 0)

    self.dark_conv4 =

DarknetConv2D_BN_Leaky(numOut, numOut*2, ksize = 3, stride = 1, padding = 1)

    self.dark_conv5 =

DarknetConv2D_BN_Leaky(numOut*2, numOut, ksize = 1, stride = 1, padding = 0)

    self.dark_conv6 =

DarknetConv2D_BN_Leaky(numOut, numOut*2, ksize = 3, stride = 1, padding = 1)

    self.conv7 = nn.Conv2d(numOut*2,

numOut2, 1, stride = 1, padding = 0)

def forward(self, x):x = self.dark_conv1(x)x = self.dark_conv2(x)x = self.dark_conv3(x)x = self.dark_conv4(x)x = self.dark_conv5(x)y = self.dark_conv6(x)y = self.conv7(y)return x,y

Yolov3模型

基本的模块已经定义好,Yolov3的模型就是把这些模型叠加起来。注意下图就是Yolov3的简化模型,数字表示该上一个模块的输出特征尺寸(CxHxW),相应的颜色对应相应的模块。

class Yolov3(nn.Module):

def __init__(self, numAnchor, numClass):super(Yolov3, self).__init__()self.dark_conv1 =

DarknetConv2D_BN_Leaky(3, 32, ksize = 3, stride = 1, padding = 1)

    self.res1 = ResidualBlock(32, 64, 1)self.res2 = ResidualBlock(64, 128, 2)self.res3 = ResidualBlock(128, 256, 8)self.res4 = ResidualBlock(256, 512, 8)self.res5 = ResidualBlock(512, 1024, 4)self.last1 = LastLayer(1024, 512,

numAnchor*(numClass+5))

    self.up1 =

nn.Sequential(DarknetConv2D_BN_Leaky(512, 256, ksize = 1, stride = 1, padding =0),

nn.Upsample(scale_factor=2))
self.last2 = LastLayer(768, 256,
numAnchor*(numClass+5))

    self.up2 =

nn.Sequential(DarknetConv2D_BN_Leaky(256, 128, ksize = 1, stride = 1, padding =0),

nn.Upsample(scale_factor=2))

self.last3 = LastLayer(384, 128,
numAnchor*(numClass+5))

def forward(self, x):x = self.dark_conv1(x)#32x256x256 x = self.res1(x)#64x128x128x = self.res2(x)#128x64x64x3 = self.res3(x)#256x32x32x4 = self.res4(x3)#512x16x16x5 = self.res5(x4)#1024x8x8x,y1 = self.last1(x5)#512x8x8, x = self.up1(x)#256x16x16x = torch.cat((x, x4), 1)#768x16x16x,y2 = self.last2(x)#256x16x16x = self.up2(x)#128x32x32x = torch.cat((x, x3), 1)#384x32x32x,y3 = self.last3(x)#128x32x32return y1,y2,y3

到这里模型已经完成,模型代码结构非常清晰。有人可能会问,为什么要这种堆叠方式,其实自己根据新的需求定义网络结构完全可以,但是要注意模型深度增加时如何保证收敛,如何加速模型训练,同时输出特征的分辨率要计算好。

Darknet_Yolov3模型搭建相关推荐

  1. PyTorch 笔记(20)— torchvision 的 datasets、transforms 数据预览和加载、模型搭建(torch.nn.Conv2d/MaxPool2d/Dropout)

    计算机视觉是深度学习中最重要的一类应用,为了方便研究者使用,PyTorch 团队专门开发了一个视觉工具包torchvision,这个包独立于 PyTorch,需通过 pip instal torchv ...

  2. 【直播】陈安东,但扬:CNN模型搭建、训练以及LSTM模型思路详解

    CNN模型搭建.训练以及LSTM模型思路详解 目前 Datawhale第24期组队学习 正在如火如荼的进行中.为了大家更好的学习"零基础入门语音识别(食物声音识别)"的课程设计者 ...

  3. python利器app怎么查文献-科研人必备:一个工具搞定文献查阅、数据分析、模型搭建...

    原标题:科研人必备:一个工具搞定文献查阅.数据分析.模型搭建 写论文有多难?这首诗形容得好: 进入学校先选题,踌躇满志万人敌:发现前辈都做过,满脸懵逼加惊奇. 终于找到大空白,我真是个小天才:左试右试 ...

  4. 信息抽取(一)机器阅读理解——样本数据处理与Baseline模型搭建训练(2020语言与智能技术竞赛)

    机器阅读理解--样本数据处理与Baseline模型搭建训练 前言 样本数据处理 数据测试 模型部分 模型构建 模型训练 部分推理结果 总结 前言 最近看到今年早些时候百度的"2020语言与智 ...

  5. kaggle实战—泰坦尼克(五、模型搭建-模型评估)

    kaggle实战-泰坦尼克(一.数据分析) kaggle实战-泰坦尼克(二.数据清洗及特征处理) kaggle实战-泰坦尼克(三.数据重构) kaggle实战-泰坦尼克(四.数据可视化) kaggle ...

  6. 目标检测——夏侯南溪模型搭建篇(legacy)

    4 定义模型整体结构 4.3.1 输入样本的预处理操作 (注意:训练样本在输入网路之前,需要进行归一化,包括:均值归一化操作 具体可以看看我写的<目标检测--输入数据的归一化操作>) MT ...

  7. 图像语义分割实践(三)模型搭建与实现

    众所周知,神经网络搭建常用基础模块有卷积,池化,归一,激活,全连接等等.如果使用Pytorch进行网络的搭建时,除了需要掌握这些基础模块外,还需要熟悉模型容器. Pytorch.nn 的容器conta ...

  8. 泰坦尼克号 第三章 模型搭建和评估

    第三章 模型搭建和评估–建模 经过前面的两章的知识点的学习,我可以对数数据的本身进行处理,比如数据本身的增删查补,还可以做必要的清洗工作.那么下面我们就要开始使用我们前面处理好的数据了.这一章我们要做 ...

  9. Gazebo仿真平台模型搭建与修改

    ROS进阶教程(一)Gazebo仿真平台模型搭建与修改 文件讲解 Models 文件 World文件 Launch文件 模型编辑 可视化操作 配置文件编辑 仿真操作流程 完成model建模 world ...

最新文章

  1. TensorRT Samples: CharRNN
  2. ## *将以下学生成绩数据,存放在Hdfs上,使用Spark读取完成下面分析**
  3. VS Code插件之Cordova Tools
  4. Tech.ED 2009前瞻:认识System Center
  5. [原]关于在 iOS 中支持 DLNA
  6. leetcode145. 二叉树的后序遍历 意想不到的骚操作
  7. python重命名窗口_为《Python实现批量重命名》程序加一个GUI
  8. 进程间通信-Queue 消息队列 先进先出
  9. 郁金香汇编代码注入怎么写看雪_世界黑客编程大赛冠军的汇编代码 你见过吗?...
  10. jq在html中添加dom元素,使用jQuery添加DOM元素的最佳方法
  11. Win11字体显示不全怎么解决?
  12. 后台管理系统--毕业设计02
  13. 关于EasyExcel 优化,实现格式自定义,数据字典自动转化。
  14. 正确的姿势很重要:该如何执笔
  15. springboot整合author2
  16. Ubuntu安装flash
  17. Citrix实践(三)——安装XenCenter管理XenServer
  18. 如何高效学习(斯科特·扬 )(含思维导图)
  19. java 内存模型面试_Java面试- JVM 内存模型讲解
  20. 赛门铁克拆分后蜕变:未来不只是“防病毒”

热门文章

  1. Docker安装Apache与运行简单的web服务——httpd helloworld
  2. OpenCV 笔记(02)— 图像显示、保存、腐蚀、模糊、canny 边缘检测(imread、imshow、namedWindow、imwrite)
  3. c语言中struct和c++中class实例对比
  4. 【Spring】spring基于注解的声明式事务控制
  5. 毕业,新的开始,撸起袖子加油干!
  6. 【Sql Server】DateBase-高级查询
  7. linux系统管理必备知识之关机命令
  8. PyTorch 学习笔记(四):权值初始化的十种方法
  9. Kafka史上最详细原理总结 ----看完绝对不后悔
  10. CodeGen字段循环Field Loop