前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手撕 CNN 经典网络之 VGGNet(理论篇)

手撕 CNN 经典网络之 VGGNet(理论篇)

作者头像
红色石头
发布2022-04-14 08:07:22
8340
发布2022-04-14 08:07:22
举报

2014年,牛津大学计算机视觉组(Visual Geometry Group)和Google DeepMind公司一起研发了新的卷积神经网络,并命名为VGGNet。VGGNet是比AlexNet更深的深度卷积神经网络,该模型获得了2014年ILSVRC竞赛的第二名,第一名是GoogLeNet(我们之后会介绍)。

论文《Very Deep Convolutional Networks for Large-Scale Image Recognition》

论文传送门:https://arxiv.org/abs/1409.1556

1. 网络结构

VGG 的结构与 AlexNet 类似,区别是深度更深,但形式上更加简单。VGG由5层卷积层、3层全连接层、1层softmax输出层构成,层与层之间使用maxpool(最大化池)分开,所有隐藏层的激活单元都采用ReLU函数。作者在原论文中,根据卷积层不同的子层数量,设计了A、A-LRN、B、C、D、E这6种网络结构。

2c39549160dc0b18f4c55f047b0b374f.png
2c39549160dc0b18f4c55f047b0b374f.png

这6种网络结构相似,都是由5层卷积层、3层全连接层组成,区别在于每个卷积层的子层数量不同,从A至E依次增加,总的网络深度从11层到19层。表格中的卷积层参数表示为“conv(感受野大小)-通道数”,例如con3-64,表示使用3x3的卷积核,通道数为64;最大池化表示为maxpool,层与层之间使用maxpool分开;全连接层表示为“FC-神经元个数”,例如FC-4096表示包含4096个神经元的全连接层;最后是softmax层。

其中,D表示著名的VGG16,E表示著名的VGG19。下面以VGG16为例,来详细剖析一下VGG的网络结构。VGG16的结构如下图所示:

980a12e04d4628ba0ee6a813a4143db9.png
980a12e04d4628ba0ee6a813a4143db9.png

VGG16总共包含16个子层,第1层卷积层由2个conv3-64组成,第2层卷积层由2个conv3-128组成,第3层卷积层由3个conv3-256组成,第4层卷积层由3个conv3-512组成,第5层卷积层由3个conv3-512组成,然后是2个FC4096,1个FC1000。总共16层,这也就是VGG16名字的由来。

1.1 输入层

VGG输入图片的尺寸是224x224x3。

1.2 第1层卷积层

af6438d357757d750a74e7f5b82a1749.png
af6438d357757d750a74e7f5b82a1749.png

第1层卷积层由2个conv3-64组成。

该层的处理流程是:卷积-->ReLU--> 卷积-->ReLU-->池化。

卷积:输入是224x224x3,使用64个3x3x3的卷积核进行卷积,padding=1,stride=1,根据公式:

(input_size + 2 * padding - kernel_size) / stride + 1=(224+2*1-3)/1+1=224

得到输出是224x224x64。

ReLU:将卷积层输出的FeatureMap输入到ReLU函数中。

卷积:输入是224x224x64,使用64个3x3x64的卷积核进行卷积,padding=1,stride=1,根据公式:

(input_size + 2 * padding - kernel_size) / stride + 1=(224+2*1-3)/1+1=224

得到输出是224x224x64。

ReLU:将卷积层输出的FeatureMap输入到ReLU函数中。

池化:使用2x2,stride=2的池化单元进行最大池化操作(max pooling)。根据公式:

(224+2*0-2)/2+1=112

每组得到的输出为112x112x64。

1.3 第2层卷积层

64d4dabff9a724c5eff29de1b079f21a.png
64d4dabff9a724c5eff29de1b079f21a.png

第2层卷积层由2个conv3-128组成。

该层的处理流程是:卷积-->ReLU--> 卷积-->ReLU-->池化。

卷积:输入是112x112x64,使用128个3x3x64的卷积核进行卷积,padding=1,stride=1,根据公式:

(input_size + 2 * padding - kernel_size) / stride + 1=(112+2*1-3)/1+1=112

得到输出是112x112x128。

ReLU:将卷积层输出的FeatureMap输入到ReLU函数中。

卷积:输入是112x112x128,使用128个3x3x128的卷积核进行卷积,padding=1,stride=1,根据公式:

(input_size + 2 * padding - kernel_size) / stride + 1=(112+2*1-3)/1+1=112

得到输出是112x112x128。

ReLU:将卷积层输出的FeatureMap输入到ReLU函数中。

池化:使用2x2,stride=2的池化单元进行最大池化操作(max pooling)。根据公式:

(112+2*0-2)/2+1=56

