文章目录

数据预处理

首先将 train中的照片分别划分为猫狗的测试集、验证集和训练集 。(原始从数据集可在如下网址下载:https://www.kaggle.com/c/dogs-vs-cats/data

为了便于理解各个功能所作出的贡献,我们只取少量数据集用于学习

可以看到,训练精度慢慢趋向于100%,而验证精度则一直在75%左右徘徊;训练损失接近线性下降,直到接近于0,但验证损失尽在7、8轮左右达到最小,之后快速增加。
这是因为训练样本相对较少(2000个),所以过拟合问题亟需解决,如使用dropout和权重衰减(L2正则化)。而我们这次将使用一种针对计算机视觉领域的新方法,在用深度学习模型处理图像时几乎都会用到这种方法,它就是数据增强(data augmentation)。

数据增强并添加dropou层后

数据增强是从现有的训练样本中生成更多的训练数据,其方法是利用多种能够生成可信图像的随即变换来增加(augment)样本。其目标是,模型在训练时不会两次查看完全相同的图像。这让模型能够观察到数据的更多内容,从而获得更好的泛化能力。 在keras中,可以通过ImageDataGenerator实例读取的图像执行多次随即变换来实现。

如果使用这种数据增强来训练一个新网络,那么网络将不会看到两次同样的输入。但网络看到的输入任然是高度相关的,因为这些输入都来自于少量的原始图像。你无法生成新信息,而只能混合现有信息。因此,这种方法可能不足以完全消除过拟合。 为了进一步降低过拟合,还需要向模型中添加一个Dropout层,添加到密集连接分类器之前。

可以看到,使用了数据增强和dropout后,模型不再过拟合:训练曲线紧紧跟随着验证曲线。通过进一步使用正则化方法以及调节网络参数(比如每个卷积层的过滤器个数或网络中的层数),我们可以得到更高的精度。但只靠从头开始训练自己的卷积神经网络,再想提高精度就十分困难,因为可用的数据太少。要想在这个问题上进一步提高精度,就需要使用预训练的模型。

引入VGG16架构

想要将深度学习应用于小型图像数据集,一种常用切非常高效的方法时使用预训练网络。预训练网络(pretrained network)是一个保存好的网络,之前已在大型数据集(通常是大规模图像分类任务)上训练好。如果这个原始数据集足够大且通用,那么预训练网络学到的特征的空间层次结构可以有效地作为视觉世界的通用模型,因此这些特征可用于各种不同的计算机视觉问题,即使这些新问题涉及的类别和原始任务完全不同。

这种学到的特征在不同问题之间的可移植性,是深度学习与许多早期浅层学习方法相比的重要优势,它使得深度学习对小数据问题非常有效。

最后的特征图形状为(4,4,512)。我们将在这个特征上添加一个密集连接分类器。下一步有两种方法可供选择:
1.在数据集上运行卷积基,将输出保存成硬盘中的Numpy数组,然后用这个数据作为输入,输入到独立的密集连接分类器中。这种方法速度快,计算代价低,应为对于每个输入图像只需运行一次卷积基,而卷积基是目前流程中计算代价最高的。但出于同样的原因,这种方法不允许使用数据增强。
2.在顶部添加Dense层来扩展已有模型(即conv_base),并在输入数据上端到端地运行整个模型。这样就可以使用数据增强,因为每个输入图像进入模型时都会经过卷积基。但出于同样的原因,这种方法的计算代价比第一种要高很多。

不使用数据增强的快速特征提取

验证精度达到了约90%,比之前的85左右又增加了一大步。但从图中可以看出,虽然dropout比率相当大,但模型几乎始终在过拟合。这是因为本方法没有使用数据增强,而数据增强对防止小型图像数据集的过拟合非常重要。

使用数据增强的特征提取

在编译和训练模型之前,一定要‘冻结’卷积基。冻结(freeze)一个或多个层是指在训练过程中保持其权重不变。如果不这么做,那么卷积基之前学到的表示将会在训练过程中被修改。因为器上添加的Dense层是随机初始化的,所以非常大的权重更新将会在网络上传播,对之前学到的表示造成很大破坏。
在keras中,冻结网络的方法就是将其trainable属性设为False。

微调模型

可以看到,最终我们仅使用2000张图片就使得验证成功率在97%左右。