您的位置:首页 > 理论基础 > 计算机网络

Deep Learning-TensorFlow (11) CNN卷积神经网络_解读 VGGNet

2017-04-13 16:27 369 查看
环境:Win8.1 TensorFlow1.0.1

软件:Anaconda3 (集成Python3及开发环境)

TensorFlow安装:pip install tensorflow (CPU版) pip install tensorflow-gpu (GPU版)

TFLearn安装:pip install tflearn

参考:

1. Very Deep Convolutional Networks for Large-Scale Image Recognition

2. Github: tflearn

3. 独家 |《TensorFlow实战》作者黄文坚:四大经典CNN网络技术原理

1. 前言

VGGNet 是牛津大学计算机视觉组(Visual Geometry Group)和
Google DeepMind
公司的研究员一起研发的的深度卷积神经网络,在 ILSVRC 2014 上取得了第二名的成绩,将 Top-5错误率降到7.3%

VGGNet 探索了卷积神经网络的深度与其性能之间的关系,通过反复堆叠3´3的小型卷积核和2´2的最大池化层,VGGNet 成功地构筑了16~19层深的卷积神经网络。VGGNet 相比之前 state-of-the-art 的网络结构,错误率大幅下降,并取得了 ILSVRC 2014 比赛分类项目的第2名和定位项目的第1名。

同时 VGGNet 的拓展性很强,迁移到其他图片数据上的泛化性非常好。VGGNet 的结构非常简洁,整个网络都使用了同样大小的卷积核尺寸(3´3)和最大池化尺寸(2´2)。到目前为止,VGGNet 依然经常被用来提取图像特征(!!!)。VGGNet 训练后的模型参数在其官方网站上开源了,可用来在 domain specific 的图像分类任务上进行再训练(相当于提供了非常好的初始化权重),因此被用在了很多地方。

2. 网络结构

VGGNet 论文中全部使用了3´3的卷积核和2´2的池化核,通过不断加深网络结构来提升性能。下图所示为 VGGNet 各级别的网络结构图,以及随后的每一级别的参数量,从11层的网络一直到19层的网络都有详尽的性能测试。虽然从A到E每一级网络逐渐变深,但是网络的参数量并没有增长很多,这是因为参数量主要都消耗在最后3个全连接层。前面的卷积部分虽然很深,但是消耗的参数量不大,不过训练比较耗时的部分依然是卷积,因其计算量比较大。这其中的D、E也就是我们常说的 VGGNet-16 和 VGGNet-19。C相比B多了几个1´1的卷积层,1´1卷积的意义主要在于线性变换,而输入通道数和输出通道数不变,没有发生降维



VGGNet 拥有5段卷积,每一段内有2~3个卷积层,同时每段尾部会连接一个最大池化层用来缩小图片尺寸。每段内的卷积核数量一样,越靠后的段的卷积核数量越多:64 – 128 – 256 – 512 – 512。其中经常出现多个完全一样的3´3的卷积层堆叠在一起的情况,这其实是非常有用的设计。如下图所示,两个3´3的卷积层串联相当于1个5´5的卷积层,即一个像素会跟周围5´5的像素产生关联,可以说感受野大小为5´5。而3个3´3的卷积层串联的效果则相当于1个7´7的卷积层。除此之外,3个串联的3´3的卷积层,拥有比1个7´7的卷积层更少的参数量,只有后者的一半。最重要的是,3个3´3的卷积层拥有比1个7´7的卷积层更多的非线性变换(前者可以使用三次
ReLU 激活函数,而后者只有一次),使得 CNN 对特征的学习能力更强。




两个串联3´3的卷积层功能类似于一个5´5的卷积层

VGGNet 在训练时有一个小技巧,先训练级别A的简单网络,再复用A网络的权重来初始化后面的几个复杂模型,这样训练收敛的速度更快。在预测时,VGG 采用 Multi-Scale 的方法,将图像 scale 到一个尺寸 Q,并将图片输入卷积网络计算。然后在最后一个卷积层使用滑窗的方式进行分类预测,将不同窗口的分类结果平均,再将不同尺寸 Q的结果平均得到最后结果,这样可提高图片数据的利用率并提升预测准确率。同时在训练中,VGGNet
还使用了 Multi-Scale 的方法做数据增强
,将原始图像缩放到不同尺寸 S,然后再随机裁切224´224的图片,这样能增加很多数据量,对于防止模型过拟合有很不错的效果。实践中,作者令 S 在[256,512]这个区间内取值,使用 Multi-Scale 获得多个版本的数据,并将多个版本的数据合在一起进行训练。

总结:

在 AlexNet 基础上将单层网络替换为堆叠的3´3的卷积层和2´2的最大池化层,减少卷积层参数,同时加深网络结构提高性能;
采用 Pre-trained 方法利用浅层网络(A)训练参数初始化深层网络参数(D,E),加速收敛;
采用 Multi-Scale 方法进行数据增强、训练、测试,提高准确率;
去掉了 LRN,减少了内存的小消耗和计算时间。

