交叉熵损失:介绍、应用、代码

您所在的位置:网站首页 怎么计算熵 交叉熵损失:介绍、应用、代码

交叉熵损失:介绍、应用、代码

2023-03-13 11:35| 来源: 网络整理| 查看: 265

让我们深入研究交叉熵函数并讨论它们在机器学习中的应用,特别是在分类问题上。

到 2023 年,机器学习将出现在我们日常交互的几乎所有应用程序中。

为确保应用程序以最高效率运行,所有企业都必须不断优化其 ML 模型。微调所有参数是创建可实现最高性能并有助于创造最佳用户体验的模型的唯一方法。

这些参数之一是准确度,用损失函数来衡量。而在机器学习应用中使用最广泛的损失函数是交叉熵。

在本文中,我们将详细解释交叉熵函数并讨论它们在机器学习中的应用,尤其是在分类问题上的应用。

以下是我们将介绍的内容:

什么是交叉熵?机器学习中的损失函数交叉熵损失函数 如何应用交叉熵?什么是交叉熵?

在深入研究熵的概念之前,让我们先解释一下信息论的概念。克劳德·香农 (Claude Shannon) 于 1948 年在其开创性著作“通信理论”中首次引入了它。

根据香农的说法,熵是表示或传输从随机变量的概率分布中提取的事件所需的平均位数。

简单来说,熵表示事件的不确定性大小。让我们以确定公平抛硬币结果的问题为例。

对于一枚公平的硬币,我们有两个结果。两者都有 P[X=H] = P[X=T] = 1/2。使用香农熵方程:

硬币的两项都为 0,几乎总是 H 或几乎总是 T,因此熵为 0。

在数据科学领域,两个离散概率分布之间的交叉熵与Kullback-Leibler (KL)Divergence相关,这是一个衡量两个分布相似程度的指标。

给定真实分布 t 和预测分布 p,它们之间的交叉熵由以下等式给出:

这里,t 和 p 分布在同一个支持 S 上,但可以取不同的值。

对于三元素支持 S,如果 t = [t1, t2, t3] 和 p = [p1, p2, p3],则 t_i = p_i 对 {1,2,3} 中的 i 来说是不必要的。

然而,在现实世界中,预测值与实际值不同,称为发散,因为它与实际值不同或背离。因此,交叉熵是熵和 KL 散度(散度类型)的总和。

现在让我们使用分类示例了解交叉熵如何适合深度神经网络范例。

每个分类案例都有一个已知的类别标签,其概率为 1.0,而其他每个标签的概率为 0。在此,模型确定特定案例属于每个类别名称的概率。然后可以使用交叉熵来确定每个标签的神经通路有何不同。

将每个预测的类别概率与所需输出 0 或 1 进行比较。计算出的分数/损失会根据与预期值的距离来惩罚概率。惩罚是对数的,对接近 1 的显着差异产生高分,对接近 0 的微小差异产生小分。

在训练期间调整模型权重时使用交叉熵损失。目的是最小化损失——损失越小,模型越好。

机器学习中的损失函数

损失函数衡量模型偏离正确预测的程度。

损失函数提供的不仅仅是模型运行情况的静态说明;它们还可以作为您的算法与数据匹配准确程度的基础。大多数机器学习算法在优化阶段采用损失函数,这涉及选择数据的最佳参数(权重)。

考虑线性回归。传统的“最小二乘”回归使用机器平方误差 (MSE) 来估计最佳拟合线,因此得名“最小二乘”!MSE 是为模型在所有输入样本上尝试的权重而生成的。然后使用梯度下降等优化器方法,模型将 MSE 函数减少到绝对最小值。

机器学习算法通常具有三种类型的损失函数。

回归损失函数处理连续值,可以取两个极限之间的任何值,例如在预测一个国家的人均 GDP 时,给定人口增长率、城市化率、历史 GDP 趋势等。

分类损失函数处理离散值,例如使用置信度值对对象进行分类。例如,将图像分类为两个标签:猫和狗。

‍ 排名损失函数预测值之间的相对距离。一个例子是人脸验证,我们想知道哪些人脸图像属于特定的人脸。我们可以通过不属于原始人脸持有者的人脸与目标人脸扫描的相对近似度对人脸进行排名来做到这一点。

