经典论文阅读(2)-VGGNet

经典论文阅读(2)-VGGNet

0. 前言

  VGGNet是牛津大学Visual Geometry Group和Deep Mind共同开发的一种深度卷积网络。他们探索了卷积神经网络深度与其性能之间的关系。通过堆叠 3 ∗ 3 3*3 33的小型卷积核和 2 ∗ 2 2*2 22的池化层,构建了VGGNet16和VGGNet19。该模型获得了ILSVRC 2014年图像分类项目的第二名和图像定位项目的 第一名。它继承了AlexNet的思路,一样由5个卷积层和3个全连接层组成。只不过在每个卷积层中进行2~4次连续卷积

论文原文:Very Deep Convolutional Networks for Large-Scale Image Recognition

1. VGGNet与AlexNet

【1】在VGGNet中,卷积层使用的卷积核均为 3 ∗ 3 3*3 33,步长都为1。卷积之后都要进行最大池化Max pooling,池化核为 2 ∗ 2 2*2 22, 步长为2。

【2】所有的隐藏层都使用Relu激活函数。

【3】全连接层1,2使用Dropout避免过拟合,概率为0.5。

VGGNet显著的特点是:

  1. 特征图空间分辨率单调递减;
  2. 特征图通道数单调递增。

AlexNet没有这个规律,VGGNet和后续的GoogLeNet、ResNet均遵循这个规律。

2. 关于文章对收敛快的解释

  在文章中提到,VGGNet虽然参数多,层数深,但是收敛速度快的原因是:

  1. 由更深的网络和较小的卷积核引起的隐性正则化;
  2. 某些层的预初始化;

文章中关于某些层初始化的说法这样的,所有的权值并不是随机初始化的,而是先训练模型A(如下图所示,文中一共提出了6种模型,最后两种就是我们见到的VGGNet16和VGGNet19)

对模型A进行随机初始化,然后训练一小段时间。取出模型A此时的权值,用于初始化其他模型的卷积层的前4层和全连接层,卷积层第5层仍是随机初始化。但是他们提交结果后发现使用随机初始化来训练也是可以的T_T。

3. 关于使用3*3的卷积核

  在文章中提到,一个 5 ∗ 5 5*5 55的卷积核可以通过两个 3 ∗ 3 3*3 33的卷积核级联得到同样的效果,一个 7 ∗ 7 7*7 77的卷积核可以用3个 3 ∗ 3 3*3 33的卷积核级联来实现。其实可以这么理解:

一个 5 ∗ 5 5*5 55的卷积核可以将图上 5 ∗ 5 5*5 55个像素点的区域变成特征图上的一个点。那么对这个区域先使用 3 ∗ 3 3*3 33的卷积核,步长为1,就可以得到一个 3 ∗ 3 3*3 33的图,再对这个图使用 3 ∗ 3 3*3 33的卷积核,就得到了一个点。这跟 5 ∗ 5 5*5 55卷积核的效果是一样的。

4. 关于模型训练

  VGGNet也使用了多个GPU一起训练,每个GPU都训练一个batch,在计算梯度的时候,取这些GPU上计算梯度的均值作为全局的梯度。

5. VGGNet的实现

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
import tflearn.datasets.oxflower17 as oxflower17

import numpy as np

def loadData():
    X, Y = oxflower17.load_data(dirname='17flowers/', one_hot=True, resize_pics=(227, 227))
    return X, Y

def convLayer(network, para):
    for i in range(1, 6): # 五层卷积层
        for j in range(para[i]['convNum']):
            network = conv_2d(network, para[i]['kernel_num'], 3, strides=1, activation='relu')
        network = max_pool_2d(network, 2, strides=2)
    return network

def fcLayer(network, para):
    for i in range(1, 4): # 三层全连接层
        network = fully_connected(network, para[i]['nNode'], activation=para[i]['activa'])
        if para[i]['isDropout']:
            network = dropout(network, 0.5)

    return network

def VGGNet16():
    # 定义输入层
    network = input_data(shape=[None, 227, 227, 3])

    '''
    定义卷积层:
    卷积核大小均为: 3*3, strides是1
    池化核大小均为: 2*2, strides是2
    激励函数均为:Relu
    '''
    convPara = {1: {'kernel_num': 64, 'convNum': 2},
                2: {'kernel_num': 128, 'convNum': 2},
                3: {'kernel_num': 256, 'convNum': 3},
                4: {'kernel_num': 512, 'convNum': 3},
                5: {'kernel_num': 512, 'convNum': 3}}
    network = convLayer(network, convPara)

    '''
    定义全连接层
    前两层为4096个节点,并设置dropout,概率为0.5,激励函数为relu
    最后一层节点个数为17, 激励为relu,最后的输出结果通过softmax
    '''
    fcPara = {1: {'nNode': 4096, 'isDropout': True, 'activa': 'relu'},
              2: {'nNode': 4096, 'isDropout': True, 'activa': 'relu'},
              3: {'nNode': 17, 'isDropout': False, 'activa': 'softmax'}}
    network = fcLayer(network, fcPara)

    return network

def VGGNet19():
    # 定义输入层
    network = input_data(shape=[None, 227, 227, 3])

    '''
    定义卷积层:
    卷积核大小均为: 3*3, strides是1
    池化核大小均为: 2*2, strides是2
    激励函数均为:Relu
    '''
    convPara = {1: {'kernel_num': 64, 'convNum': 2},
                2: {'kernel_num': 128, 'convNum': 2},
                3: {'kernel_num': 256, 'convNum': 4},
                4: {'kernel_num': 512, 'convNum': 4},
                5: {'kernel_num': 512, 'convNum': 4}}
    network = convLayer(network, convPara)

    '''
    定义全连接层
    前两层为4096个节点,并设置dropout,概率为0.5,激励函数为relu
    最后一层节点个数为17, 激励为relu,最后的输出结果通过softmax
    '''
    fcPara = {1: {'nNode': 4096, 'isDropout': True, 'activa': 'relu'},
              2: {'nNode': 4096, 'isDropout': True, 'activa': 'relu'},
              3: {'nNode': 17, 'isDropout': False, 'activa': 'softmax'}}
    network = fcLayer(network, fcPara)

    return network

def main():
    X, Y = loadData()
    network = VGGNet16()
    network = regression(network, optimizer='momentum')

    # Start training
    model = tflearn.DNN(network, checkpoint_path='model_vgg16/', max_checkpoints=5, tensorboard_verbose=0, tensorboard_dir='logs/')
    model.fit(X, Y, n_epoch=1, validation_set=0.1, shuffle=True, show_metric=True, batch_size=32, snapshot_step=200, snapshot_epoch=False, run_id='vggnet_oxflowers17')


if __name__ == '__main__':
    main()

参考资料

深度学习原理与TensorFlow实践 - 喻俨
VGGNet结构分析

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值