使用keras进行二分类时,常使用binary_crossentropy作为损失函数。那么它的原理是什么,跟categorical_crossentropy、sparse_categorical_crossentropy有什么区别?在进行文本分类时,如何选择损失函数,有哪些优化损失函数的方式?本文将从原理到实现进行一一介绍。
binary_crossentropy
原理
假设我们想做一个二分类,输入有10个点:
x = [-2.2, -1.4, -0.8, 0.2, 0.4, 0.8, 1.2, 2.2, 2.9, 4.6]
输出有两类,分别为红色、绿色:
我们可以将问题描述成“这个点是绿色的吗?”,或者“这个点是绿色的概率是多少?”。理想情况下,绿点的概率是1.0,而红点的(是绿色的)概率是0.0。从而,绿色就是正样本,红色就是负样本。
如果我们拟合一个模型来执行这种分类,它将预测我们每个点的绿色概率。那么我们如何评估预测概率的好坏呢?这就是损失函数的意义,
Binary CrossEntorpy的计算如下:
其中y是标签(1代表绿色点,0代表红色点),p(y)是所有N个点都是绿色的预测概率。看到这个计算式,发现对于每一个绿点(y=1)它增加了log(p(y))的损失(概率越大,增加的越小),也就是它是绿色的概率。下面我们可视化地看一下这个损失函数。
假设我们训练一个逻辑回归模型来进行分类,那么训练出的函数趋近于一个sigmoid曲线,曲线上每个点表示对于每个x是绿色点的概率:
那么对于这些绿色的点,他们预测为绿色的概率是多少呢?实际下面图片中绿色的bar:
那么红色点预测为红色的概率是多少呢?实际就是下面图片中红色的bar:
我们把图片绘制得更好看一下,如下图:
因为我们要计算损失,我们需要惩罚错误的预测。如果与正例相关的概率是1.0,我们需要它的损失为零。相反,如果概率很低,比如0.01,我们需要它的损失是巨大的!取概率的(负)对数非常适合我们的目的(由于0.0和1.0之间的值的对数是负的,我们取负对数来获得正的损失值)。下面这个图展示了当正例的概率逐渐趋近于0时loss的变化:
下面这个图表示了,我们使用负对数时每个点的损失,我们计算其平均值,就是binary cross entropy了!
keras实现
tf2.1的bce用法如下:
bce = tf.keras.losses.BinaryCrossentropy()
loss = bce([0., 0., 1., 1.], [1., 1., 1., 0.])
print('Loss: ', loss.numpy()) # Loss: 11.522857
或者:
model = tf.keras.Model(inputs, outputs)
model.compile('sgd', loss=tf.keras.losses.BinaryCrossentropy())
具体实现如下(tensorflow.python.keras/losses):
class BinaryCrossentropy(LossFunctionWrapper):
def __init__(self, from_logits&