文章目录
深度学习 — keras 改写 VGG16 网络,替换全连接层
一、VGG16简介
1. VGG网络结构
VGG16:包含了16个隐藏层(13个卷积层和3个全连接层)
VGG19:包含了19个隐藏层(16个卷积层和3个全连接层)
下图为VGG16网络结构的可视化:
2. VGG网络的优缺点
VGG优点
- VGGNet的结构非常简洁,整个网络都使用了同样大小的卷积核尺寸(3x3)和最大池化尺寸(2x2)。
- 几个小滤波器(3x3)卷积层的组合比一个大滤波器(5x5或7x7)卷积层好。
- 验证了通过不断加深网络结构可以提升性能
VGG缺点
- VGG耗费更多计算资源,并且使用了更多的参数(这里不是3x3卷积的锅),导致更多的内存占用(140M)。其中绝大多数的参数都是来自于第一个全连接层。VGG可是有3个全连接层啊!
PS:有的文章称:发现这些全连接层即使被去除,对于性能也没有什么影响,这样就显著降低了参数数量。
二、keras 改写 VGG16 网络
- keras 加载 VGG16 预训练网络模型:
from keras.applications import VGG16
# include_top:是否包含卷积之上的分类器模块
vgg_model = VGG16(weights='imagenet',
include_top=True)
- 可视化 VGG16 网络结构:
vgg_model.summary()
- 改写 VGG16 网络:
- 提取 VGG16 网络中的卷积模块
- 替换 VGG16 网络的全连接层
from keras.models import Model
from keras.layers import Flatten, Dense, Dropout
# 提取 VGG16 网络中的卷积模块
inputs = vgg_model.inputs
outputs = vgg_model.get_layer('block5_pool').output
conv_block = Model(inputs=inputs, outputs=outputs)
conv_block.summary()
# 替换 VGG16 网络的全连接层
# 获取卷积模块的输出张量
conv_block_out = conv_block.output
# 添加自定义的全连接模块
model_outputs = Flatten(name='flatten')(conv_block_out)
model_outputs = Dense(1024, activation='relu', name='fc1')(model_outputs)
model_outputs = Dense(1024, activation='relu', name='fc2')(model_outputs)
model_outputs = Dropout(0.5)(model_outputs)
model_outputs = Dense(10, activation='softmax')(model_outputs) # model_outputs就是最后的y
base_model = Model(inputs=conv_block.inputs, outputs=model_outputs)
base_model.summary()
三、VGG16 进行特征提取,预测
为了简单起见,直接加载 VGG16 的原来网络结构进行操作。
from keras.applications import VGG16
from keras.models import Model
from keras.applications.vgg16 import preprocess_input, decode_predictions
from keras.preprocessing import image
import numpy as np
vgg_model = VGG16(weights='imagenet',
include_top=True)
inputs = vgg_model.inputs
outputs = vgg_model.get_layer('block5_pool').output
conv_block = Model(inputs=inputs, outputs=outputs)
conv_block.summary()
# 加载测试图片
img_path = 'dog.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
# 预处理图片
x = preprocess_input(x)
# 提取出卷积模块的输出 feature Map
feature_map = base_model.predict(x)
print(feature_map)
# 类别预测
pred_labes = vgg_model.predict(x)
# 解析预测结果
labels = decode_predictions(features)
print(labels)