6

准确地说,我要找的损失函数是绝对误差小于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 之间,它就是一个。这些名称非常不言自明。

4

4 回答 4

5

这是我在 python tensorflow 中实现Huber 损失函数:

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)
于 2017-03-23T19:48:15.880 回答
1
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)))
于 2017-07-04T09:15:56.943 回答
1

You can use tf.select to implement it in a single call:

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
于 2017-06-01T09:30:44.463 回答
0

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

这是该方法的链接

于 2018-05-31T12:33:14.823 回答