Have a look at Ignite 21. They have some utilities and abstractions which you may find useful.
You don’t need an activation function for certain loss functions.
nn.CrossEntropyLoss for example expects logits, so that you shouldn’t have any activation at the end of your model.
nn.NLLLoss on the other have expects log probabilities, so that you would have to add a nn.LogSoftmax as the last layer.
Have a look at the loss functions in the docs 11 for more information.
This is mostly done for numerical stability reasons. E.g. calling log on softmax separately might not be stable.