PyTorch学习笔记:nn.KLDivLoss——KL散度损失
torch.nn.KLDivLoss(size_average=None, reduce=None, reduction='mean', log_target=False)
功能:生成一个KL散度损失函数,常用于衡量两个连续分布的距离:
l
(
x
,
y
)
=
L
=
{
l
1
,
…
,
l
N
}
,
l
n
=
y
n
(
l
o
g
y
n
−
x
n
)
l(x,y)=L=\{l_1,\dots,l_N\},l_n=y_n(logy_n-x_n)
l(x,y)=L={l1,…,lN},ln=yn(logyn−xn)
其中,
N
N
N表示batch size。
输入:
size_average
与reduce
已被弃用,具体功能由参数reduction
代替reduction
:指定损失输出的形式,有四种选择:none
|mean
|batchmean
|sum
。none
:损失不做任何处理,直接输出一个数组;mean
:将得到的损失求平均值再输出,会输出一个数;batchmean
:将输出的总和除以batchsize;sum
:将得到的损失求和再输出,会输出一个数log_target
:指定是否对输入的 y y y使用 l o g log log操作
注意:
- 给定的输入
x
x
x应该为对数概率形式,即首先对网络的输出应用
softmax
,之后再取对数(可由F.log_softmax
函数直接实现) reduction
设置为mean
时,并不会返回真正的KL散度值,在定义KL的时候,需使用batchmean
(与数学公式对应起来)- 由于KL散度具有不对称性,存在一个指导和被指导的关系,如果想用 y y y去指导 x x x,则第一个参数需要传 x x x,第二个参数需要传 y y y,因此这里又称 y y y为 t a r g e t target target。引自:https://www.w3cschool.cn/article/84661764.html
代码案例
import torch.nn as nn
import torch
import torch.nn.functional as F
x = torch.randn((1, 8))
y = torch.randn((1, 8))
# 先转化为概率,之后取对数
x_log = F.log_softmax(x,dim=1)
# 只转化为概率
y = F.softmax(y,dim=1)
kl = nn.KLDivLoss(reduction='batchmean')
out = kl(x_log, y)
print(x)
print(x_log)
print(y)
print(out)
输出
# 输入x
tensor([[-1.5233, 2.5922, 1.7129, 0.3326, 0.4060, 2.4113, 2.0535, 0.4290]])
# x_log
tensor([[-5.2728, -1.1573, -2.0365, -3.4168, -3.3435, -1.3381, -1.6959, -3.3205]])
# 输入y
tensor([[0.1136, 0.1651, 0.0477, 0.3457, 0.0577, 0.0488, 0.1507, 0.0707]])
# 输出的损失
tensor(0.9757)
官方文档
nn.KLDivLoss:https://pytorch.org/docs/stable/generated/torch.nn.KLDivLoss.html#torch.nn.KLDivLoss
初步完稿于:2022年1月30日