pytorch 是否在 nn.Linear 中自动应用 softmax

yuj*_*ao 9 python deep-learning activation-function pytorch

pytorch分类网络模型中定义为这样,

class Net(torch.nn.Module):
    def __init__(self, n_feature, n_hidden, n_output):
        super(Net, self).__init__()
        self.hidden = torch.nn.Linear(n_feature, n_hidden)   # hidden layer
        self.out = torch.nn.Linear(n_hidden, n_output)   # output layer

    def forward(self, x):
        x = F.relu(self.hidden(x))      # activation function for hidden layer
        x = self.out(x)
        return x
Run Code Online (Sandbox Code Playgroud)

这里应用了 softmax 吗?在我看来,事情应该是这样的,

class Net(torch.nn.Module):
    def __init__(self, n_feature, n_hidden, n_output):
        super(Net, self).__init__()
        self.hidden = torch.nn.Linear(n_feature, n_hidden)   # hidden layer
        self.relu =  torch.nn.ReLu(inplace=True)
        self.out = torch.nn.Linear(n_hidden, n_output)   # output layer
        self.softmax = torch.nn.Softmax(dim=n_output)
    def forward(self, x):
        x = self.hidden(x)      # activation function for hidden layer
        x = self.relu(x)
        x = self.out(x)
        x = self.softmax(x)
        return x
Run Code Online (Sandbox Code Playgroud)

我知道这F.relu(self.relu(x))也在应用 relu,但是第一段代码没有应用 softmax,对吧?

den*_*ger 5

揪着什么@jodag已经在他的评论中说,延长了一点,形成一个完整的答案:

,PyTorch 不会自动应用 softmax,您可以随时应用torch.nn.Softmax()但是,softmax 在数值稳定性方面存在一些问题,我们希望尽可能避免这些问题。一种解决方案是使用 log-softmax,但这往往比直接计算慢。

尤其是当我们使用负对数似然的损失函数(在PyTorch,这是torch.nn.NLLLoss我们可以利用的事实衍生物(对数)+添加Softmax是NLLL其实数学相当不错的,简单的,这就是为什么它是有道理的将两者组合成一个函数/元素。结果是torch.nn.CrossEntropyLoss。再次注意,这仅适用于网络的最后一层,任何其他计算都不受此影响。

  • 如果我理解正确的话,最好将 nn.CrossEntropyLoss 作为损失函数应用于最后一层 nn.Linear() 的输出,而不是直接使用 nn.Softmax() 。这是正确的吗? (3认同)
  • 回答你的第一条评论:你并不是真的用损失函数替换任何层,而是用不同的损失替换当前的损失函数(应该是“nn.NLLLoss”),同时删除最后一个“nn.Softmax( )`。不过,我认为您的想法已经是正确的。第二个问题:由于您的损失函数仍然“应用”log softmax(或者至少您的导数基于此),因此解释仍然成立。如果您以任何其他方式使用输出,例如在推理期间,您当然必须在这种情况下重新应用 softmax。 (2认同)