每组得到的输出为56x56x128。

1.4 第3层卷积层

62467e01c29b5ffb5883fa0feb0ccc73.png
62467e01c29b5ffb5883fa0feb0ccc73.png

第3层卷积层由3个conv3-256组成。

该层的处理流程是:卷积-->ReLU--> 卷积-->ReLU-->池化。

卷积:输入是56x56x128,使用256个3x3x128的卷积核进行卷积,padding=1,stride=1,根据公式:

(input_size + 2 * padding - kernel_size) / stride + 1=(56+2*1-3)/1+1=56

得到输出是56x56x256。

ReLU:将卷积层输出的FeatureMap输入到ReLU函数中。

卷积:输入是56x56x256,使用256个3x3x256的卷积核进行卷积,padding=1,stride=1,根据公式:

(input_size + 2 * padding - kernel_size) / stride + 1=(56+2*1-3)/1+1=56

得到输出是56x56x256。

ReLU:将卷积层输出的FeatureMap输入到ReLU函数中。

池化:使用2x2,stride=2的池化单元进行最大池化操作(max pooling)。根据公式:

(56+2*0-2)/2+1=28

每组得到的输出为28x28x256。

1.5 第4层卷积层

b895734289015c1680f5f37055dec0d4.png
b895734289015c1680f5f37055dec0d4.png

第4层卷积层由3个conv3-512组成。

该层的处理流程是:卷积-->ReLU--> 卷积-->ReLU-->池化。

卷积:输入是28x28x256,使用512个3x3x256的卷积核进行卷积,padding=1,stride=1,根据公式:

(input_size + 2 * padding - kernel_size) / stride + 1=(28+2*1-3)/1+1=28

得到输出是28x28x512。

ReLU:将卷积层输出的FeatureMap输入到ReLU函数中。

卷积:输入是28x28x512,使用512个3x3x512的卷积核进行卷积,padding=1,stride=1,根据公式:

(input_size + 2 * padding - kernel_size) / stride + 1=(28+2*1-3)/1+1=28

得到输出是28x28x512。

ReLU:将卷积层输出的FeatureMap输入到ReLU函数中。

池化:使用2x2,stride=2的池化单元进行最大池化操作(max pooling)。根据公式:

(28+2*0-2)/2+1=14

每组得到的输出为14x14x512。

1.6 第5层卷积层

782938682c770c2e7439fff3448c3111.png
782938682c770c2e7439fff3448c3111.png

第5层卷积层由3个conv3-512组成。

该层的处理流程是:卷积-->ReLU--> 卷积-->ReLU-->池化。

卷积:输入是14x14x512,使用512个3x3x512的卷积核进行卷积,padding=1,stride=1,根据公式:

(input_size + 2 * padding - kernel_size) / stride + 1=(14+2*1-3)/1+1=14

得到输出是14x14x512。

ReLU:将卷积层输出的FeatureMap输入到ReLU函数中。

卷积:输入是14x14x512,使用512个3x3x512的卷积核进行卷积,padding=1,stride=1,根据公式:

(input_size + 2 * padding - kernel_size) / stride + 1=(14+2*1-3)/1+1=14

得到输出是14x14x512。

ReLU:将卷积层输出的FeatureMap输入到ReLU函数中。

池化:使用2x2,stride=2的池化单元进行最大池化操作(max pooling)。根据公式:

(14+2*0-2)/2+1=7

每组得到的输出为7x7x512。

1.7 第1层全连接层

a1e8d9784e1bff94598a073f9d280dc6.png
a1e8d9784e1bff94598a073f9d280dc6.png

第1层全连接层FC4096由4096个神经元组成。

该层的处理流程是:FC-->ReLU-->Dropout。

FC:输入是7x7x512的FeatureMap,展开为7*7*512的一维向量,即7*7*512个神经元,输出为4096个神经元。

ReLU:这4096个神经元的运算结果通过ReLU激活函数中。

Dropout:随机的断开全连接层某些神经元的连接,通过不激活某些神经元的方式防止过拟合。

1.8 第2层全连接层

9023aafdce834c6df627aa801f89b316.png
9023aafdce834c6df627aa801f89b316.png

第2层全连接层FC4096由4096个神经元组成。

该层的处理流程是:FC-->ReLU-->Dropout。

FC:输入是4096个神经元,输出为4096个神经元。

ReLU:这4096个神经元的运算结果通过ReLU激活函数中。

Dropout:随机的断开全连接层某些神经元的连接,通过不激活某些神经元的方式防止过拟合。

1.9 第3层全连接层

6d886dbf3cacd60885e442ba9bda0443.png
6d886dbf3cacd60885e442ba9bda0443.png

第3层全连接层FC1000由1000个神经元组成,对应ImageNet数据集的1000个类别。

