本文通过 log_softmax源码分析看值与概率的关系,log_softmax在pytorch中常见的有两个实现,一个是torch.nn.LogSoftmax(),一个是F.log_softmax()。
太长不看可以直接点 3.小结
```python
def log_softmax(input, dim=None, _stacklevel=3, dtype=None):
# type: (Tensor, Optional[int], int, Optional[int]) -> Tensor
if dim is None:
dim = _get_softmax_dim('log_softmax', input.dim(), _stacklevel)
if dtype is None:
ret = input.log_softmax(dim)
else:
ret = input.log_softmax(dim, dtype=dtype)
return ret
```
对softmax的结果计算Log。
虽然在数学上等同于log(softmax(x)),但是
单独操作速度较慢,且数值不稳定。此函数
能够正确计算输出和梯度。
有关详细信息,请参见:class:`~torch.nn.LogSoftmax`。
论据:
输入(张量):输入
dim(int):将沿其计算log_softmax的维度。
dtype(:class:`torch.dtype`,可选):返回的张量的所需数据类型。
这对于防止数据类型溢出非常有用。
```python
class LogSoftmax(Module):
__constants__ = ['dim']
def __init__(self, dim=None):
super(LogSoftmax, self).__init__()
self.dim = dim
def __setstate__(self, state):
self.__dict__.update(state)
if not hasattr(self, 'dim'):
self.dim = None
def forward(self, input):
return F.log_softmax(input, self.dim, _stacklevel=5)
```
参考官方文档:
(转载请保留本文链接:https://blog.csdn.net/ftimes/article/details/119648876)
根据源代码与官方文档,我们可以得出这样的结论:log_softmax是一一种更为强健的方式计算log(softmax)这一对数概率。
同时,在官方文档 torch.nn.Softmax(dim=None) 一节中,也提示到:
This module doesn’t work directly with NLLLoss, which expects the Log to be computed between the Softmax and itself. Use LogSoftmax instead (it’s faster and has better numerical properties).
值得强调的是,在pytorch中使用的是log这一符号,约定俗称的为以e为底,所以,通常情况下,我们可以通过torch.exp()还原回softmax()。
Out[11]:
tensor([ -8.7414, -8.5590, -10.5708, -3.1370, -4.8619, -4.5376, -3.7627,
-3.6359, -5.8785, -3.8922, -4.7725, -6.0678, -3.1159, -4.4447,
-2.2655, -1.6365, -4.1371, -5.2297, -5.4012, -6.4455, -4.3431,
-1.0044, -3.7157, -3.3281, -5.4026, -3.5647], device='cuda:0')
torch.exp(current_log_prob[0,:])
Out[13]:
tensor([1.5982e-04, 1.9181e-04, 2.5654e-05, 4.3415e-02, 7.7354e-03, 1.0699e-02,
2.3220e-02, 2.6360e-02, 2.7991e-03, 2.0400e-02, 8.4595e-03, 2.3162e-03,
4.4339e-02, 1.1741e-02, 1.0378e-01, 1.9466e-01, 1.5969e-02, 5.3552e-03,
4.5112e-03, 1.5876e-03, 1.2996e-02, 3.6627e-01, 2.4338e-02, 3.5860e-02,
4.5050e-03, 2.8307e-02], device='cuda:0')
torch.exp(current_log_prob[0,:]).sum()
Out[14]: tensor(1.0000, device='cuda:0')
故有:log_softmax的值越大(由于log_softmax的值域为[-inf,0),越大指越接近0),则softmax的值越接近1,也就是通常意义上的概率越大。
通过代码,我们也能验证该结果:
current_log_prob[0,:].argmax()
Out[15]: tensor(21, device='cuda:0')
current_log_prob[0,:][21]
Out[16]: tensor(-1.0044, device='cuda:0')
torch.exp(current_log_prob[0,:]).argmax()
Out[17]: tensor(21, device='cuda:0')
torch.exp(current_log_prob[0,:])[21]
Out[18]: tensor(0.3663, device='cuda:0')
torch.exp(current_log_prob[0,:]).max()
Out[19]: tensor(0.3663, device='cuda:0')