在我们进入损失函数之前,让我们讨论一下激活函数及其应用。输出激活函数是我们在损失计算之前应用于来自卷积神经网络 (CNN) 的向量的转换。

Sigmoid 和 Softmax 在分类问题中广泛使用激活函数。

Sigmoid 压缩范围 (0, 1) 中的向量。它在训练期间独立应用于批次中的每个输入元素。它也称为逻辑函数

Softmax 是函数,不是损失。它压缩范围 (0, 1) 中的向量,所有结果元素加起来为 1。它应用于输出分数s

由于元素代表一个类别,因此可以将它们解释为类别概率。Softmax 函数不能独立应用于每个元素si,因为它依赖于s的所有元素。对于给定的类si, Softmax 函数可以计算为:

在计算训练阶段的损失之前,激活函数会转换向量。在测试中,当不再应用损失时,激活函数也用于获取 CNN 输出。

交叉熵损失函数

交叉熵通过测量给定随机变量/事件集的两个概率分布之间的变化来扩展信息论熵的概念。

在训练期间调整模型权重时使用交叉熵损失。目的是最小化损失——损失越小,模型越好。完美模型的交叉熵损失为 0。它通常用于多类和多标签分类。

交叉熵损失衡量深度学习分类模型发现的和预测的概率分布之间的差异。

两个概率分布之间的交叉熵,例如来自 P 的 Q,可以正式表示为

H(P, Q)

在哪里:

H() 是交叉熵函数P 可能是目标分布Q 是目标分布的近似值。

可以使用来自 P 和 Q 的事件的概率来计算交叉熵:

H(P, Q) = — XP(x) * log(Q(x)) 中的总和 x

通常,激活函数 (Sigmoid/Softmax) 在 CE 损失计算之前应用于分数。

使用 Softmax,模型预测概率向量 [0.7, 0.2, 0.1]。70%、20%、10%之和为100%,第一个进入的可能性最大。

下图展示了图像分类推理的工作流程:

Softmax 将 logits 转换为概率。交叉熵的目的是获取输出概率 (P) 并测量与真值的距离(如下所示)。

下图说明了交叉熵损失函数的输入参数:

二元交叉熵损失

二元交叉熵是仅用于两个类别之间的分类问题的损失函数。它也称为二进制分类问题。

在处理离散量时使用概率质量函数 (PMF)(返回概率)对于使用均方误差的连续值,改为应用概率密度函数 (PDF)(返回密度)。

此函数中使用的 PMF 由以下等式表示:

这里,x 是常量,因为它存在于数据中,而 mu 是变量。

为了最大化似然,PMF 可以表示为:

要执行计算,请取此函数的对数,因为它允许我们使用导数快速最小化/最大化。在处理之前取日志是允许的,因为日志是单调递增的函数。

如上图所示,在区间 (0,1) 中,log(x) 和 -log(x) 分别为负值和正值。观察 -log(x) 如何在 x 接近 1 时接近 0。这个观察结果是在解析交叉熵损失的表达式时很有用。

由于我们想要最大化输出属于特定类别的概率,因此必须在下面的对数似然方程中找到 mu 值。

计算上述对数似然函数关于 mu 的偏导数。输出是:

在上面的等式中,x(i) 的概率值为 1 或 0。

让我们以抛硬币为例。如果我们正在寻找正面,则 x() 的值

比如在抛硬币中,如果我们要找正面,如果出现正面,那么x(i)的值就会为1;否则为 0。这样,上述等式将计算所有事件中预期结果的概率。

如果我们最大化似然或最小化负对数似然(它是预测中的实际误差和实际值),结果是相同的

因此,负对数似然将为:

在负对数似然方程中,mu将变成y_pred——i的最大概率对应的类(y(i)根据最大概率被分类到的类)。

如果数据集中有 n 个样本,则总交叉熵损失是数据集中所有样本的损失值之和。因此,最小化误差的二元交叉熵 (BCE) 可以用以下方式表示:

从上面的计算中,我们可以做出以下观察:

