原文链接
https://blog.csdn.net/qq_33037903/article/details/88774615
背景简介
2012年 AlexNet 在 ImageNet 上显著的降低了分类错误率,深度神经网络进入迅速发展阶段。在2014年牛津大学机器人实验室尝试构建了更深的网络,文章中称为"VERY DEEP CONVOLUTIONAL NETWORKS",如VGG16,有16层,虽然现在看起来稀疏平常,但与 AlexNet 相比,翻了几倍。这个阶段,主要是没有解决网络太深梯度反向传播消失的问题,且受限于GPU等硬件设备的性能,所以深度网络不易于训练。不过,VGG 显然是当时最好的图像分类模型,斩获 ILSVRC 比赛冠军。顺便说下,2012年之后,标准数据集主要是ImageNet,到后来又有微软的COCO数据集。
原论文地址
https://arxiv.org/pdf/1409.1556.pdf
文章发在 ICLR( International Conference on Learning Representations) 2015会议上,截止目前引用次数为27081
个人github实现
https://github.com/uestcsongtaoli/vgg_net
模型介绍
这里重点介绍VGG16
上图上半部分相对直观,下半部分是一种常见的普通网络结构的表示方法,下半部分最后一层不应该是4096,应该是分类问题的类别数目 num_classes。
该模型可以简单分为5个 stage,(我猜测这种思想来自于 AlexNet 的5层卷积,可以参考我写的关于AlexNet的文章结构介绍部分)每层两卷积核池化组成,最后接3层全连接用于分类。
先定义 conv block 包括卷积、BatchNormalization 和 Activation:
def conv_block(layer, filters, kernel_size=(3, 3), strides=(1, 1), padding='same', name=None):
x = Conv2D(filters=filters,
kernel_size=kernel_size,
strides=strides,
padding=padding,
kernel_initializer="he_normal",
name=name)(layer)
x = BatchNormalization()(x)
x = Activation('relu')(x)
return x
Stage 1
- 卷积层Conv_1_1
- 卷积层Conv_1_2
- 池化层 max_pool_1
x = conv_block(input_layer, filters=64, kernel_size=(3, 3), name="conv1_1_64_3x3_1") x = conv_block(x, filters=64, kernel_size=(3, 3), name="conv1_2_64_3x3_1") x = MaxPool2D(pool_size=(2, 2), strides=(2, 2), name="max_pool_1_2x2_2")(x)
Stage 2
- 卷积层Conv_2_1
- 卷积层Conv_2_2
- 池化层 max_pool_2
x = conv_block(x, filters=128, kernel_size=(3, 3), name="conv2_1_128_3x3_1") x = conv_block(x, filters=128, kernel_size=(3, 3), name="conv2_2_128_3x3_1") x = MaxPool2D(pool_size=(2, 2), strides=(2, 2), name="max_pool_2_2x2_2")(x)
Stage 3
- 卷积层Conv_3_1
- 卷积层Conv_3_2
- 卷积层Conv_3_3
- 池化层 max_pool_3
x = conv_block(x, filters=256, kernel_size=(3, 3), name="conv3_1_256_3x3_1") x = conv_block(x, filters=256, kernel_size=(3, 3), name="conv3_2_256_3x3_1") x = conv_block(x, filters=256, kernel_size=(1, 1), name="conv3_3_256_3x3_1") x = MaxPool2D(pool_size=(2, 2), strides=(2, 2), name="max_pool_3_2x2_2")(x)
Stage 4
- 卷积层Conv_4_1
- 卷积层Conv_4_2
- 卷积层Conv_4_3
- 池化层 max_pool_4
x = conv_block(x, filters=512, kernel_size=(3, 3), name="conv4_1_512_3x3_1") x = conv_block(x, filters=512, kernel_size=(3, 3), name="conv4_2_512_3x3_1") x = conv_block(x, filters=512, kernel_size=(1, 1), name="conv4_3_512_3x3_1") x = MaxPool2D(pool_size=(2, 2), strides=(2, 2), name="max_pool_4_2x2_2")(x)
Stage 5
- 卷积层Conv_5_1
- 卷积层Conv_5_2
- 卷积层Conv_5_3
- 池化层 max_pool_5
x = conv_block(x, filters=512, kernel_size=(3, 3), name="conv5_1_512_3x3_1") x = conv_block(x, filters=512, kernel_size=(3, 3), name="conv5_2_512_3x3_1") x = conv_block(x, filters=512, kernel_size=(1, 1), name="conv5_3_512_3x3_1") x = MaxPool2D(pool_size=(2, 2), strides=(2, 2), name="max_pool_5_2x2_2")(x)
FC Layers
3 层全连接,最后接 softmax 分类
# FC layer 1
x = Flatten()(x)
x = Dense(2048)(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
x = Activation("relu")(x)
# FC layer 2
x = Dense(1024)(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
x = Activation("relu")(x)
# FC layer 3
x = Dense(num_classes)(x)
x = BatchNormalization()(x)
x = Activation("softmax")(x)
全连接层最后的 units 个数可以根据实际问题修改,我觉得4096对于10个类别的分类太多了,简单的处理了下,减少了一般的参数,毕竟实验室机器不太好呀!
这是原论文中不同深度的VGG网络结构
个人理解
- 看完 VGG 你会觉得就是在 AlexNet 网络上没一层进行了改造,5个 stage 对应 AlexNet 中的5层卷积,3层全连接仍然不变。
- 图片输入的大小还是沿用了 224x224x3
- 网络更深,训练出来的效果确实比 AlexNet 有所提升
- 常用的 trick 都加进去了: max_pooling/batch_normalization/dropout(我没加)
- 调参主要是,初始化用了 he_normal;使用了不同的优化器 optimizer, 如 adamax 等
- 由于网络在如今看来并不是太深,所以有些任务的基础骨架仍然选择VGG
更多参考资料
- Reading the VGG Network Paper and Implementing It From Scratch with Keras
https://hackernoon.com/learning-keras-by-implementing-vgg16-from-scratch-d036733f2d5 - VGG Convolutional Neural Networks Practical
原文作者的网络,讲解详细,源码是 MATLAB
http://www.robots.ox.ac.uk/~vgg/practicals/cnn/index.html - Convolutional Neural Network with VGG Architecture
清晰的结构图
https://betweenandbetwixt.com/2018/12/23/convolutional-neural-network-with-vgg-architecture/ - VGG in TensorFlow
https://www.cs.toronto.edu/~frossard/post/vgg16/
代码
- VGG16 – Implementation Using Keras
https://engmrk.com/vgg16-implementation-using-keras/ - VGG16 model for Keras
https://gist.github.com/baraldilorenzo/07d7802847aaad0a35d3 - VGG16 model for TensorFlow
https://github.com/machrisaa/tensorflow-vgg/blob/master/vgg16.py