一.引言:
之前提到过 自定义Loss与metrics,下面盘点下 Keras中常用的损失函数,当然也是日常生产开发中常用的损失函数供今后自定义损失函数使用。损失函数虽然有很多形式,但万变不离其宗,损失函数都是将随机事件例如回归,分类等问题的目标抽象为非负的实数从而衡量该事件的损失或风险,从而矫正模型,希望模型朝着损失最小的方向进行,但是这里只是大多数情况,例如一些图像结合算法中,也会最大化损失使得图像的表达更加多元化,抽象化。
二.常见损失函数
1. MAE 平均绝对误差 (mean-absolute error)
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)
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 其实和 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 为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)
# 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 余弦相似度
余弦相似度一般通过夹角考虑两个向量在空间的相似度,比如常见的 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 二值交叉熵
用于二值分类,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 交叉熵
用于多类别分析,最常见的手写数字识别就用了交叉熵损失函数,常与 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散度
这里信息熵定义为:
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 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 泊松损失
参考官方 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 顾名思义平滑绝对误差,其构造为分段函数,它介于 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
更多推荐算法相关深度学习:深度学习导读专栏