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.

LossInput shapeTarget shapeTarget dtypeDocs
CrossEntropyLoss(C), (N, C) or (N, C, d1..dK)(), (N) or (N, d1..dK)torch.longdocs
CrossEntropyLoss probabilities(C), (N, C) or (N, C, d1..dK)same shape as inputfloatdocs
NLLLoss(C), (N, C) or (N, C, d1..dK)(), (N) or (N, d1..dK)torch.longdocs
BCEWithLogitsLoss(*)(*) same shape as inputfloatdocs
BCELoss(*)(*) same shape as inputfloatdocs
MSELoss(*)(*) same shape as inputfloatdocs
L1Loss(*)(*) same shape as inputfloatdocs
SmoothL1Loss(*)(*) same shape as inputfloatdocs
KLDivLoss(*) in log-space(*) same shape as inputfloatdocs

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 passedWhat PyTorch raisesFix
target (4, 1) longRuntimeError: 0D or 1D target tensor expected, multi-target not supportedtarget.squeeze(1) to get (4)
target (4, 3) long, one-hotRuntimeError: Expected floating point type for target with class probabilities, got Longtarget.argmax(dim=1), or cast to float to use the probability mode
target (4) floatRuntimeError: expected scalar type Long but found Floattarget.long()
target value 5 with C = 3IndexError: 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.