• 主页
  • 我的文章
    • 按归档标签分类
    • 按发布时间分类
  • 关于我
    • 万花侠客 photo

      万花侠客

      侠肝义胆,执剑走天涯。我,总要在这个江湖中留下些什么!

    • 了解我更多
    • 我的简书
    • Github
    • Twitter
    • Facebook
  • 我的项目

02_深度学习之损失函数

02 Apr 2019

Reading time ~1 minute

损失函数

smooth L1 loss 损失函数

假设有这么一个需求:

$x = a -b $ ,b是固定值,a 是可变值。我们希望一点一点调节 a 的值,使得 a 的值趋于 b 的值,最好是 a = b。比如,b的值恒为1.23,a 的初始值为100,假设 a 的值每次只能做自减1的计算,即 a = a - 1 。减很多次以后,a=2,然后再减一次,a = 1。显然,a 无法等于 1.23。因为,每次减1,是不能使a=1.23的。那每次只减小0.01就好了,可以使a = 1.23。这样做确实可以,但要计算的次数太多了。我们自然想到:

当差值 x 比较大时,也就是 a 和 b 的差距还很大时,a 减去一个比较大的值,这样收敛得快一些。等到 a 和 b比较接近时,a 减去一个比较小的值,这时虽然收敛得慢点,但可以有效得靠近 b。

smooth_l1_loss 函数公式如下: \(smooth_{L1}(x) = \begin{cases} 0.5x^2 &\text{if } | x | < 1 \\ | x | - 0.5 &\text{otherwise } \end{cases}\) 对 $x$ 进行求导: \(\frac{d smooth_{L1}}{dx} = \begin{cases} -1 &\text{if} &{x < -1} \\ x &\text{if } &{| x | \le 1} \\ 1 &\text{if } &{x > 1} \end{cases}\) 从中,可以看出,$ x $ 的绝对值小于1时,缓慢变化,大于1时,步长变为1。下面是演示代码:

import tensorflow as tf
import tensorflow.python.keras.backend as K

def smooth_l1_loss(y_true, y_pred):
    """smooth L1 loss 函数。"""
    diff = K.abs(y_true - y_pred)
    less_than_one = K.cast(K.less(diff, 1.0), "float32")
    loss = (less_than_one * 0.5 * diff**2) + (1 - less_than_one) * (diff - 0.5)
    return loss

# 真实值,固定不变,也就是上面说明中的b
y_true = tf.constant([1], dtype=tf.float32)
# 预测值,不断调整,也就是上面说明中的a
y_pred = tf.constant([11], dtype=tf.float32)
# 计算smooth L1 loss
loss = smooth_l1_loss(y_true, y_pred)
print(loss)

打印结果如下:

tf.Tensor([9.5], shape=(1,), dtype=float32)

smooth L1 loss 函数,解决的是L1范数和L2范数遇到的问题。当 $x$ 是一个数时(不是向量),L1范数公式如下(其实就是取绝对值): \(L1(x) = | x |\) L2范数公式如下(其实就是平方之后开方的值): \(L2(x) = \sqrt{x^2}\)



02_深度学习 Share Tweet +1