Shortcuts

KLDivLoss

class torch.nn.KLDivLoss(size_average=None, reduce=None, reduction='mean', log_target=False)[源代码]

库尔贝克-莱布勒散度损失。

对于形状相同的张量 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 以对数空间形式提供。参数 target 也可以在对数空间中提供,如果 log_target= True

总结来说,这个函数大致相当于计算

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

然后根据参数 reduction 减少此结果,如下所示:

if reduction == "mean":  # 默认
    loss = loss_pointwise.mean()
elif reduction == "batchmean":  # 数学上正确
    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”,它与数学定义一致。

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

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

  • reduction (str, 可选) – 指定应用于输出的reduction。默认值: “mean”

  • log_target (bool, 可选) – 指定 target 是否在日志空间中。默认值:False

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

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

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

示例:

>>> import torch.nn.functional as F
>>> kl_loss = nn.KLDivLoss(reduction="batchmean")
>>> # 输入应该是在对数空间中的分布
>>> input = F.log_softmax(torch.randn(3, 5, requires_grad=True), dim=1)
>>> # 采样一批分布。通常这些分布来自数据集
>>> 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)
优云智算