【发布时间】:2020-06-30 16:40:05
【问题描述】:
如何将我的图像数据集随机拆分为训练和验证日期集?更具体地说,Keras ImageDataGenerator 函数中的 validation_split 参数不会将我的图像随机拆分为训练和验证,而是从未打乱的数据集中分割验证样本。
【问题讨论】:
标签: python validation tensorflow keras training-data
如何将我的图像数据集随机拆分为训练和验证日期集?更具体地说,Keras ImageDataGenerator 函数中的 validation_split 参数不会将我的图像随机拆分为训练和验证,而是从未打乱的数据集中分割验证样本。
【问题讨论】:
标签: python validation tensorflow keras training-data
当在 Keras 的 ImageDataGenerator 中指定 validation_split 参数时,会在数据混洗之前执行拆分,以便仅获取最后 x 个样本。问题是最后一个被选为验证的数据样本可能不能代表训练数据,因此它可能会失败。当您的图像数据存储在一个公共目录中,每个子文件夹都由类命名时,这是一个特别常见的死胡同。已在多个帖子中指出:
Choose random validation data set
正如你所提到的,Keras 只是取数据集的最后 x 个样本,所以如果你想继续使用它,你需要提前打乱你的数据集。
The training accuracy is very high, while the validation accuracy is very low?
请检查您是否在训练前对数据进行了混洗。因为 keras 中的验证拆分是在 shuffle 之前进行的,所以可能你选择了一个不平衡的数据集作为验证集,因此你得到的准确率很低。
Does 'validation split' randomly choose validation sample?
选择验证数据作为输入的最后 10%(例如,如果 validation_split=0.9)。可以选择在每个时期对训练数据(剩余部分)进行洗牌(适合的洗牌参数)。这不会影响验证数据,显然,它必须从一个时期到另一个时期是相同的。
This answer 指向 sklearn train_test_split() 作为解决方案,但我想提出一个不同的解决方案,以保持 keras 工作流程的一致性。
使用split-folders 包,您可以将主数据目录随机拆分为训练、验证和测试(或只是训练和验证)目录。特定类的子文件夹会自动复制。
输入文件夹应具有以下格式:
input/
class1/
img1.jpg
img2.jpg
...
class2/
imgWhatever.jpg
...
...
为了给你这个:
output/
train/
class1/
img1.jpg
...
class2/
imga.jpg
...
val/
class1/
img2.jpg
...
class2/
imgb.jpg
...
test/ # optional
class1/
img3.jpg
...
class2/
imgc.jpg
...
来自文档:
import split_folders
# Split with a ratio.
# To only split into training and validation set, set a tuple to `ratio`, i.e, `(.8, .2)`.
split_folders.ratio('input_folder', output="output", seed=1337, ratio=(.8, .1, .1)) # default values
# Split val/test with a fixed number of items e.g. 100 for each set.
# To only split into training and validation set, use a single number to `fixed`, i.e., `10`.
split_folders.fixed('input_folder', output="output", seed=1337, fixed=(100, 100), oversample=False) # default values
通过这种新的文件夹排列,您可以轻松地使用 keras 数据生成器将您的数据划分为训练和验证,并最终训练您的模型。
import tensorflow as tf
import split_folders
import os
main_dir = '/Volumes/WMEL/Independent Research Project/Data/test_train/Data'
output_dir = '/Volumes/WMEL/Independent Research Project/Data/test_train/output'
split_folders.ratio(main_dir, output=output_dir, seed=1337, ratio=(.7, .3))
train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(
rescale=1./224)
train_generator = train_datagen.flow_from_directory(os.path.join(output_dir,'train'),
class_mode='categorical',
batch_size=32,
target_size=(224,224),
shuffle=True)
validation_generator = train_datagen.flow_from_directory(os.path.join(output_dir,'val'),
target_size=(224, 224),
batch_size=32,
class_mode='categorical',
shuffle=True) # set as validation data
base_model = tf.keras.applications.ResNet50V2(
input_shape=IMG_SHAPE,
include_top=False,
weights=None)
maxpool_layer = tf.keras.layers.GlobalMaxPooling2D()
prediction_layer = tf.keras.layers.Dense(4, activation='softmax')
model = tf.keras.Sequential([
base_model,
maxpool_layer,
prediction_layer
])
opt = tf.keras.optimizers.Adam(lr=0.004)
model.compile(optimizer=opt,
loss=tf.keras.losses.CategoricalCrossentropy(),
metrics=['accuracy'])
model.fit(
train_generator,
steps_per_epoch = train_generator.samples // 32,
validation_data = validation_generator,
validation_steps = validation_generator.samples // 32,
epochs = 20)
【讨论】: