使用 ImageDataGenerator 进行数据增强

Posted

技术标签:

【中文标题】使用 ImageDataGenerator 进行数据增强【英文标题】:Data augmentation with ImageDataGenerator 【发布时间】:2022-01-21 14:39:11 【问题描述】:

关于 ImageDataGenerator。我的代码是

Train_Data,Test_Data = train_test_split(Main_Data,train_size=0.9,shuffle=True,random_state=42)
Train_Data.shape

Train_IMG_Generator = ImageDataGenerator(rescale=1./255,
                                    rotation_range=25,
                                    shear_range=0.5,
                                    zoom_range=0.5,
                                    width_shift_range=0.2,
                                    height_shift_range=0.2,
                                    horizontal_flip=True,
                                    fill_mode="nearest",
                                    validation_split=0.1)
Test_IMG_Generator = ImageDataGenerator(rescale=1./255)

train_set=Train_IMG_Generator.flow_from_dataframe(dataframe=Train_Data,
                                   x_col='png',
                                   y_col='cat',
                                   seed=42,
                                   color_mode='rgb',
                                   class_mode='categorical',
                                   target_size=(128,128),
                                   subset='training')
#prepare validation set
validation_set=Train_IMG_Generator.flow_from_dataframe(dataframe=Train_Data,
                                       x_col='png',
                                       y_col='cat',
                                       seed=42,
                                       color_mode='rgb',
                                       class_mode='categorical',
                                       target_size=(128,128),
                                       subset='validation')
Test_IMG_Set = Test_IMG_Generator.flow_from_dataframe(dataframe=Test_Data,
                                                   x_col="png",
                                                   y_col="cat",
                                                   color_mode="rgb",
                                                   class_mode="categorical",
                                                   target_size=(128,128),
                                                   shuffle=False)

这是数据扩充还是只是预处理?我得到任何新图像了吗?在调用 flow_from_dataframe 函数之前,我们在 Train_Data 向量中有 8083 张图像,在调用它之后,我认为图像的数量仍然是 8083。或者至少我们在生成训练集和验证集后得到这个输出。

"找到 7275 个经过验证的图像文件名,属于 3 个类别。 找到属于 3 个类的 808 个经过验证的图像文件名。”

总共是 8083 个。

我应该在哪里指定我想要的新图像的数量?

【问题讨论】:

【参考方案1】:

从某种意义上说,生成器会创建一个新图像,即对图像执行增强,并将该图像作为训练数据的一部分提供给模型。除非采取措施保存这些图像,否则这些图像不会被保存。下面是生成指定数量的增强图像并将它们以指定的前缀和指定的图像格式保存到指定目录的代码。我将假设一个数据框 df 存在并且有 2 列。文件名列包含图像文件的完整路径。标签列包含与图像关联的类名称。

import shutil
total = 0
img_size=(128,128)
aug_dir=r'c:\Temp\aug_images' # directory in which to save the images
num_desired = 10 # set to the number of images you want to save for EACH class
gen=ImageDataGenerator(rotation_range=25,
                       shear_range=0.5,
                       zoom_range=0.5,
                       width_shift_range=0.2,
                       height_shift_range=0.2,
                       horizontal_flip=True) # Notice did not rescale the images
if os.path.isdir(aug_dir):
        shutil.rmtree(aug_dir) # if the directory exists remove it
os.mkdir(aug_dir) # create an empty fresh aug_dir
class_groups=df.groupby('labels') #makes a dataframe for each unique label(class)
for label in df['labels'].unique():
    aug_count = 0
    dir_path=os.path.join(aug_dir,label)
    os.mkdir(dir_path) # in aug_dir make a sub directory for each class
    class_df=class_groups.get_group(label) #get dataframe for the label
    aug_gen=gen.flow_from_dataframe( class_df,
                                     x_col='filepaths',
                                     y_col=None, 
                                     target_size=img_size,
                                     class_mode=None, 
                                     batch_size=1, 
                                     shuffle=False, 
                                     save_to_dir=dir_path, 
                                     save_prefix='aug-', 
                                     color_mode='rgb',
                                     save_format='jpg') 
    while aug_count < num_desired:
        images=next(aug_gen)
        aug_count +=1
    total += aug_count
print ('Total augmented images generated = ', total)

当你运行它时,你会创建一个目录 c:\Temp\aug_dir。该目录将包含子目录,每个类一个。在这些子目录中的每一个中,都会有 10 个增强图像。每个图像文件都有前缀 aug- 和扩展名 jpg。图像将是 128 X 128 X 3。像素值将在 0 到 255 范围内。我没有缩放增强图像,因此如果将原始图像与增强图像组合为新的复合数据集,它们都具有相同的像素范围。现在您可以使用以下代码将增强图像与原始图像合并以创建复合数据集

filepaths=[]
labels=[]
classlist=os.listdir(aug_dir)
for klass in classlist:
    classpath= os.path.join(aug_dir, klass)
    flist=os.listdir(classpath)
    for f in flist:
        fpath=os.path.join(classpath,f)
        filepaths.append(fpath)
        labels.append(klass)
Fseries=pd.Series(filepaths, name='filepaths')
Lseries=pd.Series(labels, name='labels')
aug_df=pd.concat([Fseries, Lseries], axis=1)
composite_df=pd.concat([df, aug_df], axis=0).reset_index(drop=True)
print ('df length: ' , len(df), '  aug_df length: ', len(aug_df), '  length composite_df: ', len(composite_df))

现在您可以使用此复合数据集进行训练

【讨论】:

以上是关于使用 ImageDataGenerator 进行数据增强的主要内容,如果未能解决你的问题,请参考以下文章

使用 ImageDataGenerator 进行多类分割时训练 U-Net 的问题

如何从大型 .h5 数据集中批量读取数据,使用 ImageDataGenerator 和 model.fit 进行预处理,所有这些都不会耗尽内存?

Keras ImageDataGenerator 不处理符号链接文件

用于语义分割的 ImageDataGenerator

Keras - 如何在不改变纵横比的情况下使用 ImageDataGenerator

Keras `ImageDataGenerator` 图像和蒙版的增强方式不同