【问题标题】:What should be the Input types for Earth Mover Loss when images are rated in decimals from 0 to 9 (Keras, Tensorflow)当图像以 0 到 9 的小数进行评级时,Earth Mover Loss 的输入类型应该是什么(Keras,Tensorflow)
【发布时间】:2020-08-23 14:28:44
【问题描述】:

我正在尝试实施 Google 的 NIMA 研究论文,他们对图像质量进行了评级。我正在使用 TID2013 数据集。我有 3000 张图像,每张图像的分数从 0.00 到 9.00

df.head()
>>
Image Name          Score
0   I01_01_1.bmp    5.51429
1   i01_01_2.bmp    5.56757
2   i01_01_3.bmp    4.94444
3   i01_01_4.bmp    4.37838
4   i01_01_5.bmp    3.86486

找到下面给出的损失函数代码

def earth_mover_loss(y_true, y_pred):
    cdf_true = K.cumsum(y_true, axis=-1)
    cdf_pred = K.cumsum(y_pred, axis=-1)
    emd = K.sqrt(K.mean(K.square(cdf_true - cdf_pred), axis=-1))
    return K.mean(emd)

我将模型构建的代码编写为:

base_model = InceptionResNetV2(input_shape=(W,H, 3),include_top=False,pooling='avg',weights='imagenet')
for layer in base_model.layers: 
    layer.trainable = False

x = Dropout(0.45)(base_model.output)
out = Dense(10, activation='softmax')(x) # there are 10 classes

model = Model(base_model.input, out)
optimizer = Adam(lr=0.001)
model.compile(optimizer,loss=earth_mover_loss,)

问题: 当我使用ImageDataGenerator 时:

gen=ImageDataGenerator(validation_split=0.15,preprocessing_function=preprocess_input)

train = gen.flow_from_dataframe(df,TRAIN_PATH,x_col='Image Name',y_col='Score',subset='training',class_mode='sparse')

val = gen.flow_from_dataframe(df,TRAIN_PATH,x_col='Image Name',y_col='Score',subset='validation',class_mode='sparse')

它要么在训练期间给出错误,要么给出nan的损失值

我尝试了几种方法:

  1. 将分数创建为rounded = math.round(score) 并使用class_mode=sparse
  2. 将分数创建为str(rounded),然后使用class_mode=categorical

但我每次都有错误。

请帮助我使用 ImageDataGenerator 加载图像,了解我应该如何将图像加载到此模型中

模型结构不应改变。

【问题讨论】:

    标签: python tensorflow keras deep-learning image-recognition


    【解决方案1】:

    根据here 的介绍,我对NaN gradient 有一些想法...

    我认为您的损失是 nan,因为 sqrt 是根据不允许的负数计算的。所以有两种可能:

    • 在应用 sqrt 之前剪切值。通过这种方式,我们将所有值

      def earth_mover_loss(y_true, y_pred):
          cdf_true = K.clip(K.cumsum(y_true, axis=-1), 0,1)
          cdf_pred = K.clip(K.cumsum(y_pred, axis=-1), 0,1)
          emd = K.sqrt(K.maximum(K.mean(K.square(cdf_true - cdf_pred), axis=-1), K.epsilon()))
          return K.mean(emd)
      
    • 排除sqrt,这样Earth Mover Loss更类似于CDF之间的MSE

      def earth_mover_loss(y_true, y_pred):
          cdf_true = K.clip(K.cumsum(y_true, axis=-1), 0,1)
          cdf_pred = K.clip(K.cumsum(y_pred, axis=-1), 0,1)
          emd = K.mean(K.square(cdf_true - cdf_pred), axis=-1)
          return K.mean(emd)
      

    【讨论】:

      猜你喜欢
      • 2020-08-23
      • 2019-09-23
      • 1970-01-01
      • 1970-01-01
      • 2017-04-02
      • 2021-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多