目标检测入坑指南3:VGGNet神经网络
学了蛮久的目标检测了,但是有好多细节总是忘或者模棱两可,感觉有必要写博客记录一下学习笔记和一些心得,既可以加深印象又可以方便他人。博客内容集成自各大学习资源,所以图片也就不加水印了,需要自取。本专栏会详细记录本人在研究目标检测过程中的所学所感,主要包括:1.目标检测算法解读,如R-CNN系列、YOLO系列;2.论文阅读笔记;3.其它目标检测相关的概念和技巧,如attention机制的应用。由于水平有限,不少地方可能会有不准确甚至错误,也希望大家多多包涵并指正一下!
文章目录
- 一、引言
- 二、VGGNet的特点
- 1. 结构简洁
- 2. 使用小卷积核
- 3. 使用小滤波器
- 4. 通道数较多
- 5. 将全连接层转换为卷积层
- 三、网络结构
- 1. 整体纵览
- 2. 卷积层
- 3. 全连接层
- 四、实例演示
一、引言
目标检测整体的框架是由backbone、neck和head组成的,所以在学习具体的目标检测算法之前,有必要了解一下常见的卷积神经网络结构,这有利于后面学习目标检测算法的backbone部分。VGGNet虽然结构比较简单,但是我们所熟知的单目标检测算法SSD就是用VGGNet作为backbone的,因此有必要把VGGNet的网络结构简单过一遍,为后续学习打下基础。
VGGNet是由牛津大学的视觉几何组(Visual Geometry Group)和谷歌旗下DeepMind团队的研究员共同研发提出的,获得了2014年ImageNet图像分类竞赛的第二名。可以将VGGNet看成加深版的AlexNet,也是由卷积层和全连接层两部分组成,只不过卷积核尺寸都是3×3的。VGGNet的核心思想是利用较小的卷积核增加网络的深度,其主要贡献是证明了增加网络深度是可以有效提升模型性能的,并且对于其他数据集也有很好的泛化性能。在AlexNet论文中,作者最后指出了网络深度对最终的分类结果有很大的影响,而VGGNet则更加直接地论证了这一结论。常用的VGGNet有VGG16和VGG19两种类型,前者拥有13个核大小均为3×3的卷积层、5个最大池化层和3个全连接层,后者拥有16个核大小均为3×3的卷积层、5个最大池化层和3个全连接层。本文主要针对VGG16进行解读,可以看出VGG19只是多了3个卷积层而已,其它的和VGG16没啥区别。
二、VGGNet的特点
1. 结构简洁
VGGNet的结构十分简洁,由5个卷积层、3个全连接层和1个softmax层构成,层与层之间使用最大池化连接,隐藏层之间使用的激活函数全都是ReLU。并且网络的参数也是整齐划一的,赏心悦目。
2. 使用小卷积核
VGGNet使用含有多个小型的3×3卷积核的卷积层来代替卷积核较大的卷积层。2个3×3的卷积核堆叠的感受野相当于一个5×5的卷积核的感受野,而3个3×3的卷积核堆叠的感受野则相当于一个7×7的卷积核的感受野。因此,采用多个小型卷积核,既能减少参数的数量,又能增强网络的非线性映射从而提升网络的表达能力。
为什么可以增加网络的非线性?我们知道激活函数的作用就是给神经网络增加非线性因素,使其可以拟合任意的函数,每个卷积操作后都会通过ReLU激活,ReLU函数就是一个非线性函数。下图展示了为什么使用2个3x3的卷积核可以代替5×5卷积核。
总结一下,使用多个3×3卷积堆叠的作用有两个:一是在不影响感受野的前提下减少了参数;二是增加了网络的非线性。
3. 使用小滤波器
与AlexNet相比,VGGNet在池化层全部采用的是2×2的小滤波器。
4. 通道数较多
VGGNet的第一层有64个通道,后面的每一层都对通道进行了翻倍,最多达到了512个通道。由于每个通道都代表着一个feature map,这样就使更多的信息可以被提取出来。
5. 将全连接层转换为卷积层
这个特征是体现在VGGNet的测试阶段。在进行网络测试时,将训练阶段的3个全连接层替换为3个卷积层,使测试得到的网络没有全连接的限制,能够接收任意宽和高的输入。如果后面3个层都是全连接层,那么在测试阶段就只能将测试的图像全部缩放到固定尺寸,这样就不便于多尺度测试工作的开展。
为什么这样替换之后就可以处理任意尺寸的输入图像了呢?因为1×1卷积一个很重要的作用就是调整通道数。如果下一层输入的特征图需要控制通道数为N,那么设置N个1×1卷积核就可以完成通道数的调整。比如最后需要1000个神经元用于分出1000个类别,那就在最后一层的前面使用1000个1×1的卷积核,这样的到的结果就是(1, 1, 1000)正好可以匹配。
有关1×1卷积的更多内容会在后续分析Inception结构的博客中介绍。
三、网络结构
1. 整体纵览
论文中一共提供了6种网络配置,层数从浅到深分别为11层、13层、16层和19层,上面表格里黑色加粗的部分就是该列相对于前一列增加的配置。虽然LRN在AlexNet中起到了作用,但是在VGG中并没有效果,并且该操作会增加内存和计算量,所以在更深的网络结构中,没有使用该操作。最后两列就分别对应了VGG16和VGG19,由于VGG16和VGG19的后三层(全连接层)完全一致,上面的结构图是针对VGG16,后文都以VGG16为例。VGGNet在替换了AlexNet的大卷积核的基础上,增加了新的卷积层,可以分为五个部分,如图中紫色序号①到⑤,VGG19仅仅是在③、④、⑤的部分增加了一个3×3的卷积层。
2. 卷积层
在卷积层中,为了便于计算,padding都是1。图像在输入进网络后的各个步骤在上图中已经很明了了,这里不做赘述(也可以直接去看第四部分的代码),下面是CS231课件中整个网络的全部参数的计算过程(不考虑偏置):
3. 全连接层
和AlexNet类似,VGGNet的最后三层都是全连接层,通过softmax层输出1000个预测结果。
四、实例演示
下面是VGG16结合批归一化方法的实现代码:
from torch import nn
import torchclass VGG16(nn.Module):def __init__(self, dim, num_classes):super().__init__()self.conv1 = nn.Sequential(nn.Conv2d(dim, 64, kernel_size=3, padding=1),nn.BatchNorm2d(64),nn.ReLU(True),nn.Conv2d(64, 64, kernel_size=3, padding=1),nn.BatchNorm2d(64),nn.ReLU(True),nn.MaxPool2d(2, 2))self.conv2 = nn.Sequential(nn.Conv2d(64, 128, kernel_size=3, padding=1),nn.BatchNorm2d(128),nn.ReLU(True),nn.Conv2d(128, 128, kernel_size=3, padding=1),nn.BatchNorm2d(128),nn.ReLU(True),nn.MaxPool2d(2, 2))self.conv3 = nn.Sequential(nn.Conv2d(128, 256, kernel_size=3, padding=1),nn.BatchNorm2d(256),nn.ReLU(True),nn.Conv2d(256, 256, kernel_size=3, padding=1),nn.BatchNorm2d(256),nn.ReLU(True),nn.Conv2d(256, 256, kernel_size=3, padding=1),nn.BatchNorm2d(256),nn.ReLU(True),nn.MaxPool2d(2, 2))self.conv4 = nn.Sequential(nn.Conv2d(256, 512, kernel_size=3, padding=1),nn.BatchNorm2d(512),nn.ReLU(True),nn.Conv2d(512, 512, kernel_size=3, padding=1),nn.BatchNorm2d(512),nn.ReLU(True),nn.Conv2d(512, 512, kernel_size=3, padding=1),nn.ReLU(True),nn.MaxPool2d(2, 2))self.conv5 = nn.Sequential(nn.Conv2d(512, 512, kernel_size=3, padding=1),nn.BatchNorm2d(512),nn.ReLU(True),nn.Conv2d(512, 512, kernel_size=3, padding=1),nn.BatchNorm2d(512),nn.ReLU(True),nn.Conv2d(512, 512, kernel_size=3, padding=1),nn.BatchNorm2d(512),nn.ReLU(True),nn.MaxPool2d(2, 2))self.fc = nn.Sequential(nn.Linear(7 * 7 * 512, 4096),nn.ReLU(True),nn.Dropout(),nn.Linear(4096, 4096),nn.ReLU(True),nn.Dropout(),nn.Linear(4096, num_classes))def forward(self, x):x = self.conv1(x)x = self.conv2(x)x = self.conv3(x)x = self.conv4(x)x = self.conv5(x)x = x.view(x.size(0), -1)output = self.fc(x)return output
可以把以下FlattenLayer加在全连接层容器最前面,来替换掉forward里的x.view,用下面的代码查看各层输出的尺寸:
class FlattenLayer(nn.Module):def __init__(self):super().__init__()def forward(self, x):return x.view(x.size(0), -1)net = VGG16(3, 1000)
X = torch.rand(1, 3, 224, 224)
for block in net.children():X = block(X)print('output shape: ', X.shape)
得到的输出结果如下:
output shape: torch.Size([1, 64, 112, 112])
output shape: torch.Size([1, 128, 56, 56])
output shape: torch.Size([1, 256, 28, 28])
output shape: torch.Size([1, 512, 14, 14])
output shape: torch.Size([1, 512, 7, 7])
output shape: torch.Size([1, 1000])
VGG的结构还是很简单的,和前面博客里的两个网络差别不大,只是深度更深了,从代码也可以看出来,所以这里只是简单记录一下。原论文中还有很多其他的细节,包括网络的测试等等,这里就不逐一细说了,毕竟只是过一下,感兴趣的话可以去读一读原论文:
Very Deep Convolutional Networks for Large-Scale Image Recognition
后面要讲解的GooLeNet会相对而言更巧妙一些~
目标检测入坑指南3:VGGNet神经网络相关推荐
- 一块GPU搞定ChatGPT;ML系统入坑指南;理解GPU底层架构
1. 跑ChatGPT体量模型,从此只需一块GPU 在发展技术,让大模型掌握更多能力的同时,也有人在尝试降低AI所需的算力资源.最近,一种名为FlexGen的技术因为「一块RTX 3090跑ChatG ...
- 增加检测类别?这是一份目标检测的基础指南
关注"迈微AI研习社",内容首发于公众号 来自丨机器之心 Adrian Rosebrock 目标检测技术作为计算机视觉的重要方向,被广泛应用于自动驾驶汽车.智能摄像头.人脸识别及 ...
- 搜索和CTR预估入坑指南
简介 搜索小白.CTR小白,整理了一份入坑指南,一些比较好的博客和论文.本文适用于有一定的机器学习和深度学习基础,但是不懂搜索和CTR的同学. 注:后续会不定时更新. 基础 主要是一些经典的语言模型( ...
- 信息安全之路入坑指南
作者:腾讯安全平台部研发安全团队 riusksk 疫情下的高考已结束,又快到填志愿的时候了,又有不少知青要加入信息安全这个圈子.为了响应组织号召,撰写此文作为信安行业的入坑指南,希望能对刚入圈的同学有 ...
- 开发工具篇第九讲:菜鸟入坑指南
摘要:本文是开发工具篇第九讲:菜鸟入坑指南.针对新人上手慢的问题,写了这篇入坑指南,方便自己回顾,总结.本文分为四个部分,分别为jenkins使用技巧:常用软件操作命令:开发手册:调试手册.主要材料来 ...
- 百度OCR(文字识别)服务使用入坑指南
百度OCR使用入坑指南 一.背景:什么是OCR 二.在线调用百度api接口 1. 注册百度智能云账号,创建应用获取key 2. 调用api发送请求,获取文字识别结果 2.1 构造请求 2.2 识别结果 ...
- 树莓派使用PCA9685扩展(二)之驱动无刷电机(调)入坑指南
摘要 在上一篇<树莓派使用PCA9685扩展PWM驱动舵机入坑指南>中简单介绍了树莓派使用PCA9685驱动sg90的180°舵机的应用.本身因为想做无人机,所以就研究了下如何驱动无刷电机 ...
- C语言入坑指南-缓冲区溢出
前言 缓冲区溢出通常指的是向缓冲区写入了超过缓冲区所能保存的最大数据量的数据.如果说之前所提到的一些问题可能只是影响部分功能的实现,那么缓冲区溢出将可能会造成程序运行终止,被不安全代码攻击等严重问题, ...
- 发布开源框架到CocoaPods入坑指南
个人原文博客地址: 发布开源框架到CocoaPods入坑指南 在开发过程中一定会用到一些第三方框架, 只要安装了CocoaPods, 然后通过pod install命令, 就可以集成框架到项目中了 可 ...
最新文章
- 文件名批量汉字转拼音+核磁共振影像数据处理
- 医学影像阅读/分析软件FSLeyes安装避坑+核磁共振影像数据处理
- AngularJS学习笔记之一: AngularJS入门
- .sql文件如何执行_Excel如何运行可执行文件,别急,用过vba Shell函数的都知道
- mysql orderby count_mysql中count(),groupby,orderby使用方法分享
- Unable to establish a connection to Redis Cluster at [RedisURI
- 【Java 基础】枚举、包装类、Math、Radnom、UUID、格式化、DecimalFormat、高精度计算(BigDecimal)
- Hadoop核心之HDFS 架构设计
- Vue.创建工程卡住
- 使用easy_install安装BeautifulSoup——Python
- 一、显示VOC2007数据集中的图像及标注信息
- 怎样抠图怎么把背景换成白色?几个步骤教你轻松掌握
- Oracle RAC集群安装,从零开始
- Zooming Slow-Mo: Fast and Accurate One-Stage Space-Time Video Super-Resolution | 摘要翻译 |
- shiro 使用md5密码加密 锁定账户
- devexpress gridcontrol gridview小结
- idea中import project是什么意思
- 基于iBeacon指纹的室内定位系统论文笔记
- Excel常用查找函数,vlookup、match+index/offset
- 02- 配置软件仓库