深度学习 - 16.TF x Keras Losses 常见损失函数

36 篇文章 6 订阅
24 篇文章 11 订阅

一.引言:

之前提到过 自定义Loss与metrics,下面盘点下 Keras中常用的损失函数,当然也是日常生产开发中常用的损失函数供今后自定义损失函数使用。损失函数虽然有很多形式,但万变不离其宗,损失函数都是将随机事件例如回归,分类等问题的目标抽象为非负的实数从而衡量该事件的损失或风险,从而矫正模型,希望模型朝着损失最小的方向进行,但是这里只是大多数情况,例如一些图像结合算法中,也会最大化损失使得图像的表达更加多元化,抽象化。

二.常见损失函数

1. MAE 平均绝对误差 (mean-absolute error)

MAE(pre,y) = \frac{1}{n}\sum_{i=1}^{n}\left | pre^{(i)}-y^{(i)} \right |

pre为预测值,y为真实值,MAE为预测值与真实值差的绝对值之和

# Mean Ablsolutely Error
def getMaeLoss(predict, label):
    loss = tf.reduce_mean(tf.losses.mean_absolute_error(label, predict))
    return loss

模拟100个样本进行 Loss 计算,下述如无特殊声明默认使用该样本进行 Loss 计算。 

    numSamples = 100
    predict = np.random.randint(0, 2, size=(numSamples,)).astype('float32')
    label = np.random.randint(0, 2, size=(numSamples,)).astype('float32')

    maeLoss = getMaeLoss(predict, label).numpy()
    print("Mae Loss:", maeLoss)

2. MSE 均方误差 (mean-square error)

\fn_cm MSE(pre,y) = \frac{1}{n}\sum_{i=1}^{n}(pre^{(i)}-y^{(i)} )^2

pre为预测值,y为真实值,MSE为预测值与真实值差的平方之和,与MAE相同,不论 pre 比 y 高还是低于同一个数,计算得到的结果都是相同的。

# Mean Squared Error
def getMseLoss(predict, label):
    loss = tf.reduce_mean(tf.losses.mean_squared_error(label, predict))
    return loss

3. RMSE 均方根误差 (root-mean-square error)

RMSE(pre,y) = \sqrt{\frac{1}{n}\sum_{i=1}^{n}(pre^{(i)}-y^{(i)} )^2}

RMSE 其实和 MSE 表征大小没有区别,只不过是类似于方差和标准差的区别,如果预测目标为万元,则 MSE 的单位是万*万,而 RMSE 则是万,这里类似做一个标准化的过程。

# Root Mean Squared Error
def getRmseLoss(predict, label):
    loss = tf.sqrt(tf.reduce_mean(tf.losses.mean_squared_error(label, predict)))
    return loss

4. MAPE 平均绝对百分比误 (mean_absolute_percentage_error)

MAPE(pre,y) = \frac{1}{n}\sum_{i=1}^{n}\left \| \frac{y^{(i)}-pre^{(i)}}{y^{(i)}} \right \| \cdot 100%

MAPE 为0%表示完美模型,MAPE 大于 100 %则表示劣质模型。这里需要注意分母为0的情况。

# mean_absolute_percentage_error
def getMapeLoss(predict, label):
    loss = tf.reduce_mean(tf.losses.mean_absolute_percentage_error(label, predict))
    return loss

5. MSLE 均方对数误差 (mean_squared_logarithmic_error)

\fn_cm MSLE(pre,y) = \frac{1}{n}\sum_{i=1}^{n}(log(y^{(i)}+1)-log(pre^{(i)}+1))^2

# Mean Squared Logarithmic Error (MSLE)
def getMsleLoss(predict, label):
    loss = tf.reduce_mean(tf.losses.mean_squared_logarithmic_error(label, predict))
    return loss

(1) 可以看出来在均方根误差相同的情况下,预测值比真实值小这种情况的错误比较大,即对于预测值小这种情况惩罚较大。

(2) 当数据当中有少量的值和真实值差值较大的时候,使用log函数能够减少这些值对于整体误差的影响。

y = np.array([2.,3.,4.,5.,6.])
predict = y + 2
print("预测值大于真实值:",getMsleLoss(predict, y))
predict = y - 2
print("预测值小于真实值:",getMsleLoss(predict, y))
预测值大于真实值: tf.Tensor(0.13689565089565417, shape=(), dtype=float64)
预测值小于真实值: tf.Tensor(0.44519201856286134, shape=(), dtype=float64)
 

6. Cosine Similarity 余弦相似度

