Zab*_*azi 14
import torch
x = torch.rand(5)
x1 = torch.nn.Softmax()(x)
x2 = torch.nn.functional.softmax(x)
x3 = torch.nn.functional.log_softmax(x)
print(x1)
print(x2)
print(torch.log(x1))
print(x3)
Run Code Online (Sandbox Code Playgroud)
tensor([0.2740, 0.1955, 0.1519, 0.1758, 0.2029])
tensor([0.2740, 0.1955, 0.1519, 0.1758, 0.2029])
tensor([-1.2946, -1.6323, -1.8847, -1.7386, -1.5952])
tensor([-1.2946, -1.6323, -1.8847, -1.7386, -1.5952])
Run Code Online (Sandbox Code Playgroud)
torch.nn.Softmax并torch.nn.functional.softmax给出相同的输出,一个是类(pytorch 模块),另一个是函数。
log_softmax应用 softmax 后应用 log。
NLLLoss 采用对数概率 (log(softmax(x))) 作为输入。因此,您需要 log_softmax 来实现 NLLLoss,log_softmax 在数值上更稳定,通常会产生更好的结果。
import torch
import torch.nn as nn
class Network(nn.Module):
def __init__(self):
super().__init__()
self.layer_1 = nn.LazyLinear(128)
self.activation = nn.ReLU()
self.layer_2 = nn.Linear(128, 10)
self.output_function = nn.Softmax(dim=1)
def forward(self, x, softmax="module"):
y = self.layer_1(x)
y = self.activation(y)
y = self.layer_2(y)
if softmax == "module":
return self.output_function(y)
# OR
if softmax == "torch":
return torch.softmax(y, dim=1)
# OR (deprecated)
if softmax == "functional":
return nn.functional.softmax(y, dim=1)
# OR (careful, the reason why the log is there is to ensure
# numerical stability so you should use torch.exp wisely)
if softmax == "log":
return torch.exp(torch.log_softmax(y, dim=1))
raise ValueError(f"Unknown softmax type {softmax}")
x = torch.rand(2, 2)
net = Network()
for s in ["module", "torch", "log"]:
print(net(x, softmax=s))
Run Code Online (Sandbox Code Playgroud)
基本上nn.Softmax()创建了一个模块,因此它返回一个函数,而其他都是纯函数。
为什么需要 log softmax?嗯,一个例子在文档中nn.Softmax:
该模块不能直接与 NLLLoss 一起使用,NLLLoss 期望在 Softmax 与其自身之间计算 Log。改为使用
LogSoftmax(它更快并且具有更好的数值属性)。
另请参阅log_softmax 和 softmax 之间有什么区别?