对于二值图像分类问题(使用 tf.keras 的 CNN)。我的图像数据被分成文件夹(训练、验证、测试),每个文件夹都有两个平衡类的子文件夹。借用本教程中的代码,我最初以这种方式加载我的训练和验证集:
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
train_path,
validation_split=0.2,
subset="training",
seed=42,
image_size=image_size,
batch_size=batch_size,
)
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
train_path,
validation_split=0.2,
subset="validation",
seed=42,
image_size=image_size,
batch_size=batch_size,
)
请注意,我从同一个文件夹加载训练和验证,然后使用validation_split(因为我想在使用真正的验证集之前先玩一下)。我的模型表现非常好,验证准确度约为 0.95。
然后我决定更新我的代码以加载真正的验证集:
train_ds = image_dataset_from_directory(
train_path,
seed=42,
image_size=image_size,
batch_size=batch_size,
)
val_ds = image_dataset_from_directory(
val_path,
seed=42,
image_size=image_size,
batch_size=batch_size,
)
现在我的模型表现得更差了(~0.75 准确度)。我试图理解为什么。我怀疑我的初始代码导致了一些数据泄漏。现在我看了一下,我不知道第二次调用 image_dataset_from_directory(对于 val_ds)如何知道不加载已经为第一次调用(对于 train_ds)加载的图像(除非具有相同的随机种子可以防止这种情况)。我可以肯定这是问题所在,除了我直接从 keras.io 教程中提取了这段代码——他们肯定不会犯这样的基本错误吗?
主要问题:鉴于validation_split与subset交互的方式,image_dataset_from_directory()我的代码的第一个版本是否会导致数据泄漏?
如果它不应该导致训练集和验证集之间的数据泄漏,那么我将需要考虑其他可能性,例如:
- 训练集和验证集文件夹中的图像之间存在实际差异。我可以合并并重新洗牌。
- 训练文件夹中图像的顺序是这样的,即给定我的随机种子“更容易”的图像被提取用于验证集。