如题,初学者,看官网的 tutorials 中的 quick start ,它是定义了一个长相为这样的网络
self.linear_relu_stack = nn.Sequential(
nn.Linear(28*28, 512),
nn.ReLU(),
nn.Linear(512, 512),
nn.ReLU(),
nn.Linear(512, 10)
)
输出类别为 10 类,然后反向传播的代码是
pred = model(X)
loss = loss_fn(pred, y)
# Backpropagation
optimizer.zero_grad()
loss.backward()
optimizer.step()
loss_fn 是nn.CrossEntropyLoss()
交叉熵,那么这个输出类别似乎是没有通过 softmax 直接就输入交叉熵了吗?
如果要 softmax+交叉熵的话,是应该在定义网络的时候,在最后的 fc 后面再加一个 nn.Softmax(),还是说写成下面这样:
pred = nn.Softmax(model(X))
loss = loss_fn(pred, y)
这个样子?谢谢大家
1
raycool 2021-11-18 18:38:12 +08:00
没记错的话好像 CrossEntropyLoss 是先调用了 softmax
|
2
oblivious 2021-11-18 18:40:15 +08:00 1
不需要加 nn.Softmax ,nn.CrossEntropyLoss 在计算 loss 的时候,会帮你把最后一层的输入做 softmax ,你可以仔细阅读 https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html#torch.nn.CrossEntropyLoss 的计算 loss 的公式。
|
3
houshuu 2021-11-18 18:42:23 +08:00
因为 CrossEntropyLoss 融合了 LogSoftmax 和 NLLLoss.
可以看看[官方文档]( https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html), 这个问题算是老生常谈了. |
4
LeeReamond OP |
5
oblivious 2021-11-18 20:12:10 +08:00
|
6
houshuu 2021-11-18 20:17:59 +08:00
@LeeReamond ReLU 依旧是最常用的, 但是我这两年挺爱用 Leaky ReLU 的. 网上也有不少关于激活函数的对比文章, 个人觉得还是需要针对不同任务, 不同知识领域来选用. 但是差别很大倒是也没有.
|
7
linbo0518 2021-11-19 09:56:27 +08:00 via iPhone
具体为什么 torch 里这么写,其实主要是 softmax 中有 exp ,本身有数值稳定性的问题,ce loss 里有 log ,两个函数可以抵消,整合到一起又更好的数值稳定性,torch 里叫 logsoftmax
具体可以参考这篇 blog: https://freemind.pluskid.org/machine-learning/softmax-vs-softmax-loss-numerical-stability/ |