【问题标题】:Keras ImageDataGenerator setting mean and stdKeras ImageDataGenerator 设置均值和标准
【发布时间】:2019-04-18 21:27:21
【问题描述】:

我有一个预训练的 keras 模型,我想在新数据集上使用它。我有来自预训练模型的权重、平均值和标准文件,我想使用来自图像数据生成器的 flow_from_directory 来加载新数据集。问题是如何显式设置均值和标准文件以进行标准化?

谢谢

【问题讨论】:

    标签: python machine-learning keras


    【解决方案1】:

    我认为您可以使用 ImageDataGenerator 的 'featurewise_center' 和 'featurewise_std_normalization' 来处理它。参考:https://keras.io/preprocessing/image/#imagedatagenerator-class

    比如说,你的预训练数据集的平均 [R, G, B] 值为 [123.68, 116.779, 103.939],标准为 64.0。然后您可以使用下面的示例代码:(使用带有 TF 后端的 Keras 2,image_data_format='channels_last')

    from keras.preprocessing import image
    
    datagen = image.ImageDataGenerator(featurewise_center=True,
                                       featurewise_std_normalization=True)
    datagen.mean = np.array([123.68, 116.779, 103.939], dtype=np.float32).reshape((1,1,3)) # ordering: [R, G, B]
    datagen.std = 64.
    batches = datagen.flow_from_directory(DATASET_PATH + '/train',
                                          target_size=(224,224),
                                          color_mode='rgb',
                                          class_mode='categorical',
                                          shuffle=True,
                                          batch_size=BATCH_SIZE)
    

    【讨论】:

    • datagen.std 不也是 RGB 通道的 3 个元素的列表
    • 我认为这个答案已经过时,因为图像数据预处理 API 在最新版本的 Keras 中发生了变化。但如果你真的关心旧 API 的工作原理,可以在这里找到相关的源代码:github.com/keras-team/keras/blob/2.1.6/keras/preprocessing/…
    • 跟进上一条评论,datagen.std 可以是 3 个元素,也可以只有 1 个元素。 (x /= (self.std + K.epsilon()))
    【解决方案2】:

    我认为实现这一点的最佳方法是编写自己的方法来处理flow_from_directory 生成的样本。可能是这样的:

    def custom_normilze_generator(directory, mean):
        for img in flow_from_directory(directory):
            yield (img - mean)
    

    【讨论】:

      【解决方案3】:

      我最终使用自定义函子来计算、存储和检索统计信息:

      class Normaliser():
          def __init__(self, mean=None, std=None):
              self.mean = mean
              self.std = std
      
          def __call__(self, img):
              if self.mean is not None:
                  img = self.center(img)
              if self.std is not None:
                  img = self.scale(img)
              return img
      
          def center(self, img):
              return img - self.mean
      
          def scale(self, img):
              return img / self.std
      
          def normalise(self, img):
              return (img - self.mean) / self.std
      
          def set_mean(self, filepaths, input_size):
              print("Calculating mean with shape: ", input_size)
              self.mean = # calculate the mean
              print("Mean is:", self.mean)
              return True
      
          def set_std(self, filepaths):
              self.std = # calculate the std
              return False
      

      要使用它,给定输入大小 input_size,将 Normaliser 的一个实例传递给 ImageDataGenerator

      normaliser = Normaliser()
      img_gen = ImageDataGenerator(preprocessing_function=normaliser)                         
      

      使用 keras 预处理工具获取文件路径。我用flow_from_directory

      iterator = img_gen.flow_from_directory(directory, input_size=input_size)
      

      然后设置normaliser 的平均值

      normaliser.set_mean(iterator.filepaths, input_size)
      

      然后您可以按照自己的方式保存统计信息。 在预测阶段,您使用构造函数使用保存的平均值重新创建 Normaliser

      与直接使用 keras 生成器相比,它帮助我更灵活地处理我的数据,并且更清楚地知道我正在对其进行哪些修改,这不是一件小事。 samplwise_centerfeaturewise_center 并不是将图像标准化为 this discussion describes 的唯一方法

      【讨论】:

        猜你喜欢
        • 2021-07-03
        • 2019-02-08
        • 2017-04-25
        • 1970-01-01
        • 2020-12-26
        • 2020-04-15
        • 2019-05-29
        • 1970-01-01
        • 2021-09-06
        相关资源
        最近更新 更多