pytorch 是不是在 nn.Linear 中自动应用 softmax
Posted
技术标签:
【中文标题】pytorch 是不是在 nn.Linear 中自动应用 softmax【英文标题】: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 的回答下还有其他问题。希望也能听到您的建议!
【参考方案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。以上是关于pytorch 是不是在 nn.Linear 中自动应用 softmax的主要内容,如果未能解决你的问题,请参考以下文章
pytorch中的神经网络子模块(线性模块)——torch.nn.Linear
如何在 Pytorch 的“nn.Sequential”中展平输入