【问题标题】:keras: Smooth L1 losskeras:平滑 L1 损失
【发布时间】:2017-10-23 04:10:50
【问题描述】:

尝试在 keras 中自定义损失函数(平滑 L1 损失),如下所示

ValueError:形状必须为 0 级,但对于 'cond/Switch'(操作:'Switch')为 5 级,输入形状为:[?,24,24,24,?], [?,24,24, 24,?]。

from keras import backend as K
import numpy as np


def smooth_L1_loss(y_true, y_pred):
    THRESHOLD = K.variable(1.0)
    mae = K.abs(y_true-y_pred)
    flag = K.greater(mae, THRESHOLD)
    loss = K.mean(K.switch(flag, (mae - 0.5), K.pow(mae, 2)), axis=-1)
    return loss

【问题讨论】:

    标签: deep-learning keras loss-function


    【解决方案1】:

    我知道我迟到了两年,但如果你使用 tensorflow 作为 keras 后端,你可以像这样使用 tensorflow 的Huber loss(基本相同):

    import tensorflow as tf
    
    
    def smooth_L1_loss(y_true, y_pred):
        return tf.losses.huber_loss(y_true, y_pred)
    

    【讨论】:

      【解决方案2】:
      def smoothL1(y_true, y_pred):
          x = K.abs(y_true - y_pred)
          if K._BACKEND == 'tensorflow':
              import tensorflow as tf
              x = tf.where(x < HUBER_DELTA, 0.5 * x ** 2, HUBER_DELTA * (x - 0.5 * HUBER_DELTA))
              return  K.sum(x)
      

      【讨论】:

      • 如果后端是 Tensorflow,你应该使用 tf.where 而不是 K.switch
      【解决方案3】:

      这是使用 keras.backend 实现 Smooth L1 loss:

      HUBER_DELTA = 0.5
      def smoothL1(y_true, y_pred):
         x   = K.abs(y_true - y_pred)
         x   = K.switch(x < HUBER_DELTA, 0.5 * x ** 2, HUBER_DELTA * (x - 0.5 * HUBER_DELTA))
         return  K.sum(x)
      

      【讨论】:

      • 非常感谢。但我仍然收到错误:ValueError: Shape must be rank 0 but is rank 5 for 'cond/Switch' (op: 'Switch') with input shapes: [?,24,24,24,?], [?,24,24,24,?].
      • @yuanzhou 这意味着网络输出或您的目标有错误/不兼容的形状。
      • 对不起,我认为不是输出和目标形状的问题,当我使用其他损失函数时,它工作正常。仅使用自定义的 smoothL1 时发生错误。
      猜你喜欢
      • 2020-10-05
      • 1970-01-01
      • 2019-01-29
      • 2020-02-11
      • 2022-01-18
      • 2019-11-28
      • 2022-10-19
      • 2018-07-08
      • 2019-04-02
      相关资源
      最近更新 更多