PyTorch学习笔记——softmax和log_softmax的区别、CrossEntropyLoss()
1、softmax函数 Softmax(x) 也是一个 non-linearity, 但它的特殊之处在于它通常是网络中一次操作. 这是因为它接受了一个实数向量并返回一个概率分布.其定义如下. 定义 x 是一个实数的向量(正数或负数都无所谓, 没有限制). 然后, 第i个 Softmax(x) 的组成是
exp(xi)∑jexp(xj)
exp(xi)∑jexp(xj)
输出是一个概率分布: 每个元素都是非负的, 并且所有元素的总和都是1.
2、log_softmax
在softmax的结果上再做多一次log运算
While mathematically equivalent to log(softmax(x)), doing these two
operations separately is slower, and numerically unstable. This function
uses an alternative formulation to compute the output and gradient correctly.
1
2
3
虽然在数学上等价于log(softmax(x)),但做这两个
单独操作速度较慢,数值上也不稳定。这个函数
使用另一种公式来正确计算输出和梯度。
1
2
3
4
5
测试:
import torch
import torch.autograd as autograd
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np
data=autograd.Variable(torch.FloatTensor())
log_softmax=F.log_softmax(data,dim=0)
print(log_softmax)
softmax=F.softmax(data,dim=0)
print(softmax)
np_softmax=softmax.data.numpy()
log_np_softmax=np.log(np_softmax)
print(log_np_softmax)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
3、nn.CrossEntropyLoss() 与 NLLLoss()
NLLLoss 的 输入 是一个对数概率向量和一个目标标签. 它不会为我们计算对数概率. 适合网络的最后一层是log_softmax. 损失函数 nn.CrossEntropyLoss() 与 NLLLoss() 相同, 唯一的不同是它为我们去做 softmax.
4、log似然代价函数
C=−∑kyklogak
C=−∑kyklogak
其中,akak表示第k个神经元的输出值;ykyk表示第k个神经元对应的真实值,取值为0或1。实际上,做分类时候,只有一个ykyk为1,其他均为0,最终结果是C=−yklogakC=−yklogak(akak对应着正确的那一个分类,log默认是e为底,ak∈ak∈,当akak最大时候,C=0),损失为0.
https://blog.csdn.net/hao5335156/java/article/details/80607732 我的理解是这样的:理论上对于单标签多分类问题,直接经过softmax求出概率分布,然后把这个概率分布用crossentropy做一个似然估计误差。但是softmax求出来的概率分布,每一个概率都是(0,1)的,这就会导致有些概率过小,导致下溢。 考虑到这个概率分布总归是要经过crossentropy的,而crossentropy的计算是把概率分布外面套一个-log 来似然,那么直接在计算概率分布的时候加上log,把概率从(0,1)变为(-∞,0),这样就防止中间会有下溢出。 所以log_softmax说白了就是将本来应该由crossentropy做的套log的工作提到预测概率分布来,跳过了中间的存储步骤,防止中间数值会有下溢出,使得数据更加稳定。 正是由于把log这一步从计算误差提到前面,所以用log_softmax之后,下游的计算误差的function就应该变成NLLLoss(它没有套log这一步,直接将输入取反,然后计算和label的乘积求和平均)1个月前
页:
[1]