当真实标签 t 为 1 时,随着预测概率 p 趋近于 1,交叉熵损失趋近于 0,并且当真实标签 t 为 0 时,随着预测概率 p 趋近于 0,交叉熵损失趋近于 0。

多类交叉熵/分类交叉熵

分类交叉熵也称为Softmax 损失。它是一个softmax 激活加上一个用于多类分类的交叉熵损失。使用这种损失,我们可以训练一个卷积神经网络来为每张图像输出 N 个类别的概率。

在多类分类中,神经网络的原始输出通过 softmax 激活传递,然后输出输入类的预测概率向量。

在多类分类的特定(和通常)情况下,标签是单热的,因此只有正类在损失中保留其任期。目标向量只有一个元素,不同于零。丢弃由于目标标签而为零的求和元素,我们可以写:

Python 中的分类交叉熵损失正向函数def forward(self, bottom, top): labels = bottom[1].data scores = bottom[0].data # Normalizing to avoid instability scores -= np.max(scores, axis=1, keepdims=True) # Compute Softmax activations exp_scores = np.exp(scores) probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True) logprobs = np.zeros([bottom[0].num,1]) # Compute cross-entropy loss for r in range(bottom[0].num): # For each element in the batch scale_factor = 1 / float(np.count_nonzero(labels[r, :])) for c in range(len(labels[r,:])): # For each class if labels[r,c] != 0: # Positive classes logprobs[r] += -np.log(probs[r,c]) * labels[r,c] * scale_factor # We sum the loss per class for each element of the batch data_loss = np.sum(logprobs) / bottom[0].num self.diff[...] = probs # Store softmax activations top[0].data[...] = data_loss # Store loss分类交叉熵与稀疏分类交叉熵

分类交叉熵和稀疏分类交叉熵的损失函数是相同的,它在你提到 Yi 的方式上有所不同(即准确的标签)。

分类交叉熵

标签 (Yi) 是单热编码的。

示例(对于 3 类分类):[1,0,0]、[0,1,0]、[0,0,1]

稀疏分类交叉熵

标签 (Yi) 是整数。

以上3类分类问题的例子:[1]、[2]、[3]

此外,这取决于您加载数据集的方式。使用整数而不是向量加载数据集标签可提供更高的内存和计算效率。

在 Pytorch 和 Tensorflow 中编码交叉熵

并不是说我们涵盖了交叉熵的基础知识,让我们直接进入代码。

定义虚拟输入和目标以测试交叉熵损失 pytorch 函数。从torch.nn模块导入CrossEntropyLoss()内置函数。定义损失变量并传递输入和目标调用输出反向函数来计算梯度,以改善下一次训练迭代中的损失。z# Example of target with class probabilities import torch import torch.nn as nn input = torch.rand(3, 5, requires_grad=True) target = torch.empty(3, dtype=torch.long).random_(5) print(target.size()) loss = nn.CrossEntropyLoss() output = loss(input, target) output.backward() print("Input:",input) print("Target:",target) print("Cross Entropy Loss:",output) print('Input grads: ', input.grad) torch.Size([3]) Input: tensor([[0.8671, 0.0189, 0.0042, 0.1619, 0.9805], [0.1054, 0.1519, 0.6359, 0.6112, 0.9417], [0.9968, 0.3285, 0.9185, 0.0315, 0.9592]], requires_grad=True) Target: tensor([1, 0, 4]) Cross Entropy Loss: tensor(1.8338, grad_fn=) Input grads: tensor([[ 0.0962, -0.2921, 0.0406, 0.0475, 0.1078], [-0.2901, 0.0453, 0.0735, 0.0717, 0.0997], [ 0.0882, 0.0452, 0.0815, 0.0336, -0.2484]])

在这个例子中,我们只考虑了一个训练样本。实际上,我们通常做小批量。默认情况下,PyTorch 将使用批次中所有样本的平均交叉熵损失。

在 Pytorch 中,如果使用 nn.CrossEntropyLoss,输入必须是非标准化的原始值 (logits),目标必须是类索引而不是一个热编码向量。

二元交叉熵是类数为2的情况。在PyTorch中,有nn.BCELoss和nn.BCEWithLogitsLoss。前者需要输入归一化 sigmoid 概率,后者可以采用原始的非归一化 logits。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3