Main Ecosystems
HomePython CorePandas ReferenceNumPy ScientificFastAPI & PydanticDjango Enterprise
More Ecosystems
Environment & SetupRequests & HTTPAsyncIO ConcurrencyObject-Oriented OOPPyTorch Deep LearningScikit-Learn MLFlask FrameworkWeb ScrapingDatabase & ORMDevOps & Docker

RuntimeError: Expected scalar type Long but found Float in PyTorch

Verified FixPython 3.10+PyTorch 2.0+Silo: pytorch

Quick Fix / Solution Rapide

Cast target labels and lookup indices to 64-bit integer format using targets.long() or dtype=torch.long.

Root Cause Analysis

This error occurs when Python tries to pass a floating-point tensor (such as FloatTensor) into a PyTorch operation that strictly requires discrete integer indices (such as torch.LongTensor / int64).

1. Discrete Indices vs Continuous Predictions

Classification loss functions (including nn.CrossEntropyLoss and nn.NLLLoss) and indexing layers (such as nn.Embedding) expect discrete class labels that act as lookup indices. Indices must be discrete whole numbers (integers). When target labels are created as floating-point numbers, PyTorch cannot use them as discrete array indices and raises RuntimeError: Expected scalar type Long but found Float (or expected LongTensor).

2. Common Scenarios in Classification

This error frequently occurs when: (1) target labels are parsed from floating-point CSV columns; (2) label preprocessing involves normalization or division operations that implicitly coerce integers into floats; or (3) creating one-hot target tensors instead of sparse class index vectors for CrossEntropyLoss.

3. Resolving Label Type Mismatches

Cast target tensors using .long() or torch.as_tensor(labels, dtype=torch.long) before calculating the loss.

4. CrossEntropyLoss vs BCEWithLogitsLoss

Remember that nn.CrossEntropyLoss expects 1D integer class indices of shape (N,), whereas nn.BCEWithLogitsLoss expects floating-point probabilities of shape (N, 1) or (N, C).

Reproduction Code (MCVE)

Example: Bug Reproduction
import torch
import torch.nn as nn

criterion = nn.CrossEntropyLoss()
logits = torch.randn(2, 5)
# Targets created as float instead of long
targets = torch.tensor([1.0, 3.0])

# RuntimeError: Expected scalar type Long but found Float
loss = criterion(logits, targets)

Solution 1: Cast Target Tensor to Long (int64)

Cast label tensors to torch.long using .long() or specify dtype=torch.long during tensor instantiation.

Example: Recommended Solution
import torch
import torch.nn as nn

criterion = nn.CrossEntropyLoss()
logits = torch.randn(2, 5)
# Targets defined with explicit long dtype
targets = torch.tensor([1, 3], dtype=torch.long)

loss = criterion(logits, targets)
print('Loss computed successfully:', loss.item())

Solution 2: Use torch.as_tensor with Explicit Target Type

When converting from raw Python lists or NumPy arrays in custom Dataset classes, use torch.as_tensor with dtype=torch.long.

Example: Alternative Solution
import torch
import torch.nn as nn

criterion = nn.CrossEntropyLoss()
logits = torch.randn(2, 5)
raw_labels = [1.0, 3.0]  # Raw list with float values

targets = torch.as_tensor(raw_labels, dtype=torch.long)
loss = criterion(logits, targets)
print('Converted loss value:', loss.item())

A common misunderstanding is passing one-hot encoded targets of shape (batch_size, num_classes) to nn.CrossEntropyLoss. PyTorch's CrossEntropyLoss expects class indices (batch_size,) of dtype torch.long. Contrast this with binary classification using nn.BCEWithLogitsLoss, which requires targets of type torch.float32 matching logits shape. Always verify label ranges: class indices must be integers strictly within 0 <= target < num_classes.