如何让ImageDataGenerator配合flow_from_dataframe输出随机图像补丁而非全图
实现方案
方法1:使用ImageDataGenerator的preprocessing_function参数(最简单)
ImageDataGenerator 支持传入自定义预处理函数,会在每张图片加载、完成内置预处理(如你配置的rescale)后自动调用,无需改动原有flow_from_dataframe的核心逻辑,完全兼容大数据集的流式加载需求。
import tensorflow as tf from tensorflow.keras.preprocessing.image import ImageDataGenerator # 自定义32x32随机裁剪函数 def random_crop_32x32(img): # 可选:如果存在小于32x32的图,先做padding避免裁剪报错 # img = tf.image.pad_to_bounding_box(img, 0, 0, max(32, tf.shape(img)[0]), max(32, tf.shape(img)[1])) # 随机裁剪32x32区域 cropped_img = tf.image.random_crop(img, size=(32, 32, tf.shape(img)[-1])) return cropped_img.numpy() # 给ImageDataGenerator加上预处理函数即可 datagen = ImageDataGenerator( rescale=1./255, preprocessing_function=random_crop_32x32 ) # 原有flow_from_dataframe逻辑几乎不用改,修正原示例的语法错误 train_gen=datagen.flow_from_dataframe( dataframe=train_df, x_col="filepath", class_mode="input", shuffle=True, seed=1 )
后续训练直接用train_gen即可,每次输出的就是32x32的随机裁剪块,内存占用和你原有流程完全一致。
方法2:用tf.data.Dataset包装生成器(更灵活,支持复杂逻辑)
如果需要对裁剪逻辑做更复杂的控制,比如单图裁多块、调整裁剪概率、并行加速处理,可以把flow_from_dataframe的输出转成tf数据集后做批量处理:
import tensorflow as tf from tensorflow.keras.preprocessing.image import ImageDataGenerator datagen = ImageDataGenerator( rescale=1./255 ) train_gen=datagen.flow_from_dataframe( dataframe=train_df, x_col="filepath", class_mode="input", shuffle=True, seed=1, batch_size=32 ) # 将生成器转为tf数据集 dataset = tf.data.Dataset.from_generator( lambda: train_gen, output_signature=( tf.TensorSpec(shape=(None, None, None, 3), dtype=tf.float32), # 输入图像shape,按实际通道数修改 tf.TensorSpec(shape=(None, None, None, 3), dtype=tf.float32) # class_mode为input时标签和输入一致 ) ) # 批量裁剪函数 def crop_batch(imgs, labels): cropped_imgs = tf.map_fn(lambda x: tf.image.random_crop(x, (32,32,3)), imgs, dtype=tf.float32) # 自编码器场景下标签也为裁剪后的图像 return cropped_imgs, cropped_imgs # 开启并行处理和预加载提升效率 train_dataset = dataset.map(crop_batch, num_parallel_calls=tf.data.AUTOTUNE).prefetch(tf.data.AUTOTUNE)
训练时直接把model.fit的输入替换为train_dataset即可。
内容的提问来源于stack exchange,提问作者P M
相关产品推荐
相关产品推荐

