Pick a loss that matches your task — and read the input contract
Most "my model isn't learning" stories trace back to a mismatch between the loss function and what the model outputs. The fix is usually a one-line change once you've spotted it.
Classification
nn.CrossEntropyLoss— multi-class. Inputs: raw logits shape(N, C); targets: int64 class indices shape(N,). Combines log_softmax + NLL internally for numerical stability — do NOT softmax before it.nn.BCEWithLogitsLoss— binary OR multi-label. Inputs: raw logits; targets: floats in {0, 1}. Combines sigmoid + BCE for stability — do NOT sigmoid before it.nn.NLLLoss— multi-class but expects log-probabilities instead of logits. Use only if you've already applied log_softmax.
Regression
nn.MSELoss— mean squared error. The default for regression. Penalizes outliers heavily because of the square.nn.L1Loss— mean absolute error. More robust to outliers.nn.SmoothL1Loss/nn.HuberLoss— L2 near zero, L1 in the tails. The "best of both" for noisy regression.
Less common but useful
nn.KLDivLoss— KL divergence between two distributions. Used in knowledge distillation.nn.CosineEmbeddingLoss— for similarity-based learning (face verification, embedding similarity).nn.TripletMarginLoss— for metric learning where you have anchor/positive/negative triples.