该层的处理流程是:FC。

FC:输入是4096个神经元,输出为1000个神经元。

1.10 softmax层

1d03142eaaee493d2a0d6b7d49294d51.png
1d03142eaaee493d2a0d6b7d49294d51.png

该层的流程为:Softmax

Softmax:这1000个神经元的运算结果通过Softmax函数中,输出1000个类别对应的预测概率值。

2. 全卷积网络

接着对1.7、1.8、1.9节的内容进行介绍。这三节讲的是全连接网络,VGG16在训练的时候使用的是全连接网络。然而在测试验证阶段,网络结构稍有不同,作者将全连接全部替换为卷积网络。

先介绍做法!

2.1 第1层全连接层

输入为7x7x512的FeatureMap,使用4096个7x7x512的卷积核进行卷积,由于卷积核尺寸与输入的尺寸完全相同,即卷积核中的每个系数只与输入尺寸的一个像素值相乘一一对应,根据公式:

(input_size + 2 * padding - kernel_size) / stride + 1=(7+2*0-7)/1+1=1

得到输出是1x1x4096。相当于4096个神经元,但属于卷积层。

2.2 第2层全连接层

输入为1x1x4096的FeatureMap,使用4096个1x1x4096的卷积核进行卷积,由于卷积核尺寸与输入的尺寸完全相同,即卷积核中的每个系数只与输入尺寸的一个像素值相乘一一对应,根据公式:

(input_size + 2 * padding - kernel_size) / stride + 1=(1+2*0-1)/1+1=1

得到输出是1x1x4096。相当于4096个神经元,属于卷积层。

2.3 第2层全连接层

输入为1x1x4096的FeatureMap,使用1000个1x1x4096的卷积核进行卷积,由于卷积核尺寸与输入的尺寸完全相同,即卷积核中的每个系数只与输入尺寸的一个像素值相乘一一对应,根据公式:

(input_size + 2 * padding - kernel_size) / stride + 1=(1+2*0-1)/1+1=1

得到输出是1x1x1000。相当于1000个神经元,属于卷积层。

得到1x1x1000的输出之后,最后经过softmax层进行预测类别。

2.4 为什么要将全连接层转变为全卷积层?

作者将三个全连接层转成了1个7×7,和 2 个 1×1 的卷积层。从下图可以看到,以第一个全连接层为例,要转卷积层,FC6的输入是 7×7×512,输出是4096(也可以看做 1×1×4096),那么就要对输入在尺寸上(宽高)降维(从7×7 降到 1×1)和深度(channel 或者 depth)升维(从512 升到4096)。把7×7降到1×1,使用大小为 7×7的卷积核就好了,卷积核个数设置为4096,即卷积核为7×7×4096(下图中的[7×7×512]×4096 表示有 4096 个 [7×7×512] 这样的卷积核,7×7×4096 是简写形式忽略了输入的深度),经过对输入卷积就得到了最终的 1×1×4096 大小的 feature map。

2d8d65fc70f876d0154dc74341372ccb.png
2d8d65fc70f876d0154dc74341372ccb.png

为什么要在模型测试的时候将全连接层转变为全卷积层呢?最直接的原因是让网络模型可以接受任意大小的尺寸。

我们在前面介绍的时候限定了网络输入图片的尺寸是224x224x3。如果后面三个层都是全连接,遇到宽高大于224的图片就需要进行图片的剪裁、缩放或其它处理,使图片尺寸统一到224x224x3,才能符合后面全连接层的输入要求。但是,我们并不能保证每次裁剪都能将图片中的关键目标保留下来,可能裁剪去的部分恰好包含了目标,造成裁减丢失关键目标信息,影响模型的测试精度。

(输出是一个分类得分图,通道的数量和类别的数量相同,空间分辨率依赖于输入图像尺寸。最终为了得到固定尺寸的分类得分向量,将分类得分图进行空间平均化(求和——池化)。我们同样使用水平翻转来对测试集进行数据增强;在原始图像和翻转图像上的soft-max分类概率的平均值作为这幅图像的最终得分。)

使用全卷积层,即使图片尺寸大于224x224x3,最终经过softmax层得到的得分图就不是1x1x1000,例如是2x2x1000,这里的通道1000与类别的数量相同,空间分辨率2x2依赖于输入图像尺寸。然后将得分图进行空间平均化(求和池化),得到的还是1x1x1000。最后对1000个通道的得分进行比较,取较大值作为预测类别。

这样做的好处就是大大减少特征位置对分类带来的影响。

举个简单的例子:

2f98b0999eecb7c852abeb3e6af92c3b.png
2f98b0999eecb7c852abeb3e6af92c3b.png

