评价此页

KLDivLoss#

class torch.nn.KLDivLoss(size_average=None, reduce=None, reduction='mean', log_target=False)[source]#

kullback-Leibler 散度损失。

对于形状相同的张量 ypred, ytruey_{\text{pred}},\ y_{\text{true}}, 其中 ypredy_{\text{pred}}inputytruey_{\text{true}}target,我们定义 **逐点 KL 散度** 为

L(ypred, ytrue)=ytruelogytrueypred=ytrue(logytruelogypred)L(y_{\text{pred}},\ y_{\text{true}}) = y_{\text{true}} \cdot \log \frac{y_{\text{true}}}{y_{\text{pred}}} = y_{\text{true}} \cdot (\log y_{\text{true}} - \log y_{\text{pred}})

为了避免计算此数量时出现下溢问题,此损失函数期望 `input` 参数以对数空间(log-space)的形式给出。如果 `log_target` 设置为 `True`,则 `target` 参数也可以以对数空间的形式给出。

总结来说,此函数大致等同于计算

if not log_target:  # default
    loss_pointwise = target * (target.log() - input)
else:
    loss_pointwise = target.exp() * (target - input)

然后根据 `reduction` 参数将此结果进行约简(reduce)为

if reduction == "mean":  # default
    loss = loss_pointwise.mean()
elif reduction == "batchmean":  # mathematically correct
    loss = loss_pointwise.sum() / input.size(0)
elif reduction == "sum":
    loss = loss_pointwise.sum()
else:  # reduction == "none"
    loss = loss_pointwise

注意

与 PyTorch 中的所有其他损失函数一样,此函数期望第一个参数 `input` 是模型的输出(例如神经网络),第二个参数 `target` 是数据集中的观测值。这与标准的数学表示法 KL(P  Q)KL(P\ ||\ Q) 不同,其中 PP 表示观测值的分布,而 QQ 表示模型。

警告

当 `reduction` 为 “mean” 时,返回的不是真实的 KL 散度值,请使用 `reduction` = “batchmean”,这样才能与数学定义保持一致。

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

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

  • reduction (str, optional) – 指定应用于输出的约简方式。默认值:“mean”

  • log_target (bool, optional) – 指定 `target` 是否为对数空间。默认值:`False`

形状
  • 输入: ()(*),其中 * 表示任意数量的维度。

  • 目标: ()(*),与输入形状相同。

  • 输出: 默认情况下为标量。如果 `reduction` 为 ‘none’,则输出为 ()(*),与输入形状相同。

示例

>>> kl_loss = nn.KLDivLoss(reduction="batchmean")
>>> # input should be a distribution in the log space
>>> input = F.log_softmax(torch.randn(3, 5, requires_grad=True), dim=1)
>>> # Sample a batch of distributions. Usually this would come from the dataset
>>> target = F.softmax(torch.rand(3, 5), dim=1)
>>> output = kl_loss(input, target)
>>>
>>> kl_loss = nn.KLDivLoss(reduction="batchmean", log_target=True)
>>> log_target = F.log_softmax(torch.rand(3, 5), dim=1)
>>> output = kl_loss(input, log_target)