【问题标题】:How do I combine tf.absolute and tf.square to create the Huber loss function in Tensorflow?如何结合 tf.absolute 和 tf.square 在 Tensorflow 中创建 Huber 损失函数?
【发布时间】:2016-08-23 16:48:58
【问题描述】:

准确地说,我要找的损失函数是绝对误差小于0.5时的平方误差,绝对误差大于0.5时是绝对误差本身。这样,误差函数的梯度不会超过 1,因为一旦平方误差函数的梯度达到 1,绝对误差函数就会启动,梯度保持恒定在 1。我在下面包含了我当前的实现.出于某种原因,它给我的性能比平方误差更差。

fn_choice_maker1 = (tf.to_int32(tf.sign(y - y_ + 0.5)) + 1)/2
fn_choice_maker2 = (tf.to_int32(tf.sign(y_ - y + 0.5)) + 1)/2
choice_maker_sqr = tf.to_float(tf.mul(fn_choice_maker1,   fn_choice_maker2))

sqr_contrib = tf.mul(choice_maker_sqr, tf.square(y - y_))
abs_contrib = tf.abs(y - y_)-0.25 - tf.mul(choice_maker_sqr, tf.abs(y - y_)-0.25)
loss = tf.reduce_mean(sqr_contrib + abs_contrib)
train_step = tf.train.AdamOptimizer(1e-4).minimize(loss)

choice_maker_sqr 是一个列张量,只要误差在 0.5 和 -0.5 之间,它就是一个。这些名称非常不言自明。

【问题讨论】:

  • 当你说“这让我的表现更差”时,你是在谈论跑一步的速度,还是你的模型的学习表现?前者是预期的,因为当您计算 Huber 损失与仅平方损失时,有更多的操作。如果是后者,那么您真的是在询问使用 Huber 损失解决您的问题的效果吗?在这种情况下,如果您包含更多模型的详细信息,可能会有所帮助。
  • 是后者。这是针对强化学习模型的,与this stack overflow question 相关。实际上,我更想知道我对 Huber 损失的实现是否有任何错误(在 tensorflow 中)。
  • tf.cond(tf.abs(y-y_) < 0.5, lambda: tf.square(y-y_), lambda: tf.abs(y-y_)) 将是描述的更直接的实现。
  • 您描述的函数在|error| = 0.5 处存在不连续性。正确的 Huber 损失应该是 tf.cond(tf.abs(error) < 0.5, lambda: tf.square(error), lambda: tf.abs(error) - 0.25)
  • 要为向量实现这个,你可以使用tf.where: tf.where(tf.abs(error) < 0.5, tf.square(error), tf.abs(error) - 0.25)

标签: neural-network tensorflow loss


【解决方案1】:

这是我在 python tensorflow 中对Huber loss function 的实现:

def huber_loss(y_true, y_pred, max_grad=1.):
    """Calculates the huber loss.

    Parameters
    ----------
    y_true: np.array, tf.Tensor
      Target value.
    y_pred: np.array, tf.Tensor
      Predicted value.
    max_grad: float, optional
      Positive floating point value. Represents the maximum possible
      gradient magnitude.

    Returns
    -------
    tf.Tensor
      The huber loss.
    """
    err = tf.abs(y_true - y_pred, name='abs')
    mg = tf.constant(max_grad, name='max_grad')
    lin = mg*(err-.5*mg)
    quad=.5*err*err
    return tf.where(err < mg, quad, lin)

【讨论】:

    【解决方案2】:

    您可以使用tf.select 在一次调用中实现它:

    err = y - y_
    huber_loss = tf.select(tf.abs(err) < 1.0,   
                           0.5 * tf.square(err), 
                           tf.abs(err) - 0.5) # if, then, else
    

    【讨论】:

      【解决方案3】:
      err = tf.subtract(x,y)
      huber_loss = tf.where(tf.less(x,y),   
                             tf.sqrt(tf.square(err)), 
                             tf.abs(err))
      with tf.Session() as sess:
          print(sess.run(tf.reduce_mean(huber_loss)))
      

      【讨论】:

      • 请提供详细的解释,方便用户日后理解。
      【解决方案4】:

      不确定这是否仍然相关,但我想向将来寻求此功能的人指出。 tensorflow 研究损失脚本有一个用于对象检测的 Huber 损失的实现(就像它在 FasterRCNN 论文中实现的那样)

      这是link to the method

      【讨论】:

        猜你喜欢
        • 2018-05-30
        • 1970-01-01
        • 2020-12-19
        • 2021-02-08
        • 2021-02-22
        • 2018-03-23
        • 2018-04-09
        • 2018-08-12
        • 1970-01-01
        相关资源
        最近更新 更多