前言
深度学习的一个基本特性就是能够独立地在训练数据中找到有趣的特征,无须人为的特征工程,而这只在拥有大量训练样本时才能实现。特别是对于输入样本的维度非常高(比如图像)的问题。
所谓“大量”样本是相对的,即相对于你所要训练网络的大小和深度而言。但如果模型很小, 并做了很好的正则化(提高范化能力),同时任务非常简单,那么几百个样本可能就足够了。在现实生活中,使用很少的数据来训练一个图像分类模型是很常见的情况。
但数据集太小很容易产生过拟合现象。文章将介绍解决数据集小这一问题的基本策略–数据增强,在少量数据上训练一个模型。
一、数据集
实验使用猫狗分类数据集,是由 Kaggle 在 2013 年末公开并作为一项计算视觉竞赛的一部分。获取数据集方法:
1.可以从kaggle官方网站 下载原始数据集,这个数据集包含 25 000 张猫狗图像(每个类别都有 12 500 张);
2.或者在此资源链接 下载已经划分好的小数据集:提取码:W28D
数据集中包含 4000 张猫和狗的图像(猫狗各一半)。将 2000 张图像用于训练,1000 张用于验证,1000张用于测试。
二、训练一个基准模型
首先,在 2000 个训练样本上训练一个简单的小型卷积神经网络,不做任何正则化,为模型目标设定一个基准。
1.获取数据集目录
base_dir = './data/cats_and_dogs_small'#保存小数据集的目录
#分别对应划分后的训练、 验证和测试的目录
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')
test_dir = os.path.join(base_dir, 'test')
# (猫的训练图像目录)
train_cats_dir = os.path.join(train_dir, 'cats')
# (狗的训练图像目录)
train_dogs_dir = os.path.join(train_dir, 'dogs')
#(猫的验证图像目录)
validation_cats_dir = os.path.join(validation_dir, 'cats')
# (狗的验证图像目录)
validation_dogs_dir = os.path.join(validation_dir, 'dogs')
#(猫的测试图像目录)
test_cats_dir = os.path.join(test_dir, 'cats')
# (狗的测试图像目录)
test_dogs_dir = os.path.join(test_dir, 'dogs')
每个分组中两个类别的样本数相同,这是一个平衡的二分类问题,分类精度可作为衡量成功的指标。
2.构建网络
卷积神经网络由 Conv2D 层(使用 relu 激活)和 MaxPooling2D 层交替堆叠构成。
由于这里要处理的是大的图像和更复杂的问题,需要使用较大的网络,使用二 个 Conv2D+MaxPooling2D 的组合。这既可以增大网络容量,也可以进一步减小特征图的尺寸, 使其在连接 Flatten 层时尺寸不会太大。因为面对的是一个二分类问题,所以网络最后一层是使用 sigmoid 激活的单一单元(大小为1 的 Dense 层)。这个单元将对某个类别的概率进行编码。
from tensorflow.keras import layers
from tensorflow.keras import models
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu',
input_shape=(150, 150, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(512