经典卷积神经网络结构——VGG网络结构详解(卷积神经网络入门,Keras代码实现)

背景简介

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
经典卷积神经网络结构——VGG网络结构详解(卷积神经网络入门,Keras代码实现)
上图上半部分相对直观,下半部分是一种常见的普通网络结构的表示方法,下半部分最后一层不应该是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

  1. 卷积层Conv_1_1
  2. 卷积层Conv_1_2
  3. 池化层 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

  1. 卷积层Conv_2_1
  2. 卷积层Conv_2_2
  3. 池化层 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

  1. 卷积层Conv_3_1
  2. 卷积层Conv_3_2
  3. 卷积层Conv_3_3
  4. 池化层 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

  1. 卷积层Conv_4_1
  2. 卷积层Conv_4_2
  3. 卷积层Conv_4_3
  4. 池化层 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

  1. 卷积层Conv_5_1
  2. 卷积层Conv_5_2
  3. 卷积层Conv_5_3
  4. 池化层 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网络结构详解(卷积神经网络入门,Keras代码实现)

个人理解

  1. 看完 VGG 你会觉得就是在 AlexNet 网络上没一层进行了改造,5个 stage 对应 AlexNet 中的5层卷积,3层全连接仍然不变。
  2. 图片输入的大小还是沿用了 224x224x3
  3. 网络更深,训练出来的效果确实比 AlexNet 有所提升
  4. 常用的 trick 都加进去了: max_pooling/batch_normalization/dropout(我没加)
  5. 调参主要是,初始化用了 he_normal;使用了不同的优化器 optimizer, 如 adamax 等
  6. 由于网络在如今看来并不是太深,所以有些任务的基础骨架仍然选择VGG

更多参考资料

  1. Reading the VGG Network Paper and Implementing It From Scratch with Keras
    https://hackernoon.com/learning-keras-by-implementing-vgg16-from-scratch-d036733f2d5
  2. VGG Convolutional Neural Networks Practical
    原文作者的网络,讲解详细,源码是 MATLAB
    http://www.robots.ox.ac.uk/~vgg/practicals/cnn/index.html
  3. Convolutional Neural Network with VGG Architecture
    清晰的结构图
    https://betweenandbetwixt.com/2018/12/23/convolutional-neural-network-with-vgg-architecture/
  4. VGG in TensorFlow
    https://www.cs.toronto.edu/~frossard/post/vgg16/

代码

  1. VGG16 – Implementation Using Keras
    https://engmrk.com/vgg16-implementation-using-keras/
  2. VGG16 model for Keras
    https://gist.github.com/baraldilorenzo/07d7802847aaad0a35d3
  3. VGG16 model for TensorFlow
    https://github.com/machrisaa/tensorflow-vgg/blob/master/vgg16.py