1. 概述
VGG[1]是Oxford的Visual Geometry Group的组提出的,VGG的缩写也来自于这个组的名字。VGG网络探索了提升网络的深度对最终的图像识别准确率的重要性,同时在VGG中尝试使用小的卷积核来构建深层的卷积网络。VGG在当年的ILSVRC 2014上取得了第一的成绩,证明了增加网络的深度能够在一定程度上提高网络的性能。
2. 算法的基本思想
2.1. VGG的原理
在VGG网络中,有两种结构,分别是VGG16和VGG19,两者只是网络深度不一样。以VGG16为例,在VGG16中,相比于AlexNet,其最大的改进是采用几个
3
×
3
3\times 3
3×3的卷积核代替了AlexNet中的较大的卷积核,主要是
11
×
11
11\times 11
11×11,
5
×
5
5\times 5
5×5。相比于大的卷积核,采用多个较小卷积核的堆叠,一方面能通过多层的非线性特性增强模型的学习能力(卷积+ReLU为一个组合),同时能进一步减少模型的参数。
以
5
×
5
5\times 5
5×5的卷积核为例,可通过堆叠两个
3
×
3
3\times3
3×3的卷积核实现
5
×
5
5\times5
5×5的卷积效果,具体过程如下图所示:
5
×
5
5\times5
5×5卷积核的参数个数为
25
+
1
25+1
25+1个,与
5
×
5
5\times5
5×5的卷积核相比,堆叠两个
3
×
3
3\times3
3×3的参数个数为
9
+
1
+
9
+
1
9+1+9+1
9+1+9+1,在实现了同样的功能的情况下能够减少参数的个数。
2.2. VGG的网络结构
VGG网络的结构的具体参数如下图所示:
由上图可以看出,VGG16和VGG19只是在层数上不一样,VGG16中包含了16个隐藏层,包括13个卷积层和3个全连接层,如上图中的D列所示,VGG19中包含了19个隐藏层,包括16个卷积层和3个全连接层,如上图中的E列所示。
以VGG16为例,参照[2]的参数格式,可以绘制出如下的网络结构:
从上述的网络结构中可以看出,在VGG网络中只包含了卷积+ReLU,pooling,全连接,dropout操作模块,摒弃了在AlexNet中使用的LRN归一化模块,并在实验中验证LRN对于最终效果的影响较小。VGG的整个网络结构相对比较简单,但就是这样简单的网络结构却能提升整体的识别效果,这得益于较深的网络结构。在上述的结构中:
- data:大小为
224
×
224
×
3
224\times 224\times 3
224×224×3
- 第一组卷积(包括conv1_1,relu1_1,conv1_2,relu1_2,pool1)
- conv1_1:输入(
224
×
224
×
3
224\times 224\times 3
224×224×3),输出:(
224
×
224
×
64
224\times 224\times 64
224×224×64,其中,卷积核大小为
3
×
3
3\times3
3×3,padding为
1
1
1,步长S为
1
1
1,卷积核的个数为
64
64
64)
- relu1_1:输入(
224
×
224
×
64
224\times 224\times 64
224×224×64),输出(
224
×
224
×
64
224\times 224\times 64
224×224×64)
- conv1_2:输入(
224
×
224
×
64
224\times 224\times 64
224×224×64),输出:(
224
×
224
×
64
224\times 224\times 64
224×224×64,其中,卷积核大小为
3
×
3
3\times3
3×3,padding为
1
1
1,步长S为
1
1
1,卷积核的个数为
64
64
64)
- relu1_2:输入(
224
×
224
×
64
224\times 224\times 64
224×224×64),输出(
224
×
224
×
64
224\times 224\times 64
224×224×64)
- pool1:输入(
224
×
224
×
64
224\times 224\times 64
224×224×64),输出(
112
×
112
×
64
112\times 112\times 64
112×112×64,其中,核的大小为
2
×
2
2\times2
2×2,步长S为
2
2
2)
- 第二组卷积(包括conv2_1,relu2_1,conv2_2,relu2_2,pool2)
- conv2_1:输入(
112
×
112
×
64
112\times 112\times 64
112×112×64),输出:(
112
×
112
×
128
112\times 112\times 128
112×112×128,其中,卷积核大小为
3
×
3
3\times3
3×3,padding为
1
1
1,步长S为
1
1
1,卷积核的个数为
128
128
128)
- relu2_1:输入(
112
×
112
×
128
112\times 112\times 128
112×112×128),输出(
112
×
112
×
128
112\times 112\times 128
112×112×128)
- conv2_2:输入(
112
×
112
×
128
112\times 112\times 128
112×112×128),输出:(
112
×
112
×
128
112\times 112\times 128
112×112×128,其中,卷积核大小为
3
×
3
3\times3
3×3,padding为
1
1
1,步长S为
1
1
1,卷积核的个数为
128
128
128)
- relu2_2:输入(
112
×
112
×
128
112\times 112\times 128
112×112×128),输出(
112
×
112
×
128
112\times 112\times 128
112×112×128)
- pool2:输入(
112
×
112
×
128
112\times 112\times 128
112×112×128),输出(
56
×
56
×
128
56\times 56\times 128
56×56×128,其中,核的大小为
2
×
2
2\times2
2×2,步长S为
2
2
2)
- 第三组卷积(包括conv3_1,relu3_1,conv3_2,relu3_2,conv3_3,relu3_3,pool3)
- conv3_1:输入(
56
×
56
×
128
56\times 56\times 128
56×56×128),输出:(
56
×
56
×
256
56\times 56\times 256
56×56×256,其中,卷积核大小为
3
×
3
3\times3
3×3,padding为
1
1
1,步长S为
1
1
1,卷积核的个数为
256
256
256)
- relu3_1:输入(
56
×
56
×
256
56\times 56\times 256
56×56×256),输出(
56
×
56
×
256
56\times 56\times 256
56×56×256)
- conv3_2:输入(
56
×
56
×
256
56\times 56\times 256
56×56×256),输出:(
56
×
56
×
256
56\times 56\times 256
56×56×256,其中,卷积核大小为
3
×
3
3\times3
3×3,padding为
1
1
1,步长S为
1
1
1,卷积核的个数为
256
256
256)
- relu3_2:输入(
56
×
56
×
256
56\times 56\times 256
56×56×256),输出(
56
×
56
×
256
56\times 56\times 256
56×56×256)
- conv3_3:输入(
56
×
56
×
256
56\times 56\times 256
56×56×256),输出:(
56
×
56
×
256
56\times 56\times 256
56×56×256,其中,卷积核大小为
3
×
3
3\times3
3×3,padding为
1
1
1,步长S为
1
1
1,卷积核的个数为
256
256
256)
- relu3_3:输入(
56
×
56
×
256
56\times 56\times 256
56×56×256),输出(
56
×
56
×
256
56\times 56\times 256
56×56×256)
- pool3:输入(
56
×
56
×
256
56\times 56\times 256
56×56×256),输出(
28
×
28
×
256
28\times 28\times 256
28×28×256,其中,核的大小为
2
×
2
2\times2
2×2,步长S为
2
2
2)
- 第四组卷积(包括conv4_1,relu4_1,conv4_2,relu4_2,conv4_3,relu4_3,pool4)
- conv4_1:输入(
28
×
28
×
256
28\times 28\times 256
28×28×256),输出:(
28
×
28
×
512
28\times 28\times 512
28×28×512,其中,卷积核大小为
3
×
3
3\times3
3×3,padding为
1
1
1,步长S为
1
1
1,卷积核的个数为
512
512
512)
- relu4_1:输入(
28
×
28
×
512
28\times 28\times 512
28×28×512),输出(
28
×
28
×
512
28\times 28\times 512
28×28×512)
- conv4_2:输入(
28
×
28
×
512
28\times 28\times 512
28×28×512),输出:(
28
×
28
×
512
28\times 28\times 512
28×28×512,其中,卷积核大小为
3
×
3
3\times3
3×3,padding为
1
1
1,步长S为
1
1
1,卷积核的个数为
512
512
512)
- relu4_2:输入(
28
×
28
×
512
28\times 28\times 512
28×28×512),输出(
28
×
28
×
512
28\times 28\times 512
28×28×512)
- conv4_3:输入(
28
×
28
×
512
28\times 28\times 512
28×28×512),输出:(
28
×
28
×
512
28\times 28\times 512
28×28×512,其中,卷积核大小为
3
×
3
3\times3
3×3,padding为
1
1
1,步长S为
1
1
1,卷积核的个数为
512
512
512)
- relu4_3:输入(
28
×
28
×
512
28\times 28\times 512
28×28×512),输出(
28
×
28
×
512
28\times 28\times 512
28×28×512)
- pool4:输入(
28
×
28
×
512
28\times 28\times 512
28×28×512),输出(
14
×
14
×
512
14\times 14\times 512
14×14×512,其中,核的大小为
2
×
2
2\times2
2×2,步长S为
2
2
2)
- 第五组卷积(包括conv5_1,relu5_1,conv5_2,relu5_2,conv5_3,relu5_3,pool3)
- conv5_1:输入(
14
×
14
×
512
14\times 14\times 512
14×14×512),输出:(
14
×
14
×
512
14\times 14\times 512
14×14×512,其中,卷积核大小为
3
×
3
3\times3
3×3,padding为
1
1
1,步长S为
1
1
1,卷积核的个数为
512
512
512)
- relu5_1:输入(
14
×
14
×
512
14\times 14\times 512
14×14×512),输出(
14
×
14
×
512
14\times 14\times 512
14×14×512)
- conv5_2:输入(
14
×
14
×
512
14\times 14\times 512
14×14×512),输出:(
14
×
14
×
512
14\times 14\times 512
14×14×512,其中,卷积核大小为
3
×
3
3\times3
3×3,padding为
1
1
1,步长S为
1
1
1,卷积核的个数为
512
512
512)
- relu5_2:输入(
14
×
14
×
512
14\times 14\times 512
14×14×512),输出(
14
×
14
×
512
14\times 14\times 512
14×14×512)
- conv5_3:输入(
14
×
14
×
512
14\times 14\times 512
14×14×512),输出:(
14
×
14
×
512
14\times 14\times 512
14×14×512,其中,卷积核大小为
3
×
3
3\times3
3×3,padding为
1
1
1,步长S为
1
1
1,卷积核的个数为
512
512
512)
- relu5_3:输入(
14
×
14
×
512
14\times 14\times 512
14×14×512),输出(
14
×
14
×
512
14\times 14\times 512
14×14×512)
- pool5:输入(
14
×
14
×
512
14\times 14\times 512
14×14×512),输出(
7
×
7
×
512
7\times 7\times 512
7×7×512,其中,核的大小为
2
×
2
2\times2
2×2,步长S为
2
2
2)
- 第一组全连接(包括fc6,relu6,drop6)
- fc6:输入(
7
×
7
×
512
7\times 7\times 512
7×7×512,通过flatting,得到
25088
25088
25088),输出(
4096
4096
4096)
- relu6:输入(
4096
4096
4096),输出(
4096
4096
4096)
- drop6:输入(
4096
4096
4096),输出(
4096
4096
4096)
- 第二组全连接(包括fc7,relu7,drop7)
- fc7:输入(
4096
4096
4096),输出(
4096
4096
4096)
- relu7:输入(
4096
4096
4096),输出(
4096
4096
4096)
- drop7:输入(
4096
4096
4096),输出(
4096
4096
4096)
- 第三组全连接(包括fc8):输入(
4096
4096
4096),输出(
1000
1000
1000)
3. 总结
VGG网络结构相对比较简洁,整个网络结构中只用到了
3
×
3
3\times3
3×3的卷积核和
2
×
2
2\times2
2×2的最大池化,通过堆叠小的卷积核实现较大卷积的操作,通过这样的方式加深了网络的结构,但是在网络中还是出现计算量较大的情况,主要是出现在最后的几组全连接层,其中第一个全连接fc6的参数为
25088
×
4096
+
4096
=
102764544
25088\times4096+4096=102764544
25088×4096+4096=102764544。
参考文献
[1] Simonyan K, Zisserman A. Very deep convolutional networks for large-scale image recognition[J]. arXiv preprint arXiv:1409.1556, 2014.
[2] https://dgschwend.github.io/netscope/#/preset/vgg-16
[3] 一文读懂VGG网络
[4] VGG in TensorFlow
|