说明
最近在学习过程中,遇到了VGG16的搭建、调用和加载预训练参数的问题,下面做一个记录
下面是我在另一个平台写的可以直接运行的项目的链接
基于VGG16的好莱坞明星识别
摘录出关键代码如下:
一、直接调用VGG16模型
函数说明
tf.keras.applications.vgg16.VGG16(
include_top=True, #是否使用顶层
weights=‘imagenet’,#是否加载imgenet预训练参数
input_tensor=None,
input_shape=None,#输入向量形状
pooling=None,#max或avg,最大或平均池化层
classes=1000,#如果使用顶层且使用预训练参数,分类数必须为1000,否则可以自己改动
classifier_activation=‘softmax’#分类激活函数
)
其中顶层指的是非卷积层
使用
下面使用是要了顶层
from tensorflow.keras.applications.vgg16 import VGG16
model = VGG16(
include_top=True,
weights=None,
input_tensor=None,
input_shape=(img_height, img_width, 3),
pooling=max,
classes=len(class_names)
classifier_activation='softmax'
model.summary() # 打印网络结构
二、自己搭建VGG16模型
VGG16_model = models.Sequential([
#两次使用64个3*3的卷积核,采用l2正则化,池化后维度(112,112,64)
layers.Conv2D(64, (3, 3),padding='same', activation='relu', input_shape=(img_height, img_width, 3)),
layers.Conv2D(64, (3, 3), padding='same',activation='relu'),
layers.AveragePooling2D(pool_size=(2,2),strides=(2,2)),
#两次使用128个3*3的卷积核,池化后维度(56,56,128)
layers.Conv2D(128, (3, 3),padding='same',activation='relu'),
layers.Conv2D(128, (3, 3),padding='same',activation='relu'),
layers.AveragePooling2D(pool_size=(2,2),strides=(2,2)),
#三次使用256个3*3的卷积核,池化后维度(28,28,256)
layers.Conv2D(256, (3, 3), padding='same',activation='relu'),
layers.Conv2D(256, (3, 3), padding='same',activation='relu'),
layers.Conv2D(256, (3, 3),padding='same',activation='relu'),
layers.AveragePooling2D(pool_size=(2,2),strides=(2,2)),
#三次使用512个3*3的卷积核,池化后维度(14,14,512)
layers.Conv2D(512, (3, 3),padding='same',activation='relu'),
layers.Conv2D(512, (3, 3),padding='same',activation='relu'),
layers.Conv2D(512, (3, 3),padding='same',activation='relu'),
layers.AveragePooling2D(pool_size=(2,2),strides=(2,2)),
layers.Conv2D(512, (3, 3),padding='same',activation='relu'),
layers.Conv2D(512, (3, 3),padding='same',activation='relu'),
layers.Conv2D(512, (3, 3),padding='same',activation='relu'),
layers.AveragePooling2D(pool_size=(2,2),strides=(2,2)),
layers.Flatten(),
layers.Dense(4096, activation='relu'),
layers.Dense(4096, activation='relu'),
layers.Dense(len(class_names), activation="softmax")
])
三、VGG16模型加载卷积层预训练参数
一般都会只加载前十三层的卷积参数
VGG16_model = models.Sequential([
#两次使用64个3*3的卷积核,采用l2正则化,池化后维度(112,112,64)
layers.Conv2D(64, (3, 3),padding='same', activation='relu', input_shape=(img_height, img_width, 3)),
layers.Conv2D(64, (3, 3), padding='same',activation='relu'),
layers.AveragePooling2D(pool_size=(2,2),strides=(2,2)),
#两次使用128个3*3的卷积核,池化后维度(56,56,128)
layers.Conv2D(128, (3, 3),padding='same',activation='relu'),
layers.Conv2D(128, (3, 3),padding='same',activation='relu'),
layers.AveragePooling2D(pool_size=(2,2),strides=(2,2)),
#三次使用256个3*3的卷积核,池化后维度(28,28,256)
layers.Conv2D(256, (3, 3), padding='same',activation='relu'),
layers.Conv2D(256, (3, 3), padding='same',activation='relu'),
layers.Conv2D(256, (3, 3),padding='same',activation='relu'),
layers.AveragePooling2D(pool_size=(2,2),strides=(2,2)),
#三次使用512个3*3的卷积核,池化后维度(14,14,512)
layers.Conv2D(512, (3, 3),padding='same',activation='relu'),
layers.Conv2D(512, (3, 3),padding='same',activation='relu'),
layers.Conv2D(512, (3, 3),padding='same',activation='relu'),
layers.AveragePooling2D(pool_size=(2,2),strides=(2,2)),
layers.Conv2D(512, (3, 3),padding='same',activation='relu'),
layers.Conv2D(512, (3, 3),padding='same',activation='relu'),
layers.Conv2D(512, (3, 3),padding='same',activation='relu'),
layers.AveragePooling2D(pool_size=(2,2),strides=(2,2)),
])
# 加载模型参数
VGG16_model.load_weights('./weight/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5')
# 冻结前13层网络参数 保证加载的预训练参数不被改变
for layer in VGG16_model.layers[:13]:
layer.trainable = False
model = models.Sequential([
VGG16_model,
layers.Flatten(),
layers.Dense(4096, activation='relu'),
layers.Dense(4096, activation='relu'),
layers.Dense(len(class_names), activation="softmax")
])
四、其他说明
1.自己搭建的VGG16模型也可以增加BN层、Drop层、L2正则化进行优化。
2.预训练参数可以从GitHub上下载(最全),或者是进入我开头放的链接,fork后也可以在project中下载(只有vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5一种)