问题:

虽然 VGGNet 减少了卷积层参数,但实际上其参数空间比 AlexNet 大,其中绝大多数的参数都是来自于第一个全连接层,耗费更多计算资源。在随后的
NIN
中发现将这些全连接层替换为全局平均池化,对于性能影响不大,同时显著降低了参数数量。
采用 Pre-trained 方法训练的 VGG model(主要是 D 和 E),相对其他的方法参数空间很大,所以训练一个 VGG 模型通常要花费更长的时间,所幸有公开的 Pre-trained model 让我们很方便的使用。

3. 实例

在 tflearn/examples/images/ 下有使用 TFLearn 搭建的
VGGNet,完成 Oxford 17 类鲜花 数据集分类任务。其结构定义:

# -*- coding: utf-8 -*-

""" Very Deep Convolutional Networks for Large-Scale Visual Recognition.

Applying VGG 16-layers convolutional network to Oxford's 17 Category Flower
Dataset classification task.

References:
Very Deep Convolutional Networks for Large-Scale Image Recognition.
K. Simonyan, A. Zisserman. arXiv technical report, 2014.

Links: http://arxiv.org/pdf/1409.1556 
"""

from __future__ import division, print_function, absolute_import

import tflearn
from tflearn.layers.core import input_data, dropout, fully_connected
from tflearn.layers.conv import conv_2d, max_pool_2d
from tflearn.layers.estimator import regression

# Data loading and preprocessing
import tflearn.datasets.oxflower17 as oxflower17
X, Y = oxflower17.load_data(one_hot=True)

# Building 'VGG Network'
network = input_data(shape=[None, 224, 224, 3])

network = conv_2d(network, 64, 3, activation='relu')
network = conv_2d(network, 64, 3, activation='relu')
network = max_pool_2d(network, 2, strides=2)

network = conv_2d(network, 128, 3, activation='relu')
network = conv_2d(network, 128, 3, activation='relu')
network = max_pool_2d(network, 2, strides=2)

network = conv_2d(network, 256, 3, activation='relu')
network = conv_2d(network, 256, 3, activation='relu')
network = conv_2d(network, 256, 3, activation='relu')
network = max_pool_2d(network, 2, strides=2)

network = conv_2d(network, 512, 3, activation='relu')
network = conv_2d(network, 512, 3, activation='relu')
network = conv_2d(network, 512, 3, activation='relu')
network = max_pool_2d(network, 2, strides=2)

network = conv_2d(network, 512, 3, activation='relu')
network = conv_2d(network, 512, 3, activation='relu')
network = conv_2d(network, 512, 3, activation='relu')
network = max_pool_2d(network, 2, strides=2)

network = fully_connected(network, 4096, activation='relu')
network = dropout(network, 0.5)
network = fully_connected(network, 4096, activation='relu')
network = dropout(network, 0.5)
network = fully_connected(network, 17, activation='softmax')

network = regression(network, optimizer='rmsprop',
loss='categorical_crossentropy',
learning_rate=0.0001)

# Training
model = tflearn.DNN(network, checkpoint_path='model_vgg',
max_checkpoints=1, tensorboard_verbose=0)
model.fit(X, Y, n_epoch=500, shuffle=True,
show_metric=True, batch_size=32, snapshot_step=500,
snapshot_epoch=False, run_id='vgg_oxflowers17')


由于 TFLearn 的便捷性,我们只需要在上篇 AlexNet 定义基础上修改每一层卷积层,同时 TFLearn 支持不同的 optimizer:

SGDStochastic Gradient DescentSGD Optimizer accepts learning rate decay. When training a model, it is often recommended to lower the learning rate as the training progresses.
RMSPropRMSPropMaintain a moving (discounted) average of the square of gradients. Divide gradient by the root of this average.
AdamAdamThe default value of 1e-8 for epsilon might not be a good default in general. For example, when training an Inception network on ImageNet a current good choice is 1.0 or 0.1.
MomentumMomentumMomentum Optimizer accepts learning rate decay. When training a model, it is often recommended to lower the learning rate as the training progresses. The function returns the decayed learning rate
AdaGradAdaGradAdaptive Subgradient Methods for Online Learning and Stochastic Optimization. J. Duchi, E. Hazan & Y. Singer. Journal of Machine Learning Research 12 (2011) 2121-2159.
FtrlFtrl ProximalAd Click Prediction: a View from the Trenches
AdaDeltaAdaDeltaADADELTA: An Adaptive Learning Rate Method, Matthew D. Zeiler, 2012.
ProximalAdaGradProximalAdaGradEfficient Learning using Forward-Backward Splitting. J. Duchi, Yoram Singer, 2009.
同时,TFlearn 下还支持 vgg_network_finetuning.py,利用已经训练的 model 在自己的 dataset 上 finetune。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