similarity=cos(\theta)=\frac{pre \cdot y}{\left \| pre \right \|\left \| y \right \|}=\frac{\sum_{i=1}^{n} pre_i \cdot y_i}{\sqrt{\sum_{i=1}^{n}(pre_i)^2}x\sum_{i=1}^{n}(y_i)^2}

余弦相似度一般通过夹角考虑两个向量在空间的相似度,比如常见的 User-embedding,Item-embedding 相关的相似性计算。

# Cosine Loss
def getCosLoss(predict, label):
    loss = tf.reduce_mean(tf.losses.cosine_similarity(label, predict))
    return loss

7. Binary Crossentropy 二值交叉熵

BinaryCrossentropy= -\frac{1}{n}\sum_{i=1}^{n} y_i \cdot log^{pre_i} + (i-y_i) \cdot log^{1-pre_i}

用于二值分类,IMDB 情感分析,性别预测等等都会用到。

# Binary Loss
def getBinaryLoss(predict, label):
    loss = tf.reduce_mean(tf.losses.binary_crossentropy(label, predict))
    return loss
    predict = utils.to_categorical(np.random.randint(0, 2, size=(numSamples,)).astype('int32'), num_classes=2)
    label = utils.to_categorical(np.random.randint(0, 2, size=(numSamples,)).astype('int32'), num_classes=2)

    binaryLoss = getBinaryLoss(predict, label).numpy()
    print("Binary Loss: ", binaryLoss)

8. Category Crossentropy 交叉熵

CategoryCrossentropy=-\sum_{i=1}^{n}y_i \cdot log^{pre_i}

用于多类别分析,最常见的手写数字识别就用了交叉熵损失函数,常与 softmax 函数结合使用。

# Category Loss
def getCategoryLoss(predict, label):
    loss = tf.reduce_mean(tf.losses.categorical_crossentropy(label, predict))
    return loss
    predict = utils.to_categorical(np.random.randint(0, 10, size=(numSamples,)).astype('int32'), num_classes=10)
    label = utils.to_categorical(np.random.randint(0, 10, size=(numSamples,)).astype('int32'), num_classes=10)

    categoryLoss = getCategoryLoss(predict, label).numpy()
    print("Category Loss: ", categoryLoss)

9. Kullback-Leibler divergence KL散度

\fn_cm D_{KL} (P||Q)= \sum_{i=1}^{n}p(x_i)logp(x_i)-p(x_i)logq(x_i)

这里信息熵定义为:

H = -\sum_{i=1}^{n}p(x)logp(x)

K-L散度在统计学中用于衡量两个分步的相似程度,这里P,Q可以看做是真实值与预测值。

# KL Loss
def getKLLoss(predict, label):
    loss = tf.reduce_mean(tf.losses.kullback_leibler_divergence(label, predict))
    return loss

10.Hinge Loss 合页损失 

Hinge = max(0, (1-y) \cdot pre)

Hinge Loss 又叫合页损失,因为它的函数图像和门的合页特别像,最常见的应用场景是 SVM 支持向量机。

# Hinge Loss
def getHingeLoss(predict, label):
    loss = tf.reduce_mean(tf.losses.hinge(label, predict))
    return loss
    predict = np.where(predict < 1, -1, 1).astype('float32')
    label = np.where(label < 1, -1, 1).astype('float32')
    hingeLoss = getHingeLoss(predict, label).numpy()
    print("Hinge Loss: ", hingeLoss)

11.Possion Loss 泊松损失

Possion = pre - y * log(pre)

参考官方 API 这里为了防止 pre 出现为0的情况,所以后面改写为 y * log(pre + epsilon()) ,其中 epsilon() =  1e-07 

# Possion Loss
def getPossionLoss(predict, label):
    loss = tf.reduce_mean(tf.losses.poisson(label, predict))
    return loss

12.Huber Loss 平滑平均绝对误差

Huber = \begin{cases} & \frac{1}{2} (y - pre)^2 \rightarrow |y-pre|\leq \delta \\ & \delta |y - pre| - \frac{1}{2}\delta ^2 \rightarrow other \end{cases}

Huber 顾名思义平滑绝对误差,其构造为分段函数,它介于 MAE 与 MSE 之间,平滑程度取决于 δ 的取值范围,当Huber损失在 [0-δ,0+δ] 区间内,等价为MSE,而在[-∞,δ]和[δ,+∞]时为MAE。所以 Huber 对数据中的异常点没有平方误差敏感。

# Huber Loss
def getHuberLoss(predict, label):
    loss = tf.reduce_mean(tf.losses.huber(label, predict))
    return loss

更多推荐算法相关深度学习:深度学习导读专栏 

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BIT_666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值