在用
pytorch
做训练、测试时经常要用到损失函数计算输出与目标结果的差距,例如下面的代码:
for
batch_idx
,
(
data
,
target
)
in
enumerate
(
train_loader
)
:
data
,
target
=
data
.
to
(
device
)
,
target
.
to
(
device
)
optimizer
.
zero_grad
(
)
output
=
model
(
data
)
loss
=
F
.
nll_loss
(
output
,
target
)
loss
.
backward
(
)
optimizer
.
step
(
)
for
data
,
target
in
test_loader
:
data
,
target
=
data
.
to
(
device
)
,
target
.
to
(
device
)
output
=
model
(
data
)
test_loss
+=
F
.
nll_loss
(
output
,
target
,
reduction
=
'sum'
)
前一部分是训练过程,计算输出
output
与
target
的误差回传,后一部分是测试过程,计算
output
与
target
误差,并进行误差求和。
在该函数中重要的参数主要有三个,分别是:
-
input
:
(
N
)
目标结果,即常见分类任务中的label,包含N个。
-
reduction
:对计算结果采取的操作,通常我们用
sum
(对N个误差结果求和),
mean
(对N个误差结果取平均),默认是对所有样本求loss均值
采用官方提供的演示代码如下:
input = torch.randn(3, 5, requires_grad=True)
target = torch.tensor([1, 0, 4])
print('input:{}\n target:{}'.format(input,target))
print('log softmax:{}'.format(F.log_softmax(input,dim=1)))
output = F.nll_loss(F.log_softmax(input,dim=1), target)
print('output:{}'.format(output))
output.backward()
用jupyter notebook
打印一下中间结果:
这里做了一次log softmax
操作,softmax
实际上就是对输入tensor
中的元素按照数值计算了比例,dim=1
保证所有分类概率和为1,最后对每个数值取了log。最终要求的就是log softmax
后结果与target的误差。
我们重点关注这一步计算:
log softmax tensor
(模型output):tensor([[-3.2056, -1.7804, -0.4350, -3.9833, -2.0795],
[-2.1543, -1.8606, -1.5360, -1.1057, -1.7025],
[-2.3243, -0.7615, -1.1595, -2.5594, -3.1195]]
target
:tensor([1, 0, 4])
标签代表了tensor
中每一行向量应该检查的位置,例如第一个标签是1,这表示在tensor
第一行中应该选择1号位置的元素-1.7804
(代表了模型将数据分为1类的概率)取出,同理取第2行0号位置元素-2.1543
,取第三行4号位置元素-3.1195
,将它们去除负号求和再取均值。
则该模型输出output
与target
之间误差应为:(1.7804+2.1543+3.1195)/3 = 2.3514
回顾上文的output结果2.35138....
与预期相符。
reduction
同样是上面的输入,我们添加reduction
为sum
,查看output
结果:
发现计算结果是7.054...
,说明没有执行前面 (1.7804+2.1543+3.1195)/3 = 2.3514
求均值的操作。直接将各个样本与label之间的误差求和返回。
nll_loss 函数接收两个tensor
第一个是模型的output
,第二个是label target
,output
中每一行与一个标签中每一列的元素对应,根据target
的取值找出output
行中对应位置元素,求和取平均值。
在各种深度学习框架中,我们最常用的损失函数就是交叉熵(torch.nn.CrossEntropyLoss),熵是用来描述一个系统的混乱程度,通过交叉熵我们就能够确定预测数据与真是数据之间的相近程度。交叉熵越小,表示数据越接近真实样本。
交叉熵计算公式:
就是我们预测的概率的对数与标签的乘积,当qk->1的时候,它的损失接近零。
nn.NLLLoss
官方文档中介绍称: nn.NLLLoss...
F.nll_loss计算方式是下式,在函数内部不含有提前使用softmax转化的部分;
nn.CrossEntropyLoss内部先将输出使用softmax方式转化为概率的形式,后使用F.nll_loss函数计算交叉熵。
CrossEntropyLoss()=log_softmax() + NLLLoss()
两个函数的输入分别是input和target,
input是网络预测的输出,形状为(batch_size, pro),其中pro为class的个数;
target是标签,不
nll_loss(negative log likelihood loss):最大似然 / log似然代价函数
CrossEntropyLoss: 交叉熵损失函数。交叉熵描述了两个概率分布之间的距离,当交叉熵越小说明二者之间越接近。
nn.CrossEntropyLoss() 与 NLLLoss()
NLLLoss 的 输入 是一个对数概率向量和一个目标标签. 它不会为我们计算对数概率. 适合网络...
NLLLoss+SoftMax=CE_Loss
差不多好几天没有更新了,唉,最近有点忙,请见谅!今天终于忙里偷闲看了B站视频发现NLLLoss+SoftMax=CE_Loss,哈哈,又长见识了,那么今天来深入了解一下吧!
NLLLoss
负对数似然损失
torch.nn.NLLLoss(
weight=None,
size_average=None,
ignore_index=- 1
paddle中nll_loss()与CrossEntropyLoss()损失函数区别
首先先交代结论:nll_loss()与CrossEntropyLoss()损失函数计算的关系为CrossEntropyLoss()等于对输入数据先做softmax,再做log处理,再加nll_loss()操作。
1.NLLLoss 的输入是一个对数概率向量和一个目标标签,它不会为我们计算对数概率.,适合网络的最后一层是log_softmax损失函数,有时候调用预训练模型修改网络最后的全连接层的时候会把最后一层的输出改变,这