PyTorch loss target shape checker
For an output of shape (N, C), nn.CrossEntropyLoss wants a target of shape (N) holding class indices with dtype torch.long, not a target of shape (N, C). Enter your output shape below and the tool gives the exact target shape and dtype your loss requires.
Built by Michael Lip · verified 15 August 2026
Runs entirely in your browser. Nothing you type is sent anywhere.
Why an index target drops the class dimension
Two shapes get confused constantly. The input to a classification loss carries one score per class, so it is (N, C). The target carries one integer per sample saying which class is correct, so it is (N). The class dimension is absent by design, and that is what the documentation specifies.
“Target: If containing class indices, shape (), (N) or (N, d_1, d_2, ..., d_K) with K ≥ 1 in the case of K-dimensional loss where each value should be between [0, C). The target data type is required to be long when using class indices. If containing class probabilities, the target must be the same shape input, and each value should be between [0, 1].”
PyTorch documentation, torch.nn.CrossEntropyLoss, Shape section. Verified 15 August 2026.
Target shape contract for eight losses
N is the batch size, C the number of classes, and * means any number of dimensions. Every row below is the shape given in that loss function’s own documentation page.
| Loss | Input shape | Target shape | Target dtype | Docs |
|---|---|---|---|---|
CrossEntropyLoss | (C), (N, C) or (N, C, d1..dK) | (), (N) or (N, d1..dK) | torch.long | docs |
CrossEntropyLoss probabilities | (C), (N, C) or (N, C, d1..dK) | same shape as input | float | docs |
NLLLoss | (C), (N, C) or (N, C, d1..dK) | (), (N) or (N, d1..dK) | torch.long | docs |
BCEWithLogitsLoss | (*) | (*) same shape as input | float | docs |
BCELoss | (*) | (*) same shape as input | float | docs |
MSELoss | (*) | (*) same shape as input | float | docs |
L1Loss | (*) | (*) same shape as input | float | docs |
SmoothL1Loss | (*) | (*) same shape as input | float | docs |
KLDivLoss | (*) in log-space | (*) same shape as input | float | docs |
One honest caveat on that dtype column. CrossEntropyLoss is the only page of the eight that states the target dtype in prose. For the others the requirement shows up in the documented examples and in what the runtime accepts, so treat those rows as observed rather than quoted.
Reverse lookup, from the error back to the shape
These are the messages PyTorch raises when the contract is broken. They were reproduced against torch 2.8.0 with an input of shape (4, 3), so they are observed behaviour rather than documentation. The error strings come from the ATen kernel and appear on no documentation page.
| What you passed | What PyTorch raises | Fix |
|---|---|---|
target (4, 1) long | RuntimeError: 0D or 1D target tensor expected, multi-target not supported | target.squeeze(1) to get (4) |
target (4, 3) long, one-hot | RuntimeError: Expected floating point type for target with class probabilities, got Long | target.argmax(dim=1), or cast to float to use the probability mode |
target (4) float | RuntimeError: expected scalar type Long but found Float | target.long() |
| target value 5 with C = 3 | IndexError: Target 5 is out of bounds. | Values must be 0 to C-1 |
input (2,3,4), target (2,4,1) | RuntimeError: Expected target size [2, 4], got [2, 4, 1] | Drop the trailing dimension |
The first row is the one people hit most. A target arrives as (N, 1) from a dataframe column or a stray unsqueeze(1), and CrossEntropyLoss rejects any integer target with two or more dimensions against a 2D input, because the only legal index-target shape there is (N).
Related pages
This tool answers one question, which target shape and dtype a loss demands. For the neighbouring questions: the loss functions guide covers which loss to choose and what each one computes, expected dtype Float but got Long walks through casting a target, and input and target batch size don’t match covers the case where the batch dimension itself went missing.