WZMIAOMIAO/deep-learning-for-image-processing · error · ValueError
images is expected to be a list of 3d tensors of shape [C, H
Error message
images is expected to be a list of 3d tensors of shape [C, H, W], got {} What it means
GeneralizedRCNNTransform.forward expects each input image to be a 3-D CHW tensor (channels, height, width). If any image has dim != 3 — usually because a batched 4-D tensor or a 2-D grayscale tensor was passed — it raises ValueError with the offending shape. Normalization and resizing operate per-image, so batching must happen outside the transform.
Source
Thrown at pytorch_object_detection/retinaNet/network_files/transform.py:243
_indent = '\n '
format_string += "{0}Normalize(mean={1}, std={2})".format(_indent, self.image_mean, self.image_std)
format_string += "{0}Resize(min_size={1}, max_size={2}, mode='bilinear')".format(_indent, self.min_size,
self.max_size)
format_string += '\n)'
return format_string
def forward(self,
images, # type: List[Tensor]
targets=None # type: Optional[List[Dict[str, Tensor]]]
):
# type: (...) -> Tuple[ImageList, Optional[List[Dict[str, Tensor]]]]
images = [img for img in images]
for i in range(len(images)):
image = images[i]
target_index = targets[i] if targets is not None else None
if image.dim() != 3:
raise ValueError("images is expected to be a list of 3d tensors "
"of shape [C, H, W], got {}".format(image.shape))
image = self.normalize(image) # 对图像进行标准化处理
image, target_index = self.resize(image, target_index) # 对图像和对应的bboxes缩放到指定范围
images[i] = image
if targets is not None and target_index is not None:
targets[i] = target_index
# 记录resize后的图像尺寸
image_sizes = [img.shape[-2:] for img in images]
images = self.batch_images(images) # 将images打包成一个batch
image_sizes_list = torch.jit.annotate(List[Tuple[int, int]], [])
for image_size in image_sizes:
assert len(image_size) == 2
image_sizes_list.append((image_size[0], image_size[1]))
image_list = ImageList(images, image_sizes_list)
return image_list, targetsView on GitHub (pinned to 1ec3fe6f37)
Solutions
- Pass a list of individual [C, H, W] tensors: model([img1, img2], targets) rather than a stacked batch.
- Convert grayscale to RGB: Image.open(p).convert('RGB') so tensors are always 3-D.
- Convert HWC to CHW: img.permute(2, 0, 1) or use transforms.ToTensor() which does it.
- If you have a batched tensor, split it: [images[i] for i in range(images.shape[0])].
Example fix
// before imgs, targets = next(iterator) # imgs: [B, C, H, W] stacked by collate model(imgs, targets) // after images = [img for img in imgs] # list of [C, H, W] model(images, targets)
Defensive patterns
Strategy: type-guard
Validate before calling
assert all(isinstance(img, torch.Tensor) and img.dim() == 3 for img in images), "each image must be a [C, H, W] tensor"
Type guard
def is_chw_image(img) -> bool:
import torch
return isinstance(img, torch.Tensor) and img.dim() == 3 and img.shape[0] in (1, 3) Try / catch
try:
outputs = model(images, targets)
except ValueError as e:
if "3d tensors of shape [C, H, W]" in str(e):
images = [im.squeeze(0) if im.dim() == 4 else im.permute(2, 0, 1) if im.dim() == 3 else im for im in [batched_or_raw]]
outputs = model(images, targets)
else:
raise Prevention
- Use transforms.ToTensor() which yields CHW tensors.
- Pass a list of images, never a default-collated batch tensor.
- Load all images with convert('RGB') to avoid 2-D grayscale tensors.
- Convert HWC (cv2/numpy) with permute(2, 0, 1) before the model.
When it happens
Trigger: Passing a DataLoader-collated [B, C, H, W] batch instead of a list of 3-D tensors; loading grayscale images with PIL convert('L') yielding [H, W]; passing the raw output of cv2.imread ([H, W, C], HWC instead of CHW).
Common situations: Custom training loops that batch with default collate; forgetting ToTensor() or image_layout conversion; grayscale datasets; mixing image-list API (torchvision detection models) with the standard batched API of classification models.
Understand the failure class
Background: Tensor shape mismatch errors ("must have shape", "expected shape ... got ..."): when tensor dimensions disagree with what an op or layer was told to expect — this error's family across 6 libraries.
Related errors
- Expected target boxes to be a tensorof shape [N, 4], got {:}
- Expected target boxes to be a tensorof shape [N, 4], got {:}
- No ground-truth boxes available for one of the images during
- No proposal boxes available for one of the images during tra
- backbone should contain an attribute out_channels specifying
AI-assisted analysis of WZMIAOMIAO/deep-learning-for-image-processing@1ec3fe6f37 (2026-08-30).
Data as JSON: /api/errors/7938aa80f53af1fb.
Report an issue: GitHub.