众所周知,分类问题的常规评估指标是正确率,而标准的损失函数则是交叉熵,交叉熵有着收敛快的优点,但它并非是正确率的光滑近似,这就带来了训练和预测的不一致性问题。另一方面,当训练样本的预测概率很低时,交叉熵会给出一个非常巨大的损失(趋于log0+=),这意味着交叉熵会特别关注预测概率低的样本——哪怕这个样本可能是“脏数据”。所以,交叉熵训练出来的模型往往有过度自信现象,即每个样本都给出较高的预测概率,这会带来两个副作用:一是对脏数据的过度拟合带来的效果下降,二是预测的概率值无法作为不确定性的良好指标。

围绕交叉熵的改进,学术界一直都有持续输出,目前这方面的研究仍处于“八仙过海,各显神通”的状态,没有标准答案。在这篇文章中,我们来学习一下论文《Tailoring Language Generation Models under Total Variation Distance》给出的该问题的又一种简明的候选方案。

结果简介 #

顾名思义,原论文的改动是针对文本生成任务的,理论基础是Total Variation距离(参考《Designing GANs:又一个GAN生产车间》)。但事实上,经过原论文的一系列放缩和简化后,最终结果已经跟Total Variation距离没有明显联系,并且理论上也不限于文本生成任务。所以,本文将它作为一般分类任务的损失函数来看待。

对于数据对(x,y),交叉熵给出的损失函数为
logpθ(y|x)
原论文的改动很简单,改为
log[γ+(1γ)pθ(y|x)]1γ
其中γ[0,1]。当γ=0时,就是普通的交叉熵;当γ=1时,按极限来算,结果是pθ(y|x)

在原论文的实验中,不同任务的γ选取差别比较大,比如语言模型任务中取到了γ=107,机器翻译任务中取了γ=0.1,文本摘要任务中取了γ=0.8。一个可以参考的规律是,如果是从零训练,那么需要选择比较接近于0的γ,如果是微调训练,那么可以考虑相对大一点的γ。此外,还有一种比较直观的方案,就是将γ视为动态参数,从γ=0开始,随着训练的推进慢慢转向γ=1,但这样就多了个schedule要调试。

效果上,由于多了个可调的γ参数,并且原本的交叉熵也包含在里边,所以只要用心去调,一般总有机会调出比交叉熵更好的结果的,这个倒不用太担心。

个人推导 #

怎么理解式(2)呢?在《函数光滑化杂谈:不可导函数的可导逼近》中的“正确率”一节,我们推导过正确率的光滑近似是
E(x,y)D[pθ(y|x)]
所以,如果我们的评估指标是正确率,那么直觉上以pθ(y|x)为损失函数才对,因为这时候损失函数跟正确率的变化更加同步。然而,事实上是交叉熵的表现往往更好。但交叉熵的出发点只是“更好训练”,所以有时候就会“训过头”了,导致过拟合。所以一个直观的想法就是能否将两个结果“插值”一下,以兼顾两者的优点。

为此,我们考虑两者的梯度【准确率指的是它的负光滑近似pθ(y|x)】:
准确率:θpθ(y|x)交叉熵:1pθ(y|x)θpθ(y|x)
两者就差个1pθ(y|x)。怎么把1pθ(y|x)变为1呢?原论文的方案是:
1γ+(1γ)pθ(y|x)
当然这个构造方式不是唯一的,原论文选的这个方式,尽可能地保留了交叉熵的梯度特性,也就尽可能保留了交叉熵收敛快的特点。根据这个构造,我们就希望新损失函数的梯度为
θpθ(y|x)γ+(1γ)pθ(y|x)=θ(log[γ+(1γ)pθ(y|x)]1γ)
这就找出了损失函数(2),在这个过程中,我们先设计新的梯度,然后通过积分找原函数的方式找到了对应的损失函数。

多扯几句 #

为什么要从梯度角度去设计损失函数呢?大概有两方面的原因。

第一,很多损失函数求了梯度后会得到简化,所以在梯度空间设计,往往有更多的灵感和自由度,比如本文的例子中,在梯度空间设计1pθ(y|x)1的过渡函数1γ+(1γ)pθ(y|x)不算太复杂,但如果直接在损失函数空间设计pθ(y|x)logpθ(y|x)的过渡函数log[γ+(1γ)pθ(y|x)]1γ就复杂多了。

第二,目前使用的优化器都是基于梯度的,所以很多时候我们设计好梯度就行了,甚至都不必要找出原函数。论文的原始结果实际上就是只给出了梯度:
max
b=0时,它就等价于式\eqref{eq:gamma-ce}。也就是说,原论文在设计梯度的时候还加了个阈值,这时候就很难写出简单的原函数了。但上式实现上并不困难,只要考虑损失函数
\begin{equation}-\max\left(b, \frac{p_{\theta}(y|x)}{\gamma + (1 - \gamma)p_{\theta}(y|x)}\right)_{\text{stop_grad}}\log p_{\theta}(y|x)\end{equation}
这里边的\text{stop_grad}就是直接断掉这部分结果的梯度,在tensorflow中对应着tf.stop_gradient算子。

文章小结 #

本文主要介绍了缓解交叉熵过度自信的一个简明方案。

转载到请包括本文地址:https://spaces.ac.cn/archives/9526

更详细的转载事宜请参考:《科学空间FAQ》

如果您还有什么疑惑或建议,欢迎在下方评论区继续讨论。

如果您觉得本文还不错,欢迎分享/打赏本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!

如果您需要引用本文,请参考:

苏剑林. (Mar. 14, 2023). 《缓解交叉熵过度自信的一个简明方案 》[Blog post]. Retrieved from https://spaces.ac.cn/archives/9526

@online{kexuefm-9526,
        title={缓解交叉熵过度自信的一个简明方案},
        author={苏剑林},
        year={2023},
        month={Mar},
        url={\url{https://spaces.ac.cn/archives/9526}},
}