机器学习、深度学习与人工智能大数据,机器学习,人工智能深度学习·神经网络·计算机视觉

CNN经典模型——VGGNet

2019-08-06  本文已影响9人  Ice_spring

VGGNet结构

VGGNet 是牛津大学视觉几何组(Visual Geometry Group)和 GoogleDeepMind 公司的研究员一起研发的的深度卷积神经网络。在ImageNet大型视觉识别挑战 ILSVRC 2014 中获得物体检测任务第一名和图像分类任务第二名(图像分类第一名是 GoogLeNet)。它最主要的贡献就是展示了卷积神经网络的深度与其性能之间的关系,实验结果证实了增加网络的深度可以一定程度上影响网络最终的性能。直到现在,VGG仍然被广泛用于提取图像特征。
VGGNet的整体结构:

VGG

相比于AlexNet,VGGNet的层次更加深了。以VGG-16为例,VGG-16 网络没有那么多超参数,这是一种只需要专注于构建卷积层的简单网络,说它简单是因为它的结构足够清晰,VGG16由5块卷积层(共13个卷积操作)、3层全连接层、softmax输出层构成,层与层之间使用Maxpooling,所有隐层的激活函数都采用ReLU函数。
(注:这里所说的“5块卷积层”是按隔开的卷积层算的,实际VGG16共13个卷积层。)
该网络的具体结构如下:

注:卷积层和全连接层的唯一区别就是卷积层的神经元和输入是局部联系的,并且同一个通道内的不同神经元共享权值。这里卷积层和第一个全连接层的计算实际上相同,因此可以将其等效为卷积层,只要将卷积核大小设置为输入空间大小即可:例如这里输入为7x7x512,第一层全连接层输出4096,我们可以将其看作卷积核大小为7x7,步长为1,没有填充,输出为1x1x4096的卷积层。而且全连接层也可以看做1x1卷积核卷积的结果。这样的好处在于输入图像的大小不再受限制,不管前面处理如何最终都处理为4096个参数的全连接层,因此可以高效地对图像作滑动窗式预测;而且相比于全连接层的计算量比较大,等效卷积层的计算量减小了,这样既达到了目的又十分高效。

顺便说一下,VGG-16 的这个数字 16,就是指在这个网络中卷积层和全连接层共16层。这确实是个很大的网络,总共包含约 1.38 亿个参数,即便以现在的标准来看都算是非常大的网络。但 VGG-16 的结构并不复杂,这点非常吸引人,而且这种网络结构很规整,都是几个卷积层后面跟着可以压缩图像大小的池化层,池化层缩小图像的高度和宽度。同时,卷积层的过滤器数量变化存在一定的规律,由 64 翻倍变成 128,再到 256 和 512。无论如何,每一步都进行翻倍,或者说在每一组卷积层进行过滤器翻倍操作,正是设计此种网络结构的另一个简单原则。这种相对简单一致的网络结构对研究者很有吸引力。

VGG原文献下载:VGGNet原英文文献下载

VGGNet的Trick

视野域

在无Padding,Stride=1的情况下,一个5x5的原图像经过一个5x5的卷积核后变为1x1,同样经过两个3x3的卷积核也可以变成1x1,这说明2个3x3和一个5x5有相同的视野域,而且用两次3x3卷积还能多一次非线性变换,这一定程度上会增强模型的泛化能力。且两个3x3卷积核的参数相对数为:2\times3\times3=18,而一个5x5卷积核参数相对数为:5\times5=25,所以一般常用3x3的卷积核(小的卷积核代替大的卷积核);

VGG-16的Keras实现

下面在Keras框架下搭建VGG-16网络:

def VGG_16(weights_path=None):
    model = Sequential()
    model.add(ZeroPadding2D((1,1),input_shape=(3,224,224)))#卷积输入层,指定了输入图像的大小
    model.add(Convolution2D(64, 3, 3, activation='relu'))#64个3x3的卷积核,生成64*224*224的图像,激活函数为relu 
    model.add(ZeroPadding2D((1,1))) 
    model.add(Convolution2D(64, 3, 3, activation='relu'))#再来一次卷积 生成64*224*224
    model.add(MaxPooling2D((2,2), strides=(2,2)))#pooling操作,相当于变成64*112*112
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(128, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(128, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))#128*56*56
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(256, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(256, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(256, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))#256*28*28
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu')) 
    model.add(ZeroPadding2D((1,1))) 
    model.add(Convolution2D(512, 3, 3, activation='relu')) 
    model.add(ZeroPadding2D((1,1))) 
    model.add(Convolution2D(512, 3, 3, activation='relu')) 
    model.add(MaxPooling2D((2,2), strides=(2,2)))#512*14*14
    model.add(ZeroPadding2D((1,1))) 
    model.add(Convolution2D(512, 3, 3, activation='relu')) 
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu')) 
    model.add(MaxPooling2D((2,2), strides=(2,2)))  #到这里已经变成了512*7*7

    model.add(Flatten())#这里有点问题

    model.add(Dense(4096, activation='relu'))#全连接层有4096个神经核,参数个数就是4096*25088
    model.add(Dropout(0.5))#0.5的概率抛弃一些连接 
    model.add(Dense(4096, activation='relu'))#再来一个全连接 
    model.add(Dropout(0.5))
    model.add(Dense(1000, activation='softmax'))
    if weights_path:
        model.load_weights(weights_path)
    return model

小结:
1、通过增加深度能一定程度上有效地提升性能;
2、VGG16,从头到尾只有3x3卷积与2x2池化,简单一致;
3、卷积可代替全连接,以适应各种尺寸的图片

上一篇下一篇

猜你喜欢

热点阅读