Keras损失函数与Metrics学习总结

1. 损失函数在Keras中的用法

损失函数(或称目标函数)是模型compile()是需要指定的参数之一。

指定方法有两种:

  1. 直接传递损失函数名
model.compile(loss='mean_squared_error', optimizer='sgd')
  1. 与optimizers类似,直接传递符号函数。 该符号函数为每个数据点返回一个标量,有以下两个参数:
    y_true: 真实标签。TensorFlow/Theano 张量。
    y_pred: 预测值。TensorFlow/Theano 张量,其 shape 与 y_true 相同。
    实际的优化目标是所有数据点的输出数组的平均值。
from keras import losses

model.compile(loss=losses.mean_squared_error, optimizer='sgd')

2. 回归损失函数

机器学习模型常见的损失函数主要分为两大类别, 即用于回归问题的损失函数分类问题的损失函数。下面首先介绍几种用于回归问题的损失函数:

2.1 均方差(Mean Squared Error, MSE)

均方差 Mean Squared Error (MSE) 损失是机器学习、深度学习回归任务中最常用的一种损失函数,也称为 L2 Loss。其基本形式如下:
Keras损失函数与Metrics学习总结
事实上,在模型输出与真实值的误差服从高斯分布的假设下,最小化均方差损失函数与极大似然估计本质上是一致的,因此在这个假设能被满足的场景中(比如回归),均方差损失是一个很好的损失函数选择;当这个假设没能被满足的场景中(比如分类),均方差损失不是一个好的选择。

Keras中的用法

model.compile(loss='mean_squared_error', optimizer ='sgd')

2.2 平均绝对误差()Mean Absolute Error,MAE)

平均绝对误差 Mean Absolute Error (MAE) 是另一类常用的损失函数,也称为 L1 Loss。其基本形式如下:
Keras损失函数与Metrics学习总结
模型预测与真实值之间的误差服从拉普拉斯分布 Laplace distribution,最小化平均绝对误差损失韩式与极大似然估计本质上是一致的

MAE与MSE区别
MAE 和 MSE 作为损失函数的主要区别是:MSE 损失相比 MAE 通常可以更快地收敛,但 MAE 损失对于 outlier 更加健壮,即更加不易受到 outlier 影响。

**MSE 通常比 MAE 可以更快地收敛。**当使用梯度下降算法时,MSE 损失的梯度为 [公式] ,而 MAE 损失的梯度为 [公式] ,即 MSE 的梯度的 scale 会随误差大小变化,而 MAE 的梯度的 scale 则一直保持为 1,即便在绝对误差 [公式] 很小的时候 MAE 的梯度 scale 也同样为 1,这实际上是非常不利于模型的训练的。当然你可以通过在训练过程中动态调整学习率缓解这个问题,但是总的来说,损失函数梯度之间的差异导致了 MSE 在大部分时候比 MAE 收敛地更快。这个也是 MSE 更为流行的原因。

MAE 对于 outlier 更加 robust
从两个损失函数的假设出发,MSE 假设了误差服从高斯分布,MAE 假设了误差服从拉普拉斯分布。拉普拉斯分布本身对于 outlier 更加 robust。

当右图右侧出现了 outliers 时,拉普拉斯分布相比高斯分布受到的影响要小很多。因此以拉普拉斯分布为假设的 MAE 对 outlier 比高斯分布为假设的 MSE 更加 robust。

Keras损失函数与Metrics学习总结

Keras中的用法

model.compile(loss='mean_absolute_error', optimizer='sgd')

2.3 Huber loss

上文我们分别介绍了 MSE 和 MAE 损失以及各自的优缺点,MSE 损失收敛快但容易受 outlier 影响,MAE 对 outlier 更加健壮但是收敛慢,Huber Loss 则是一种将 MSE 与 MAE 结合起来,取两者优点的损失函数,也被称作 Smooth Mean Absolute Error Loss 。其原理很简单,就是在误差接近 0 时使用 MSE,误差较大时使用 MAE,公式为:
Keras损失函数与Metrics学习总结
Huber Loss 结合了 MSE 和 MAE 损失,在误差接近 0 时使用 MSE,使损失函数可导并且梯度更加稳定;在误差较大时使用 MAE 可以降低 outlier 的影响,使训练对 outlier 更加健壮。缺点是需要额外地设置一个超参数。

