CNN系列学习之VGG16

前言:

CNN系列总结自己学习主流模型的笔记,从手写体的LeNet-5到VGG16再到历年的ImageNet大赛的冠军ResNet50,Inception V3,DenseNet等。重点总结每个网络的设计思想(为了解决什么问题),改进点(是怎么解决这些问题的),并使用keras的两种定义模型的方式Sequential()和Functional式模型实现一遍(加深对模型理解的同时熟悉keras的使用)。

一、VGG16的设计思想

二、VGG16使用Keras的两种实现方式

1、Sequential()序列式模型实现

-*- coding -*-
'''
created on 2019-7-31 19:35:50

@author:fangsh
'''
#%%
import keras

from keras.models import Sequential
from keras.layers import Conv2D,MaxPool2D,Dense,Flatten
from keras.applications import vgg16
'''
序列式模型第一层一定要记得定义input_shape
    1、
'''
model = Sequential()
#block1
model.add(Conv2D(filters=64,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',name='block1_conv1',input_shape=(224,224,3)))#input_shape只需写图像的shape。不需要加batch的N
model.add(Conv2D(filters=64,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',name='block1_conv2'))
model.add(MaxPool2D(pool_size=(2,2),strides=(2,2),name='block1_pool'))
#block2
model.add(Conv2D(filters=128,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',name='block2_conv1'))
model.add(Conv2D(filters=128,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',name='block2_conv2'))
model.add(MaxPool2D(pool_size=(2,2),strides=(2,2),name='block2_pool'))
#block3
model.add(Conv2D(filters=256,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',name='block3_conv1'))
model.add(Conv2D(filters=256,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',name='block3_conv2'))
model.add(Conv2D(filters=256,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',name='block3_conv3'))
model.add(MaxPool2D(pool_size=(2,2),strides=(2,2),name='block3/pool'))
#block4
model.add(Conv2D(filters=512,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',name='block4_conv1'))
model.add(Conv2D(filters=512,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',name='block4_conv2'))
model.add(Conv2D(filters=512,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',name='block4_conv3'))
model.add(MaxPool2D(pool_size=(2,2),strides=(2,2),name='block4/pool'))
#block5
model.add(Conv2D(filters=512,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',name='block5_conv1'))
model.add(Conv2D(filters=512,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',name='block5_conv2'))
model.add(Conv2D(filters=512,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',name='block5_conv3'))
model.add(MaxPool2D(pool_size=(2,2),strides=(2,2),name='block5/pool'))
#fully
model.add(Flatten())
model.add(Dense(units=4096,activation='relu',name='fc1'))
model.add(Dense(units=4096,activation='relu',name='fc2'))
model.add(Dense(units=1000,activation='softmax',name='prediction'))

model.summary()
#%%
#读取imageNet的预训练模型参数,来验证定义的是否正确
modelPath = '/data/sfang/vgg16_weights_tf_dim_ordering_tf_kernels.h5'
model.load_weights(modelPath)

2、Functional函数式模型实现

'''
Keras函数式模型使用
    1、支持定义多输出,多输入模型/Sequential()模型只能定义单个输入单个输出模型
    2、像连接火车一样
Functional Model三步走:
    1、定义输入层
    2、由输出层开始连接其他网络层,上一次的输出是下一次的输入(正常情况下)。
    3、指定输入tensor和输出tensor定义一个函数式模型
'''
import keras

from keras.models import Model
from keras.layers import Dense,Conv2D,MaxPool2D,Flatten,Input
#1、定义输入层
imgInput = Input(shape=(224,224,3),name='input')
#2、依次连接其他层,上一次输出作为下一次输入
#block1
x = Conv2D(filters=64,kernel_size=(3,3),padding='same',activation='relu',name='block1_conv1')(imgInput)
x = Conv2D(filters=64,kernel_size=(3,3),padding='same',activation='relu',name='block1_conv2')(x)
x = MaxPool2D(pool_size=(2,2),strides=(2,2),name='block1_pool')(x)
#block2
x = Conv2D(filters=128,kernel_size=(3,3),padding='same',activation='relu',name='block2_conv1')(x)
x = Conv2D(filters=128,kernel_size=(3,3),padding='same',activation='relu',name='block2_conv2')(x)
x = MaxPool2D(pool_size=(2,2),strides=(2,2),name='block2_pool')(x)
#block3
x = Conv2D(filters=256,kernel_size=(3,3),padding='same',activation='relu',name='block3_conv1')(x)
x = Conv2D(filters=256,kernel_size=(3,3),padding='same',activation='relu',name='block3_conv2')(x)
x = Conv2D(filters=256,kernel_size=(3,3),padding='same',activation='relu',name='block3_conv3')(x)
x = MaxPool2D(pool_size=(2,2),strides=(2,2),name='block3_pool')(x)
#block4
x = Conv2D(filters=512,kernel_size=(3,3),padding='same',activation='relu',name='block4_conv1')(x)
x = Conv2D(filters=512,kernel_size=(3,3),padding='same',activation='relu',name='block4_conv2')(x)
x = Conv2D(filters=512,kernel_size=(3,3),padding='same',activation='relu',name='block4_conv3')(x)
x = MaxPool2D(pool_size=(2,2),strides=(2,2),name='block4_pool')(x)
#block5
x = Conv2D(filters=512,kernel_size=(3,3),padding='same',activation='relu',name='block5_conv1')(x)
x = Conv2D(filters=512,kernel_size=(3,3),padding='same',activation='relu',name='block5_conv2')(x)
x = Conv2D(filters=512,kernel_size=(3,3),padding='same',activation='relu',name='block5_conv3')(x)
x = MaxPool2D(pool_size=(2,2),strides=(2,2),name='block5_pool')(x)
#fully conv
x = Flatten()(x)
x = Dense(units=4096,activation='relu',name='fc1')(x)
x = Dense(units=4096,activation='relu',name='fc2')(x)
pred = Dense(units=1000,activation='relu',name='prediction')
functionalModel = Model(inputs=imgInput,outputs=pred)

functionalModel.summary()

#%%
#读取imageNet的预训练模型参数,来验证定义的是否正确
modelPath = '/data/sfang/vgg16_weights_tf_dim_ordering_tf_kernels.h5'
model.load_weights(modelPath)

 

上一篇:ZFNet: Visualizing and Understanding Convolutional Networks


下一篇:常用激活函数sigmoid,Tanh,ReLU