一、综述
预训练网络(pretrained network)是一个保存好的网络,之前已在大型数据集(通常是大规模图像分类任务)上训练好。如果这个原始数据集足够大且足够通用,那么预训练网络学到的特征的空间层次结构可以有效地作为视觉世界的通用模型,即使这些新问题涉及的类别和原始任务完全不同。
假设有一个在 ImageNet 数据集(140 万张标记图像,1000 个不同的类别)上训练 好的大型卷积神经网络。ImageNet 中包含许多动物类别,其中包括不同种类的猫和狗,因此可 以认为它在猫狗分类问题上也能有良好的表现。
使用预训练网络有两种方法:特征提取(feature extraction)和微调模型(fine-tuning)。
二、特征提取
特征提取是使用之前网络学到的表示来从新样本中提取出有趣的特征。然后将这些特征输 入一个新的分类器,从头开始训练。
用于图像分类的卷积神经网络包含两部分:首先是一系列池化层和卷积层,最后是一个密集连接分类器。第一部分叫作模型的卷积基(convolutionalbase)。对于卷积神经网络而言,特征提取就是取出之前训练好的网络的卷积基,在上面运行新数据,然后在输出上面 训练一个新的分类器
为什么仅重复使用卷积基?我们能否也重复使用密集连接分类器?一般来说,应该避免这么做。原因在于卷积基学到的表示可能更加通用,因此更适合重复使用。卷积神经网络的特征图表示通用概念在图像中是否存在,无论面对什么样的计算机视觉问题,这种特征图都可能很有用。但是,分类器学到的表示必然是针对于模型训练的类别,其中仅包含某个类别出现在整张图像中的概率信息。此外,密集连接层的表示不再包含物体在输入图像中的位置信息。密集连接层舍弃了空间的概念
某个卷积层提取的表示的通用性(以及可复用性)取决于该层在模型中的深度。模型中更靠近底部的层提取的是局部的、高度通用的特征图(比如视觉边缘、颜色和纹理),而更 靠近顶部的层提取的是更加抽象的概念(比如“猫耳朵”或“狗眼睛”)。如果你的新数据集与原始模型训练的数据集有很大差异,那么最好只使用模型的前几层来做特征提取,而不是使用整个卷积基。
三、特征提取程序
1、在你的数据集上运行卷积基,将输出保存成硬盘中的Numpy 数组,然后用这个数据作 为输入,输入到独立的密集连接分类器中。
验证集损失从一开始就在增加,而验证集精度在90%上下摆动,说明从一开始就已经过拟合了,原因是由于训练数据太少了。因此,我添加了一个ImageDataGenerator以对图片进行增强处理,想要将增强图片输入进卷积基以得到增强的卷积基的输出,得增强处理后的图片达到8000张,但是情况却和增强之前一样,不知为何?推测是因为卷积基对这些增强前后的图片的预测输出都没有太大的区别
#加载vgg16的卷积基
from keras.applications import VGG16
conv_base = VGG16(weights='imagenet',
include_top=False,
input_shape=(150, 150, 3))
conv_base.summary()
#定义将图片转换的函数
def extract_features(directory, sample_count, enhance=0):
features = np.zeros(shape=(sample_count, 4, 4, 512))
labels = np.zeros