Keras 中的用法

model.compile(loss='huber_loss', optimizer='sgd')

3. 分类损失函数

3.1 交叉熵损失函数(Cross Entropy Loss, CE)

上文介绍的几种损失函数都是适用于回归问题损失函数,对于分类问题,最常用的损失函数是交叉熵损失函数 Cross Entropy Loss。

Keras损失函数与Metrics学习总结

Keras损失函数与Metrics学习总结
Keras中的用法

model.compile(loss='categorical_crossentropy', optimizer='sgd')

当使用 categorical_crossentropy 损失时,你的目标值应该是分类格式 (即,如果你有 10 个类,每个样本的目标值应该是一个 10 维的向量,这个向量除了表示类别的那个索引为 1,其他均为 0)。

一般而言,在Keras中使用‘categorical_crossentropy’处理多分类问题,针对于二分类问题,有专门的’binary_crossentropy’

3.2 合页损失 (Hinge loss)

合页损失 Hinge Loss 是另外一种二分类损失函数,适用于 maximum-margin 的分类,支持向量机 Support Vector Machine (SVM) 模型的损失函数本质上就是 Hinge Loss + L2 正则化。合页损失的公式如下:
Keras损失函数与Metrics学习总结
Keras中的使用

model.compile(loss='hinge', optimizer='sgd')

4. 自定义损失函数

有些情况下需要自行定义损失函数训练模型。此时,我们可以通过编写一个返回标量并接受**两个参数(即真值y_true和预测值y_pred)**的函数,在 Keras 中创建一个自定义损失函数。然后,我们将自定义损失函数传递给 model.compile 作为参数,就像处理任何其他损失函数一样。

具体的定义形式如下:

def my_loss(y_true, y_pred)
    # y_true: 真实标签。TensorFlow/Theano 张量。
    # y_pred: 预测值,TensorFlow/Theano 张量,其 shape 与 y_true 相同。
    pass # 此处进行损失函数的具体定义,注意使用的是张量的运算操作,而不是numpy矩阵的运算规则。
    return value

5. 多输入多输出模型的损失函数定义

对于Keras函数式API定义的模型可为多输入多输出模型,此时需采用列表或者字典的方式为不同的输入输出组合指定不定损失函数,以及每个损失函数占总损失函数的百分比权重

示例:

# 定义的模型包含两个输入,两个输出
model = Model(inputs=[input_1, input_2], outputs=[output_1, output_2])
model.compile(optimizer='sgd',
              loss=['loss_fun1', 'l0ss_fun2'],
              loss_weights=[1., 0.2]
              )
# 最终的损失函数 = 1* loss_fun1(input_1, output_1) + 0.2 * loss_fun_2(input_2, output_2)

6. Metric

评价函数用于评估当前训练模型的性能。当模型编译后(compile),评价函数应该作为 metrics 的参数来输入。

与loss相似,可以通过两种方式设置metrics

model.compile(loss='mean_squared_error',
              optimizer='sgd',
              metrics=['mae', 'acc'])

from keras import metrics

model.compile(loss='mean_squared_error',
              optimizer='sgd',
              metrics=[metrics.mae, metrics.categorical_accuracy])

关于tf.keras提供的metrics非常多,具体可参见TensorFlow文档

这里介绍自定义评价函数:
自定义评价函数应该在编译的时候(compile)传递进去。该函数需要以 (y_true, y_pred) 作为输入参数,并返回一个张量作为输出结果。

import keras.backend as K

def mean_pred(y_true, y_pred):
    # y_true 为TensorFlow张量
    # y_pred 为与y_ture同形状的TensorFlow张量
    return K.mean(y_pred)

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy', mean_pred])

上一篇:ML之模型评价指标(损失函数):基于不同机器学习框架(sklearn/TF)下算法的模型评估函数(Scoring/metrics)集合(仅代码实现)


下一篇:高可用架构-熔断实现详解