【问题标题】:How do I check the order in which Keras' flow_from_directory method processes folders?如何检查 Keras 的 flow_from_directory 方法处理文件夹的顺序?
【发布时间】:2017-03-18 00:18:15
【问题描述】:

在进行迁移学习时,我首先通过 VGG16 网络的底层输入图像。我正在使用生成器函数。

datagen = ImageDataGenerator(1./255)
generator = datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size = 32,
    class_mode=None,
    shuffle=False
)
model.predict_generator(generator, nb_train_samples)

我将类模式设置为无,因为我只想要数据输出。我设置了 shuffle = false,因为我想稍后在这里输入预测的特征,并将它们与 ground truth 类别变量匹配:

train_data = np.lead(open(file_name, 'rb'))
train_labels = np.array([0] * NUMBER_OF_ITEMS_FOR_ITEM1 +
                        [1] * NUMBER_OF_ITEMS_FOR_ITEM2 +...
                        [n-1] * NUMBER_OF_ITEMS_FOR_ITEMN

这里的问题是我不知道文件的读取顺序。我怎样才能找到它?甚至更好的是,我怎样才能避免不得不猜测正确的顺序?我之所以这么问,是因为我几乎可以肯定,低预测准确度与标签不匹配有关。

【问题讨论】:

    标签: python deep-learning keras


    【解决方案1】:

    我查看了source code。我应该注意,自从我发布这个问题以来,Keras 已更新到 2.0 版。所以答案是基于那个版本的。

    ImageDataGenerator 继承自 DirectoryGenerator。在其中,我发现以下几行:

        if not classes:
            classes = []
            for subdir in sorted(os.listdir(directory)):
                if os.path.isdir(os.path.join(directory, subdir)):
                    classes.append(subdir)
        self.num_class = len(classes)
        self.class_indices = dict(zip(classes, range(len(classes))))
    
        def _recursive_list(subpath):
            return sorted(os.walk(subpath, followlinks=follow_links), key=lambda tpl: tpl[0])
    
        for subdir in classes:
            subpath = os.path.join(directory, subdir)
            for root, _, files in _recursive_list(subpath):
                for fname in files:
                    is_valid = False
                    for extension in white_list_formats:
                        if fname.lower().endswith('.' + extension):
                            is_valid = True
                            break
                    if is_valid:
                        self.samples += 1
        print('Found %d images belonging to %d classes.' % (self.samples, self.num_class))
    

    注意第 3 行,其中显示“排序(os.listdir(目录,子目录))”。生成器按字母顺序遍历所有文件夹。

    稍后 _recursive_list 的定义也对子结构使用相同的逻辑。

    所以答案是:文件夹按字母顺序处理,这在某种程度上是有意义的。

    【讨论】:

      【解决方案2】:

      好问题,在DirectoryIterator 类中的next 方法中的keras/preprocessing/image.py 中添加一个print 语句:这是迭代文件名列表的相关代码。你当然必须从源代码重建keras

      for i, j in enumerate(index_array):
         fname = self.filenames[j]
         print(fname) # add this to see the current file being accessed
      
         img = load_img(os.path.join(self.directory, fname),
                        grayscale=grayscale,
                        target_size=self.target_size)
         x = img_to_array(img, data_format=self.data_format)
         x = self.image_data_generator.random_transform(x)
      

      然而,为了避免所有这些痛苦,keras docs 页面上的这个示例建议为了确保一致性,应该遵循这种模式。 将同一模板的 train 和 validate 生成器传递给 model.fit_generator 函数。

      train_datagen = ImageDataGenerator(
              rescale=1./255,
              shear_range=0.2,
              zoom_range=0.2,
              horizontal_flip=True)
      
      test_datagen = ImageDataGenerator(rescale=1./255)
      
      train_generator = train_datagen.flow_from_directory(
              'data/train',
              target_size=(150, 150),
              batch_size=32,
              class_mode='binary')
      
      validation_generator = test_datagen.flow_from_directory(
              'data/validation',
              target_size=(150, 150),
              batch_size=32,
              class_mode='binary')
      
      model.fit_generator(
              train_generator,
              samples_per_epoch=2000,
              epochs=50,
              validation_data=validation_generator,
              num_val_samples=800)
      

      【讨论】:

      • 谢谢你,puttonspectacles。我现在在我的一台笔记本电脑上运行上面的代码。我开始走这条路的原因是我无法弄清楚如何将上面的代码与 K-fold 交叉验证一起使用。上面的代码假设我有一个包含验证文件的文件夹。有什么想法吗?
      • 嗯不是真的@Thornhale,在我的模型中,我接受验证指标作为模型泛化的良好近似。并且对于每个模型的训练时间长度而言,交叉验证对于深度学习模型来说是令人望而却步的。
      • 如果您的模型训练速度足够快,您可以将数据拆分到多个目录中,并且可以使用 fit 方法而不是 flow_from_directory 并使用来自 sklearn 的 KStratified循环读取您读入的数据。
      • 如果您必须从磁盘读取数据:您可以尝试将数据拆分到多个目录中。并对目录进行循环。
      • 迁移学习案例怎么样,我首先将我的数据通过卷积网络而不是密集的顶层 - 只有一次。然后将输出存储在没有标签的情况下。下次我在本教程中训练顶层时不再读取原始文件(这就是我必须以某种方式重新生成标签的原因):blog.keras.io/…
      猜你喜欢
      • 2017-06-26
      • 2017-09-05
      • 1970-01-01
      • 2020-03-11
      • 2016-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-01
      相关资源
      最近更新 更多