从上图我们可以看出,猫在原图片中不同的位置,如果使用全连接层很容易使得剪裁之后的图片丢失关键目标。然而使用全卷积层,对原图片直接进行卷积,最终得分图经过求和池化后得到的得分都是1,即不管猫在图片的什么位置,都能判定这张图片中有猫,保证分类正确。保留原图,使用全卷积层,相当于猫在哪我不管,我只要猫,于是我让模型去把这个猫找到,实际就是把feature map整合成一个值,这个值大,就有猫,这个值小,那就可能没猫!和这个猫在图片哪里关系不大了,鲁棒性大大增强。

3. VGG网络特点

3.1 结构简洁

虽然VGG层数较多,总的网络深度从11层到19层,但是它的整体结构还是相对简单。概括来说,VGG由5层卷积层(每个卷积层的子层数量不同)、3层全连接层、softmax输出层构成,层与层之间使用maxpooling(最大化池)分开,所有隐层的激活单元都采用ReLU函数。

3.2 小卷积核

小卷积核是VGG的一个重要特点,VGG没有采用AlexNet中比较大的卷积核尺寸(如7x7),而是通过降低卷积核的大小(3x3),增加卷积子层数来达到同样的性能(VGG:从1到4卷积子层,AlexNet:1子层)。

VGG使用多个较小卷积核(3x3)的卷积层代替一个卷积核较大的卷积层,VGG作者认为两个3x3的卷积堆叠获得的感受野大小,相当一个5x5的卷积;而3个3x3卷积的堆叠获取到的感受野相当于一个7x7的卷积。示意图如下所示:

a6c031e182059ca705daf6d6049d56a1.png
a6c031e182059ca705daf6d6049d56a1.png

使用3x3小卷积核的好处有两个方面:

一是大幅度减少模型参数数量。例如使用2个3x3的卷积核代替1个5x5的卷积核,通道数为C,1个5x5的卷积核参数量为5*5*C,2个3x3的卷积核参数量为2*3*3*C,参数两减小了28%。另外,小卷积核选取小的 stride可以防止较大的stride导致细节信息的丢失。

二是多层卷积层(每个卷积层后都有非线性激活函数),增加非线性,提升模型性能。

此外,我们注意到在VGG网络结构D中,还使用了1x1卷积核,1x1卷积核可以在不改变感受野的情况下,增加模型的非线性(后面的非线性激活函数)。同时,还可以用它来整合各通道的信息,并输出指定通道数。通道数减小即降维,通道数增加即升维。

3.3 小池化核

相比AlexNet的3x3的池化核,VGG全部采用2x2的池化核。

3.4 通道数更多,特征度更宽

每个通道代表着一个FeatureMap,更多的通道数表示更丰富的图像特征。VGG网络第一层的通道数为64,后面每层都进行了翻倍,最多到512个通道,通道数的增加,使得更多的信息可以被提取出来。

3.5 层数更深

使用连续的3x3小卷积核代替大的卷积核,网络的深度更深,并且对边缘进行填充,卷积的过程并不会减小图像尺寸。仅使用小的2x2池化单元,减小图像的尺寸。

3.6 全连接转卷积

这部分内容在全卷积网络已经介绍过了。

3.7 模型参数

A、A-LRN、B、C、D、E这6种网络结构的深度虽然从11层增加至19层,但参数量变化不大,这是由于基本上都是采用了小卷积核,参数主要集中在全连接层。

8e6fb5f02c7d31a3c2740418a194e6b2.png
8e6fb5f02c7d31a3c2740418a194e6b2.png

3.8 其他

A-LRN网络结构使用了LRN层(local response normalization,局部响应归一化),这在AlexNet网络中也使用过。但是作者实验发现使用LRN并没有带来性能的提升,因此在其它组的网络中均没再出现LRN层。

从11层的A到19层的E,网络深度增加对top1和top5的错误率下降很明显。

VGG作者用B网络和一个较浅网络比较,较浅网络用1个5x5卷积核来代替B的2个3x3卷积核,结果显示多个小卷积核比单个大卷积核效果要好。

关于VGG的更多细节和实验对比结果,建议大家直接看原论文!

手撕 CNN 系列:

手撕 CNN 经典网络之 LeNet-5(理论篇)

手撕 CNN 经典网络之 LeNet-5(MNIST 实战篇)

手撕 CNN 经典网络之 LeNet-5(CIFAR10 实战篇)

手撕 CNN 经典网络之 LeNet-5(自定义实战篇)

手撕 CNN 经典网络之 AlexNet(理论篇)

手撕 CNN 经典网络之 AlexNet(PyTorch 实战篇)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-02-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 网络结构
  • 2. 全卷积网络
  • 3. VGG网络特点
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档