一种更简洁的方式来理解分类损失函数的推导以及在 PyTorch 中何时/如何应用它们
https://medium.com/@rtdcunha?source=post_page---byline--cb75a3b03237--------------------------------https://towardsdatascience.com/?source=post_page---byline--cb75a3b03237-------------------------------- Ryan D’Cunha
·发布于 Towards Data Science ·阅读时间:9 分钟·2024 年 6 月 27 日
–
来源:GPT4o 生成
无论你是刚开始探索神经网络的新手,还是经验丰富的专家,这篇文章都将是一次有益的阅读,可以帮助你更好地理解损失函数。作为一个在模型训练过程中测试多种不同损失函数的人,我常常因为函数之间的小细节而卡住。我花了很多时间查阅教科书、研究论文和视频,以寻找一种直观的损失函数描述。我想与大家分享不仅是帮助我理解这些概念的推导过程,还有在 PyTorch 中使用分类损失函数时常见的陷阱和应用场景。
术语
在我们开始之前,我需要定义一些我将要使用的基本术语。
-
训练数据集: {xᵢ, yᵢ}
-
损失函数: L[φ]
-
模型预测输出 f[xᵢ, φ],其中 φ 为参数
-
条件概率: Pr(y|x)
-
参数化分布: Pr(y|ω),其中 ω 表示网络参数,用于描述 y 上的分布
介绍
让我们首先回归基础。一个常见的想法是神经网络从模型 f[xᵢ, φ] 计算一个标量输出。然而,现在大多数神经网络被训练用来预测一个分布的参数 y。(而不是预测 y 的值)。
实际上,网络将输出一个条件概率分布 Pr(y|x),这个分布表示给定输入 x 时各个可能输出 y 的概率。换句话说,每个输入数据点都会生成一个针对每个输出的概率分布。网络的目标是学习这些概率分布的参数,并使用这些参数和分布来预测输出。
传统的损失函数定义是一个比较目标输出和预测输出的函数。但我们刚才说过,网络的原始输出是一个分布,而不是一个标量输出,那么这是如何实现的呢?
从我们刚才定义的视角来看,损失函数推动每个yᵢ在分布Pr(yᵢ|xᵢ)中具有更高的概率。需要记住的关键部分是,我们的分布用于根据模型输出的参数预测真实输出。我们不再使用输入xᵢ来表示分布*,而是可以考虑一个参数化的分布Pr(y|ω),其中ω代表概率分布的参数。我们仍然考虑输入,但每个xᵢ会有不同的ωᵢ = f[xᵢ, φ]*。
注意: 为了澄清一个容易混淆的概念,φ代表模型参数,而ω代表概率分布的参数
推导负对数似然损失
G回到传统的损失函数定义,我们需要从模型中获得一个可用的输出。从我们的概率分布来看,选择φ来产生每个xᵢ的最大概率似乎是合乎逻辑的。因此,我们需要得到在所有训练点I上产生最大概率的总体φ(所有推导都来自《理解深度学习》[1]):
最大化输出模型概率分布的参数 [1]
我们将每个分布生成的概率相乘,以找到产生最大概率的φ(称为最大似然)。为了做到这一点,我们必须假设数据是独立且同分布的。但现在我们遇到了一个问题:如果概率非常小怎么办?我们的乘积结果将接近于 0(类似于梯度消失问题)。此外,我们的程序可能无法处理如此小的数字。
为了解决这个问题,我们引入了对数函数!利用对数的特性,我们可以将概率相加,而不是相乘。我们知道,对数是一个单调递增的函数,因此我们的原始输出被保留并通过对数进行了缩放。
使用对数加法概率 [1]
我们需要做的最后一件事是获取我们传统的负对数似然,即最小化输出。我们现在是在最大化输出,所以只需要乘以负数并取最小值(考虑一些图形示例来帮助自己理解这一点):
负对数似然 [1]
仅仅通过将模型输出可视化为一个概率分布,尝试最大化生成最大概率的φ,并应用对数,我们就推导出了负对数似然损失!通过选择一个合适的概率分布,这可以应用于许多任务。下面展示了一些常见的分类示例。
如果你想知道在推断过程中,模型是如何生成标量输出的,那就是分布的最大值:
从推断生成输出[1]
注意: 这只是负对数似然的推导。在实践中,损失函数中很可能还会有正则化项。
分类的损失
到目前为止,我们推导了负对数似然。虽然这很重要,但它可以在大多数教科书或在线资源中找到。现在,让我们将其应用于分类问题,以理解它的应用。
附注: 如果你对将其应用于回归感兴趣,《理解深度学习》[1]中有关于单变量回归和高斯分布推导均方误差的很好的例子。
二分类
二分类的目标是将输入x分配到两个类别标签之一,y ∈ {0, 1}。我们将使用伯努利分布作为我们选择的概率分布。
伯努利分布的数学表示。图片来源:作者
这只是一个花哨的说法,表示输出为真的概率,但这个方程是推导损失函数所必需的。我们需要模型f[x, φ]输出p来生成预测的输出概率。然而,在我们将p输入到伯努利分布之前,我们需要确保它在 0 和 1 之间(因为它是一个概率)。用于此的函数是 sigmoid:σ(z)
来源:en.wikipedia.org/wiki/Sigmoid_function
Sigmoid 会将输出p压缩到 0 和 1 之间。因此,我们输入伯努利分布的值是p = σ(f[x, φ])。这使我们的概率分布变为:
带有 Sigmoid 和伯努利分布的新概率分布。图片来源:作者
回到负对数似然,我们得到如下结果:
二元交叉熵。图片来源:作者
看起来很熟悉吧?这就是二元交叉熵(BCE)损失函数!理解这一点的关键是理解为什么使用 sigmoid。我们有一个标量输出,它需要被缩放到 0 和 1 之间。虽然也有其他函数能做到这一点,但 sigmoid 是最常用的。
PyTorch 中的 BCE
在 PyTorch 中实现 BCE 时,需要注意一些技巧。PyTorch 中有两个不同的 BCE 函数:BCELoss()和BCEWithLogitsLoss()。一个常见的错误(我也犯过)是错误地交换了它们的使用场景。
BCELoss(): 这个 torch 函数输出的是已经应用了 SIGMOID 的损失值。输出将是一个概率。
BCEWithLogitsLoss(): 这个 torch 函数输出的是 logits,即模型的原始输出。没有应用 SIGMOID。当使用这个函数时,你需要对输出应用torch.sigmoid()。
这对于迁移学习尤为重要,因为即使你知道模型是使用 BCE 训练的,也要确保使用正确的损失函数。如果没有这样做,可能会在 BCELoss() 后意外地应用 sigmoid,导致网络无法学习……
一旦使用任一函数计算了概率,就需要在推理过程中进行解释。这个概率是模型对结果为真的可能性的预测(类别标签为 1)。需要通过阈值来确定真实标签的截止概率。p = 0.5 是常用的阈值,但测试并优化不同的阈值概率是很重要的。一个好主意是绘制输出概率的直方图,查看输出的置信度,再决定阈值。
多类分类
多类分类的目标是将输入 x 分配给 K > 2 个类别标签 y ∈ {1, 2, …, K} 中的一个。我们将使用分类分布作为我们的概率分布选择。
分类分布。图片来源:作者
这只是为给定输出的每个类别分配一个概率,且所有概率的总和必须为 1。我们需要模型 f[x, φ] 输出 p,以生成预测的输出概率。和二分类一样,这里也会遇到总和问题。在将 p 输入到伯努利分布之前,我们需要确保它是一个介于 0 和 1 之间的概率。sigmoid 不再适用,因为它会将每个类别的分数缩放为一个概率,但不能保证所有概率的总和为 1。这点可能不容易发现,但可以通过一个例子来说明:
Sigmoid 在多类分类中无法生成概率分布。图片来源:作者
我们需要一个函数来确保满足这两个约束条件。因此,选择了 softmax。softmax 是 sigmoid 的扩展,它会确保所有概率的总和为 1。
Softmax 函数。图片来源:作者
这意味着概率分布是对模型输出应用的 softmax。计算标签k的似然:Pr(y = k|x) = Sₖ(f[x, φ])。
为了推导多类分类的损失函数,我们可以将 softmax 和模型输出代入负对数似然损失中:
多类交叉熵。图片来源:作者
这是多类别交叉熵的推导。需要记住,唯一对损失函数有贡献的项是正确类别的概率。如果你见过交叉熵,你会更熟悉一个包含 p(x) 和 q(x) 的函数。这个公式与交叉熵损失方程是相同的,其中 p(x) = 1 表示正确类别,其他类别的值为 0。q(x) 是模型输出的 softmax。交叉熵的另一个推导来源于使用 KL 散度,你可以通过将一个项视为 Dirac delta 函数(其中包含真实输出)并将另一个项视为模型输出(应用 softmax)来推导出相同的损失函数。需要注意的是,这两种推导方式都得出相同的损失函数。
PyTorch 中的交叉熵
与二元交叉熵不同,PyTorch 中的交叉熵损失只有一个损失函数。nn.CrossEntropyLoss 返回已经应用 softmax 的模型输出。推断可以通过选择最大概率的 softmax 模型输出(选择最高概率的输出)来进行。
应用
这些是两个研究得比较深入的分类例子。对于更复杂的任务,可能需要一些时间来决定使用哪个损失函数和概率分布。有很多图表可以帮助将概率分布与目标任务匹配,但总有空间可以进一步探索。
对于某些任务,将损失函数组合起来可能会有帮助。一个常见的应用场景是在分类任务中,可能有助于将[二元]交叉熵损失与修改过的 Dice 系数损失结合使用。大多数时候,损失函数会被加在一起,并通过某个超参数进行缩放,以控制每个函数对总损失的贡献。
希望这个关于负对数似然损失及其应用的推导对你有所帮助!
参考文献
[1] Prince, Simon J.D., 理解深度学习。
[2] 斯坦福 CS231n。
[3] P. Bosman, D. Thierens, 负对数似然与统计假设检验作为 IDEAs 中模型选择的基础(2000 年)。
603

被折叠的 条评论
为什么被折叠?



