progers:

Your explanation suggests that LogSoftmax and NLLLoss networks work differently: they evidently drive the output linear layer to produce large logit-like dot products.


I don’t think it works differently, but removes the softmax from the model for better numerical stability.
If you take a look at the applied loss function in nn.CrossEntropyLoss 1, you see that the softmax is calculated first and the log is applied on its result.
While this works theoretically, you could run into numerical issues due to the limited floating point precision.
Instead of directly using the mentioned function and adding the softmax layer to the model (which would then output “probabilities” in the range [0, 1]), you are instead passing the activations of the last linear layer, and apply F.log_softmax  in nn.CrossEntropyLoss.
If you want to calculate the probabilities, you could of course apply F.softmax to the output and e.g. print it for debugging purposes. Don’t pass these F.softmax outputs to nn.CrossEntropyLoss, since internally F.log_softmax will be applied on them.