评价此页

CrossEntropyLoss#

class torch.nn.modules.loss.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='mean', label_smoothing=0.0)[source]#

此准则计算输入 logits 和 target 之间的交叉熵损失。

当训练一个有 C 个类别的分类问题时,此函数非常有用。如果提供了可选参数 weight,它应该是一个 1D Tensor,为每个类别分配权重。这在训练数据集不平衡时尤其有用。

对于未批量的输入,input 期望包含每个类别的未归一化 logits(通常 input 不需要是正数或总和为 1)。input 必须是一个大小为 (C)(C) 的 Tensor;对于批量输入,大小为 (minibatch,C)(minibatch, C);或者对于 K1K \geq 1K 维情况,大小为 (minibatch,C,d1,d2,...,dK)(minibatch, C, d_1, d_2, ..., d_K)。最后一个形式对于更高维度的输入很有用,例如为 2D 图像计算每像素的交叉熵损失。

此标准(criterion)期望的 target 应该包含以下两种情况之一:

  • 类别索引,范围为 [0,C)[0, C),其中 CC 是类别的数量;如果指定了 ignore_index,此损失也接受该类别的索引(该索引不一定在类别范围内)。在这种情况下,未归约的损失(即 reduction 设置为 'none')可以描述为:

    (x,y)=L={l1,,lN},ln=wynlogexp(xn,yn)c=1Cexp(xn,c)1{ynignore_index}\ell(x, y) = L = \{l_1,\dots,l_N\}^\top, \quad l_n = - w_{y_n} \log \frac{\exp(x_{n,y_n})}{\sum_{c=1}^C \exp(x_{n,c})} \cdot \mathbb{1}\{y_n \not= \text{ignore\_index}\}

    其中 xx 是输入,yy 是目标,ww 是权重,CC 是类别的数量,NN 跨越了小批量维度以及 d1,...,dkd_1, ..., d_k 对于 K 维情况。如果 reduction 不是 'none'(默认为 'mean'),则:

    (x,y)={n=1N1n=1Nwyn1{ynignore_index}ln,if reduction=‘mean’;
n=1Nln,if reduction=‘sum’.\ell(x, y) = \begin{cases} \sum_{n=1}^N \frac{1}{\sum_{n=1}^N w_{y_n} \cdot \mathbb{1}\{y_n \not= \text{ignore\_index}\}} l_n, & \text{if reduction} = \text{`mean';}\\ \sum_{n=1}^N l_n, & \text{if reduction} = \text{`sum'.} \end{cases}

请注意,这种情况等同于对输入应用 LogSoftmax,然后应用 NLLLoss

  • 每个类别的概率;当需要单个类别标签以外的标签时(例如,混合标签、标签平滑等),此选项很有用。在这种情况下,未归约的损失(即 reduction 设置为 'none')可以描述为:

    (x,y)=L={l1,,lN},ln=c=1Cwclogexp(xn,c)i=1Cexp(xn,i)yn,c\ell(x, y) = L = \{l_1,\dots,l_N\}^\top, \quad l_n = - \sum_{c=1}^C w_c \log \frac{\exp(x_{n,c})}{\sum_{i=1}^C \exp(x_{n,i})} y_{n,c}

    其中 xx 是输入,yy 是目标,ww 是权重,CC 是类别的数量,NN 跨越了小批量维度以及 d1,...,dkd_1, ..., d_k 对于 K 维情况。如果 reduction 不是 'none'(默认为 'mean'),则:

    (x,y)={n=1NlnN,if reduction=‘mean’;n=1Nln,if reduction=‘sum’.\ell(x, y) = \begin{cases} \frac{\sum_{n=1}^N l_n}{N}, & \text{if reduction} = \text{`mean';}\\ \sum_{n=1}^N l_n, & \text{if reduction} = \text{`sum'.} \end{cases}
  • 注意

    通常情况下,当 target 包含类别索引时,此标准(criterion)的性能更好,因为这样可以进行优化计算。只有当每个小批量项只有一个类别标签过于受限时,才考虑将 target 提供为类别概率。

    参数
    • weight (Tensor, optional) – 为每个类别手动指定的重缩放权重。如果提供,则必须是一个大小为 C 的 Tensor。

    • size_average (bool, optional) – 已弃用 (参见 reduction)。默认情况下,损失值在批次中的每个损失元素上取平均值。请注意,对于某些损失,每个样本有多个元素。如果字段 size_average 设置为 False,则损失值在每个小批次中而是求和。当 reduceFalse 时忽略。默认值:True

    • ignore_index (int, optional) – 指定一个被忽略的目标值,该值不计入输入梯度。当 size_averageTrue 时,损失将根据非忽略的目标进行平均。请注意,ignore_index 仅在目标包含类别索引时适用。

    • reduce (bool, optional) – 已弃用 (参见 reduction)。默认情况下,损失值在每个小批次中根据 size_average 对观测值进行平均或求和。当 reduceFalse 时,返回每个批次元素的损失值,并忽略 size_average。默认值:True

    • reduction (str, optional) – 指定应用于输出的归约方式:'none' | 'mean' | 'sum''none':不进行归约,'mean':取输出的加权平均值,'sum':对输出进行求和。注意:size_averagereduce 正在被弃用,在此期间,指定其中任何一个参数都将覆盖 reduction。默认为:'mean'

    • label_smoothing (float, optional) – 一个在 [0.0, 1.0] 范围内的浮点数。指定计算损失时的平滑量,0.0 表示无平滑。目标变为原始真实标签和均匀分布的混合,如 Rethinking the Inception Architecture for Computer Vision 中所述。默认值:0.00.0

    形状
    • 输入:形状为 (C)(C)(N,C)(N, C)(N,C,d1,d2,...,dK)(N, C, d_1, d_2, ..., d_K) 的 Tensor,其中 K1K \geq 1 用于 K 维情况。

    • 目标:如果包含类别索引,则形状为 ()()(N)(N)(N,d1,d2,...,dK)(N, d_1, d_2, ..., d_K) 的 K 维情况,其中 K1K \geq 1。每个值应在 [0,C)[0, C) 范围内。当使用类别索引时,目标数据类型必须是 long 类型。如果包含类别概率,目标必须与输入具有相同的形状,并且每个值应在 [0,1][0, 1] 范围内。这意味着当使用类别概率时,目标数据类型必须是 float 类型。请注意,PyTorch 不会严格强制执行类别概率的约束,用户有责任确保 target 包含有效的概率分布(有关更多详细信息,请参阅下面的示例部分)。

    • 输出:如果 reduction 是 'none',则形状为 ()()(N)(N)(N,d1,d2,...,dK)(N, d_1, d_2, ..., d_K) 的 K 维情况,取决于输入的形状。否则,为标量。

    其中

    C=number of classesN=batch size\begin{aligned} C ={} & \text{number of classes} \\ N ={} & \text{batch size} \\ \end{aligned}

    示例

    >>> # Example of target with class indices
    >>> loss = nn.CrossEntropyLoss()
    >>> input = torch.randn(3, 5, requires_grad=True)
    >>> target = torch.empty(3, dtype=torch.long).random_(5)
    >>> output = loss(input, target)
    >>> output.backward()
    >>>
    >>> # Example of target with class probabilities
    >>> input = torch.randn(3, 5, requires_grad=True)
    >>> target = torch.randn(3, 5).softmax(dim=1)
    >>> output = loss(input, target)
    >>> output.backward()
    

    注意

    target 包含类别概率时,它应该由软标签组成——也就是说,每个 target 条目应该代表给定数据样本的可能类别上的概率分布,其中单个概率在 [0,1] 之间,并且整个分布的总和为 1。这就是为什么在上面的类别概率示例中对 target 应用了 softmax() 函数。

    PyTorch 不会验证 target 中提供的值是否在 [0,1] 范围内,也不会验证每个数据样本的分布是否总和为 1。不会发出警告,用户有责任确保 target 包含有效的概率分布。提供任意值可能会在训练过程中产生误导性的损失值和不稳定的梯度。

    示例

    >>> # Example of target with incorrectly specified class probabilities
    >>> loss = nn.CrossEntropyLoss()
    >>> torch.manual_seed(283)
    >>> input = torch.randn(3, 5, requires_grad=True)
    >>> target = torch.randn(3, 5)
    >>> # Provided target class probabilities are not in range [0,1]
    >>> target
    tensor([[ 0.7105,  0.4446,  2.0297,  0.2671, -0.6075],
            [-1.0496, -0.2753, -0.3586,  0.9270,  1.0027],
            [ 0.7551,  0.1003,  1.3468, -0.3581, -0.9569]])
    >>> # Provided target class probabilities do not sum to 1
    >>> target.sum(axis=1)
    tensor([2.8444, 0.2462, 0.8873])
    >>> # No error message and possible misleading loss value
    >>> loss(input, target).item()
    4.6379876136779785
    >>>
    >>> # Example of target with correctly specified class probabilities
    >>> # Use .softmax() to ensure true probability distribution
    >>> target_new = target.softmax(dim=1)
    >>> # New target class probabilities all in range [0,1]
    >>> target_new
    tensor([[0.1559, 0.1195, 0.5830, 0.1000, 0.0417],
            [0.0496, 0.1075, 0.0990, 0.3579, 0.3860],
            [0.2607, 0.1355, 0.4711, 0.0856, 0.0471]])
    >>> # New target class probabilities sum to 1
    >>> target_new.sum(axis=1)
    tensor([1.0000, 1.0000, 1.0000])
    >>> loss(input, target_new).item()
    2.55349063873291
    
    forward(input, target)[source]#

    执行前向传播。

    返回类型

    张量