【问题标题】:Does pytorch apply softmax automatically in nn.Linearpytorch 是否在 nn.Linear 中自动应用 softmax
【发布时间】:2019-12-22 06:29:06
【问题描述】:

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

这里是否应用了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

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

【问题讨论】:

  • 是的,linear 不会自动应用 softmax。
  • @unlut 谢谢,你觉得第二段代码合适吗?
  • 在我看来是正确的。
  • 在相关说明中,如果您使用的是nn.CrossEntropyLoss,则应用 log-softmax,然后是 nll-loss。您可能想确保您没有两次应用 softmax,因为 softmax not idempotent.
  • @jodag 谢谢!!!我在@dennlinger 的回答下还有其他问题。希望也能听到您的建议!

标签: python deep-learning pytorch activation-function


【解决方案1】:

了解 @jodag 在他的评论中已经说过的话,并稍微扩展一下以形成完整的答案:

,PyTorch 不会自动应用 softmax,您可以随时根据需要应用 torch.nn.Softmax()但是,softmax 有some issues with numerical stability,我们希望尽可能避免。一种解决方案是使用 log-softmax,但这往往比直接计算要慢。

特别是当我们使用负对数似然作为损失函数时(在 PyTorch 中,这是 torch.nn.NLLLoss,我们可以利用 (log-)softmax+NLLL 的导数实际上是 mathematically quite nice 和简单的事实,即这就是为什么将两者组合成一个函数/元素是有意义的。然后结果是torch.nn.CrossEntropyLoss。再次注意,这仅直接适用于网络的最后一层,任何其他计算都不会受到任何影响.

【讨论】:

  • 如果我理解正确的话,最好将nn.CrossEntropyLoss作为损失函数应用于最后一层nn.Linear()的输出,而不是直接使用nn.Softmax()。对吗?
  • 还有一个问题,nn.Softmax()的输出可以认为是某个类的概率,而nn.Linear()的所有输出之和不保证等于1。失去了最终输出的意义?
  • 回答你的第一条评论:你并没有真正用损失函数替换任何层,而是用不同的损失替换你当前的损失函数(应该是nn.NLLLoss),同时删除最后nn.Softmax()。不过,我认为您的想法已经是正确的。第二个问题:由于您的损失函数仍然“应用” log softmax(或者至少您的导数基于此),因此解释仍然成立。如果您以任何其他方式使用输出,例如在推理期间,您当然必须在这种情况下重新应用 softmax。
猜你喜欢
  • 2019-06-23
  • 1970-01-01
  • 2019-07-21
  • 2019-04-27
  • 1970-01-01
  • 1970-01-01
  • 2019-03-01
  • 1970-01-01
  • 2018-11-01
相关资源
最近更新 更多