Keras flowFromDirectory获取正在生成的文件名
keras
machine-learning
neural-network
python
5
0

是否可以获取使用flow_from_directory加载的文件名?我有 :

datagen = ImageDataGenerator(
    rotation_range=3,
#     featurewise_std_normalization=True,
    fill_mode='nearest',
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True
)

train_generator = datagen.flow_from_directory(
        path+'/train',
        target_size=(224, 224),
        batch_size=batch_size,)

我有一个用于多输出模型的自定义生成器,例如:

a = np.arange(8).reshape(2, 4)
# print(a)

print(train_generator.filenames)

def generate():
    while 1:
        x,y = train_generator.next()
        yield [x] ,[a,y]

目前,我正在为a随机数生成一个随机数,但为了进行实际训练,我希望加载一个json文件,其中包含图像的边界框坐标。为此,我需要获取使用train_generator.next()方法生成的文件名。我有,我可以加载文件,解析json ,并通过它,而不是ax变量的顺序和我得到的文件名列表也必须相同。

参考资料:
Stack Overflow
收藏
评论
共 3 个回答
高赞 时间 活跃

您可以通过继承DirectoryIterator来制作一个非常小的子类来返回image, file_path元组:

import numpy as np
from keras.preprocessing.image import ImageDataGenerator, DirectoryIterator

class ImageWithNames(DirectoryIterator):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.filenames_np = np.array(self.filepaths)
        self.class_mode = None # so that we only get the images back

    def _get_batches_of_transformed_samples(self, index_array):
        return (super()._get_batches_of_transformed_samples(index_array),
                self.filenames_np[index_array])

在初始化中,我添加了一个属性,它是self.filepaths的numpy版本,以便我们可以轻松地索引到该数组中,以获取每个批次生成的路径。

对基类的唯一其他更改是返回一个元组,该元组是图像批处理super()._get_batches_of_transformed_samples(index_array)和文件路径self.filenames_np[index_array]

这样,您可以使生成器如下所示:

imagegen = ImageDataGenerator()
datagen = ImageWithNames('/data/path', imagegen, target_size=(224,224))

然后检查

next(datagen)
收藏
评论

这是一个与shuffle=True一起使用的示例。并且还可以正确处理最后一批。要通过:

datagen = ImageDataGenerator().flow_from_directory(...)    
batches_per_epoch = datagen.samples // datagen.batch_size + (datagen.samples % datagen.batch_size > 0)
for i in range(batches_per_epoch):
    batch = next(datagen)
    current_index = ((datagen.batch_index-1) * datagen.batch_size)
    if current_index < 0:
        if datagen.samples % datagen.batch_size > 0:
            current_index = max(0,datagen.samples - datagen.samples % datagen.batch_size)
        else:
            current_index = max(0,datagen.samples - datagen.batch_size)
    index_array = datagen.index_array[current_index:current_index + datagen.batch_size].tolist()
    img_paths = [datagen.filepaths[idx] for idx in index_array]
    #batch[0] - x, batch[1] - y, img_paths - absolute path
收藏
评论

是的,至少在版本2.0.4中是可行的(不知道较早的版本)。

ImageDataGenerator().flow_from_directory(...)的实例具有带filenames的属性,该属性按生成器生成文件的顺序列出了所有文件,并且还具有batch_index属性。因此,您可以这样做:

datagen = ImageDataGenerator()
gen = datagen.flow_from_directory(...)

生成器上的每次迭代都可以得到相应的文件名,如下所示:

for i in gen:
    idx = (gen.batch_index - 1) * gen.batch_size
    print(gen.filenames[idx : idx + gen.batch_size])

这将为您提供当前批次中图像的文件名。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号