如题,初学者,看官网的 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 ![]() 不需要加 nn.Softmax ,nn.CrossEntropyLoss 在计算 loss 的时候,会帮你把最后一层的输入做 softmax ,你可以仔细阅读 https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html#torch.nn.CrossEntropyLoss 的计算 loss 的公式。 |
![]() | 3 < href="/member/houshuu" class="dark">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/ |