nn.KLDivLoss

KLDivLoss

作用:

     用于连续分布的距离度量;并且对离散采用的连续输出空间分布进行回归通常很有用;用label_smoothing就采用这个;

公式:

             nn.KLDivLoss_第1张图片

            nn.KLDivLoss_第2张图片

nn.KLDivLoss_第3张图片

 

公式理解:

     p(x)是真实分布,q(x)是拟合分布;实际计算时;通常p(x)作为target,只是概率分布;而xn则是把输出做了LogSoftmax计算;即把概率分布映射到log空间;所以

K-L散度值实际是看log(p(x))-log(q(x))的差值,差值越小,说明拟合越相近。

 

pytorch使用:

 

当前版本torch(1.3.1)要想获得真正的KL散度;设置:

reduce=False;size_average=False

(reduce默认也是True,返回所有元素loss的和;size_average=默认是True,是对batch中每个元素进行求平均,当为False时,返回各样本各维度的loss之和;

因为reduce为False会忽略size_average参数,所以其实只需要把reduce=False即可)

代码验证:

import torch
    import torch.nn as nn
    import numpy as np

    # -----------------------------------  KLDiv loss

    loss_f = nn.KLDivLoss(size_average=False, reduce=False)
    loss_f_mean = nn.KLDivLoss(size_average=True, reduce=True)

    # 生成网络输出 以及 目标输出
    output = torch.from_numpy(np.array([[0.1132, 0.5477, 0.3390]])).float()
    output.requires_grad = True
    target = torch.from_numpy(np.array([[0.8541, 0.0511, 0.0947]])).float()

    loss_1 = loss_f(output, target)
    loss_mean = loss_f_mean(output, target)

    print('\nloss: ', loss_1)
    print('\nloss_mean: ', loss_mean)

    # 熟悉计算公式,手动计算样本的第一个元素的loss,注意这里只有一个样本,是 element-wise计算的

    output = output[0].detach().numpy()
    output_1 = output[0]  # 第一个样本的第一个元素
    target_1 = target[0][0].numpy()

    loss_1 = target_1 * (np.log(target_1) - output_1)

    print('\n第一个样本第一个元素的loss:', loss_1

nn.KLDivLoss_第4张图片

 

链接:https://github.com/TingsongYu/PyTorch_Tutorial/blob/master/Code/3_optimizer/3_1_lossFunction/6_KLDivLoss.py

 

Note:

D(p||q) ≠ D(q||p) ,不具有对称性所以不能称之为K-L距离

你可能感兴趣的:(pytorch,loss,KLDivLoss,pytorch,nn.KLDivLoss)