/* 版权声明:可以任意转载,转载时请务必标明文章原始出处和作者信息 .*/
faiculty: 机器学习、计算机视觉、语音识别算法学习笔记
微信公众号、知乎专栏、简书,请搜索: faiculty
1. 前言
VGG是牛津大学计算机视觉组(Visual Geometry Group)和Google DeepMind公司研究员一起研发的深度卷积神经网络。
VGGNet 探索了卷积神经网络的深度与其性能之间的关系,通过反复堆叠3x3的小型卷积核和2x2的最大池化层,VGGNet 成功地构筑了16~19层深的卷积神经网络。VGGNet 相比之前 state-of-the-art 的网络结构,错误率大幅下降,并取得了 ILSVRC 2014 比赛分类项目的第2名和定位项目的第1名。
同时 VGGNet 的拓展性很强,迁移到其他图片数据上的泛化性非常好。VGGNet 的结构非常简洁,整个网络都使用了同样大小的卷积核尺寸(3x3)和最大池化尺寸(2x2)。到目前为止,VGGNet 依然经常被用来提取图像特征(!!!)。VGGNet 训练后的模型参数在其官方网站上开源了,可用来在 domain specific 的图像分类任务上进行再训练(相当于提供了非常好的初始化权重),因此被用在了很多地方。
2. 网络结构
下图就是VGG-net家族的网络结构图。
2.1 结构解读
==基本参数==:
- 一共有A、A-LRN、B、C、D、E,6个网络。其中的D、E也就是我们常说的VGGNet-16、VGGNet-19
- conv(receptive field size) - (number of channels)
- 论文中全部使用了3x3的卷积核 和 2x2的池化核,卷积步长为1
- 都采用Relu作为激活函数
==卷积核采用3x3 ?==
VGGNet 拥有5段卷积,每一段内有2~3个卷积层,同时每段尾部会连接一个最大池化层用来缩小图片尺寸。每段内的卷积核数量一样,越靠后的段的卷积核数量越多:64 – 128 – 256 – 512 – 512。其中经常出现多个完全一样的3x3的卷积层堆叠在一起的情况,这其实是非常有用的设计。如下图所示,两个3x3的卷积层串联相当于1个5x5的卷积层,即一个像素会跟周围5x5的像素产生关联,可以说感受野大小为5x5。而3个3x3的卷积层串联的效果则相当于1个7x7的卷积层。除此之外,3个串联的3x3的卷积层,拥有比1个7x7的卷积层更少的参数量,只有后者的一半。最重要的是,3个3x3的卷积层拥有比1个7x7的卷积层更多的非线性变换(前者可以使用三次 ReLU 激活函数,而后者只有一次),使得 CNN 对特征的学习能力更强。
[图片上传失败...(image-904a64-1515727838537)]
==C中采用了1x1的卷积核?==
我想是用来做对比试验,1x1的卷积核可以在没有改变、影响卷积感受野的情况下增加线性变换次数,而保持输入通道数和输出通道数不变,没有发生降维。
2.2 训练
文章中将224x224作为网络的training scale
1. 小批梯度下降方法
论文中的原话为: the training is carried out by optimising the multinormial logistic regression objective using mini-batch gradient descent(based on bp) with momentum.
翻译: 使用加动量的随机梯度下降方法来优化Logistic回归(SGD+momentum)
- 动量: 0.9
- 批数: 256
- 权值衰减:5x10^-4,(weight decay)
- 前两个全连接层使用dropout为: keep_prob = 0.5
- 学习速率为: 0.01,当验证集准确度停止提升的时候以10倍速度衰减
2. 权重初始化
训练A网络:
- W: 服从(0, 0,01)的高斯分布
- Bias: 0
后续:
把A的前4个卷积层和最后的全连接层的权值当做其它网络的初始值,未赋值的中间层随机初始化。
3. Multi-Scale
在训练中,VGG使用了Multi-Scale的方法做数据增强,将原始的图像缩放到不同尺寸S,然后在随机裁切224x224的图片,这样可以增加很多数据量,对于防止过拟合有很不错的效果。
初始对原始图片进行裁剪时,原始图片的最小边不宜过小,这样的话,裁剪到224x224的时候,就相当于几乎覆盖了整个图片,这样对原始图片进行不同的随机裁剪得到的图片就基本上没差别,就失去了增加数据集的意义,但同时也不宜过大,这样的话,裁剪到的图片只含有目标的一小部分,也不是很好。
针对上述问题,文章提出了两种方法:
- 固定尺寸为S=256 和 S=384, 训练后取均值
- multi-scale training,训练数据随机从[256, 512]的确定范围进行抽样,这样原始图片尺寸不同,有利于训练。
==训练数据尺寸不同,如何训练?最简单的是直接Resize==
2.3 测试
给出一个训练后的网络模型 和 一张图像,进行预测。测试的时候,图片的尺寸不一定要与训练图片的尺寸相同,而且不需要裁剪。
首先将全连接层转换到卷积层,==第一个全连接层转换到一个7x7的卷积层,后面两个转换到1x1的卷积层==,这不仅仅让全连接层应用到整个未裁剪的原始图像上,而且能得到一个类别的得分图(class score map),它的通道数等于类别数,还有一个取决于图片尺寸的可变空间分辨率(variable spatial resolution)。具体的操作如下所示:
文章中训练输入图像尺寸均为224x224,这样网络的参数就已经固定了。图像尺寸只会与pool层相关,经过5层pool层后,最后输出为7x7x512的尺寸。现在我们假设有一张测试图像的尺寸为256x256,这样经过卷积、池化后,最后输出的为8x8x512,这个时候最后三个全连接层是怎样工作的呢?
# ImgIn shape: (?, 8, 8, 512)
# FC1 参数个数: 7x7x512x4096, 训练结果,参数已经固定
# 将FC1 转换为 卷积层, 卷积核大小7x7x512,通道数4096,步长为1
conv: -> (?, 8, 8, 4096), kernel_size=(7,7,512,4096), stride=1
# ImgIn shape: (?, 8, 8, 4096)
# FC2 参数个数:4096x4096,也是训练结果,已经固定的
# 将FC2 转换为 卷积层, 卷积核大小1x1x4096, 通道数4096, 步长1
conv: -> (?, 8, 8, 4096), kernel_size(1,1,4096,4096), stride=1
# ImgIn shape: (?, 8, 8, 4096)
# FC3 参数个数:4096x1000,也是训练结果,已经固定的
# 将FC2 转换为 卷积层, 卷积核大小1x1x4096, 通道数1000, 步长1
conv: -> (?, 8, 8, 1000), kernel_size(1,1,4096,1000), stride=1
由此就得到了一个class score map, 然后取均值即可。
测试数据尺寸不同,如何测试?
3. 分类实验
3.1 单尺度评估
[图片上传失败...(image-80f29d-1515727838537)]
得到如下结论:
- LRN并不能改善A网络性能
- 分类误差随着深度增加而降低
- 在训练的时候采用图像尺度抖动(Scale Jittering)可以改善图像分类效果
3.2 多尺度评估
[图片上传失败...(image-d87b7c-1515727838537)]
- 相对于单一尺度评估,多尺度评估提高了分类精度
- 在训练的时候采用图像尺度抖动(Scale Jittering)可以改善图像分类效果
3.3 多裁剪评估
[图片上传失败...(image-dfcf87-1515727838537)]
多裁剪(multi-crop)评估比起密集(dense)评估,效果更好。而且两者具有互补作用,结合两种方式,效果更好。
3.4 卷积网络融合
[图片上传失败...(image-4b2cc6-1515727838537)]
如果结合多个卷积网络的softmax输出,分类结果会更好。