【问题标题】:How does data normalization work in keras during prediction?在预测期间,数据规范化如何在 keras 中工作?
【发布时间】:2017-06-10 20:45:19
【问题描述】:

我看到 imageDataGenerator 允许我指定不同样式的数据规范化,例如featurewise_center、samplewise_center 等

我从示例中看到,如果我指定了这些选项之一,那么我需要在生成器上调用 fit 方法,以便让生成器计算像生成器上的平均图像这样的统计数据。

(X_train, y_train), (X_test, y_test) = cifar10.load_data()
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)

datagen = ImageDataGenerator(
    featurewise_center=True,
    featurewise_std_normalization=True,
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True)

# compute quantities required for featurewise normalization
# (std, mean, and principal components if ZCA whitening is applied)
datagen.fit(X_train)

# fits the model on batches with real-time data augmentation:
model.fit_generator(datagen.flow(X_train, Y_train, batch_size=32),
                samples_per_epoch=len(X_train), nb_epoch=nb_epoch)

我的问题是,如果我在训练期间指定了数据归一化,预测如何工作?我看不到在框架中我什至会如何传递训练集均值/标准偏差的知识来预测以允许我自己规范化我的测试数据,但我也没有在训练代码中看到这些信息在哪里存储。

标准化所需的图像统计信息是否存储在模型中,以便在预测期间使用?

【问题讨论】:

    标签: python machine-learning tensorflow neural-network keras


    【解决方案1】:

    是的 - 这是Keras.ImageDataGenerator 的一个非常大的缺点,您无法自己提供标准化统计信息。但是 - 有一个简单的方法可以解决这个问题。

    假设您有一个函数 normalize(x) 正在规范化图像 batch(请记住,生成器提供的不是简单图像而是图像数组 - batch形状为(nr_of_examples_in_batch, image_dims ..),您可以使用以下方法制作自己的标准化生成器:

    def gen_with_norm(gen, normalize):
        for x, y in gen:
            yield normalize(x), y
    

    那么你可以简单地使用gen_with_norm(datagen.flow, normalize) 而不是datagen.flow

    此外 - 您可以通过从 datagen 中的适当字段(例如 datagen.meandatagen.std)获取由 fit 方法计算的 meanstd

    【讨论】:

    • @MarcinMożejko 假设我从 imagedatagenerator 定义 train_datagen,其中 featurewise_center=True(加上增强)和 train_gen 作为 train_datagen.flow_from_directory。我对 test_datagen 和 test_gen 做同样的事情。你能告诉我如何在这种情况下适应你的方法吗?
    【解决方案2】:

    我也遇到了同样的问题,我使用 ImageDataGenerator 使用的相同功能解决了它:

    # Load Cifar-10 dataset
    (trainX, trainY), (testX, testY) = cifar10.load_data()
    generator = ImageDataGenerator(featurewise_center=True, 
                                   featurewise_std_normalization=True)
    
    # Calculate statistics on train dataset
    generator.fit(trainX)
    # Apply featurewise_center to test-data with statistics from train data
    testX -= generator.mean
    # Apply featurewise_std_normalization to test-data with statistics from train data
    testX /= (generator.std + K.epsilon())
    
    # Do your regular fitting
    model.fit_generator(..., validation_data=(testX, testY), ...)
    

    请注意,这只有在您拥有合理的小型数据集(例如 CIFAR-10)时才有可能。否则solution proposed by Marcin 听起来更合理。

    【讨论】:

      【解决方案3】:

      对每个元素使用生成器的standardize 方法。这是 CIFAR 10 的完整示例:

      #!/usr/bin/env python
      
      import keras
      from keras.datasets import cifar10
      from keras.preprocessing.image import ImageDataGenerator
      from keras.models import Sequential
      from keras.layers import Dense, Dropout, Flatten
      from keras.layers import Conv2D, MaxPooling2D
      
      # input image dimensions
      img_rows, img_cols, img_channels = 32, 32, 3
      num_classes = 10
      
      batch_size = 32
      epochs = 1
      
      # The data, shuffled and split between train and test sets:
      (x_train, y_train), (x_test, y_test) = cifar10.load_data()
      print(x_train.shape[0], 'train samples')
      print(x_test.shape[0], 'test samples')
      
      # Convert class vectors to binary class matrices.
      y_train = keras.utils.to_categorical(y_train, num_classes)
      y_test = keras.utils.to_categorical(y_test, num_classes)
      
      model = Sequential()
      
      model.add(Conv2D(32, (3, 3), padding='same', activation='relu',
                       input_shape=x_train.shape[1:]))
      model.add(Conv2D(32, (3, 3), activation='relu'))
      model.add(MaxPooling2D(pool_size=(2, 2)))
      model.add(Dropout(0.25))
      
      model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
      model.add(Conv2D(64, (3, 3), activation='relu'))
      model.add(MaxPooling2D(pool_size=(2, 2)))
      model.add(Dropout(0.25))
      
      model.add(Flatten())
      model.add(Dense(512, activation='relu'))
      model.add(Dropout(0.5))
      model.add(Dense(num_classes, activation='softmax'))
      
      model.compile(loss='categorical_crossentropy', optimizer='rmsprop',
                    metrics=['accuracy'])
      
      x_train = x_train.astype('float32')
      x_test = x_test.astype('float32')
      x_train /= 255
      x_test /= 255
      
      datagen = ImageDataGenerator(zca_whitening=True)
      
      # Compute principal components required for ZCA
      datagen.fit(x_train)
      
      # Apply normalization (ZCA and others)
      print(x_test.shape)
      for i in range(len(x_test)):
          # this is what you are looking for
          x_test[i] = datagen.standardize(x_test[i])
      print(x_test.shape)
      
      # Fit the model on the batches generated by datagen.flow().
      model.fit_generator(datagen.flow(x_train, y_train,
                                       batch_size=batch_size),
                          steps_per_epoch=x_train.shape[0] // batch_size,
                          epochs=epochs,
                          validation_data=(x_test, y_test))
      

      【讨论】:

      • 非常方便,可惜它不在 Keras 文档中。
      • 除以 255 不提供标准化吗?考虑到输入数据的像素值范围是 0 到 255。
      • 我试图这样做,但我的代码永远卡在datagen.fit(x_train),我认为存在一些维度问题,请参阅我的帖子stackoverflow.com/questions/59848525/…。你知道怎么回事吗?
      • 将 'rescale=1./255 ' 作为参数传递给 ImageDataGenerator 已经对数据进行了规范化
      【解决方案4】:

      我正在使用datagen.fit 函数本身。

      from keras.preprocessing.image import ImageDataGenerator
      
      train_datagen = ImageDataGenerator(
          featurewise_center=True,
          featurewise_std_normalization=True)
      train_datagen.fit(train_data)
      
      test_datagen = ImageDataGenerator(  
          featurewise_center=True, 
          featurewise_std_normalization=True)
      test_datagen.fit(train_data)
      

      理想情况下,安装在训练数据集上的test_datagen 将学习训练数据集的统计信息。然后它将使用这些统计数据来规范化测试数据。

      【讨论】:

      • 单张图片是怎么做的?
      猜你喜欢
      • 2022-11-24
      • 2015-08-25
      • 1970-01-01
      • 2019-09-19
      • 2015-11-26
      • 2020-03-15
      • 1970-01-01
      • 2017-07-25
      • 2015-12-29
      相关资源
      最近更新 更多