WZMIAOMIAO/deep-learning-for-image-processing · error · ValueError

sampler should be an instance of torch.utils.data.Sampler, b

Error message

sampler should be an instance of torch.utils.data.Sampler, but got sampler={}

What it means

GroupedBatchSampler validates in __init__ that the sampler argument is an instance of torch.utils.data.Sampler, because it iterates the sampler to build grouped batches. Passing any other object (e.g. a list, an iterator, or a function) raises ValueError with the repr of the object.

Source

Thrown at pytorch_object_detection/yolov3_spp/train_utils/group_by_aspect_ratio.py:39


class GroupedBatchSampler(BatchSampler):
    """
    Wraps another sampler to yield a mini-batch of indices.
    It enforces that the batch only contain elements from the same group.
    It also tries to provide mini-batches which follows an ordering which is
    as close as possible to the ordering from the original sampler.
    Arguments:
        sampler (Sampler): Base sampler.
        group_ids (list[int]): If the sampler produces indices in range [0, N),
            `group_ids` must be a list of `N` ints which contains the group id of each sample.
            The group ids must be a continuous set of integers starting from
            0, i.e. they must be in the range [0, num_groups).
        batch_size (int): Size of mini-batch.
    """
    def __init__(self, sampler, group_ids, batch_size):
        if not isinstance(sampler, Sampler):
            raise ValueError(
                "sampler should be an instance of "
                "torch.utils.data.Sampler, but got sampler={}".format(sampler)
            )
        self.sampler = sampler
        self.group_ids = group_ids
        self.batch_size = batch_size

    def __iter__(self):
        buffer_per_group = defaultdict(list)
        samples_per_group = defaultdict(list)

        num_batches = 0
        for idx in self.sampler:
            group_id = self.group_ids[idx]
            buffer_per_group[group_id].append(idx)
            samples_per_group[group_id].append(idx)
            if len(buffer_per_group[group_id]) == self.batch_size:
                yield buffer_per_group[group_id]

View on GitHub (pinned to 1ec3fe6f37)

Solutions

  1. Wrap the indices in torch.utils.data.SubsetRandomSampler or RandomSampler before passing it in.
  2. If you have a custom sampler, make it inherit from torch.utils.data.Sampler.
  3. If you only have an index list, convert it: sampler = torch.utils.data.sampler.SubsetRandomSampler(indices).

Example fix

// before
sampler = torch.randperm(len(dataset)).tolist()
batch_sampler = GroupedBatchSampler(sampler, group_ids, batch_size)
// after
from torch.utils.data import SubsetRandomSampler
sampler = SubsetRandomSampler(torch.randperm(len(dataset)).tolist())
batch_sampler = GroupedBatchSampler(sampler, group_ids, batch_size)
Defensive patterns

Strategy: type-guard

Validate before calling

from torch.utils.data import Sampler
assert isinstance(sampler, Sampler), type(sampler)

Type guard

from torch.utils.data import Sampler
def is_torch_sampler(s) -> bool:
    return isinstance(s, Sampler)

Try / catch

try:
    gbs = GroupedBatchSampler(sampler, group_ids, batch_size)
except ValueError as e:
    logging.error(f"bad sampler: {e}"); raise

Prevention

When it happens

Trigger: Constructing GroupedBatchSampler(sampler, group_ids, batch_size) where sampler is a plain list/iterator instead of a torch.utils.data.Sampler instance (e.g. RandomSampler, SequentialSampler, or a custom Sampler subclass).

Common situations: Passing range(len(dataset)) or a shuffled list directly; using a custom sampler that subclasses object/Iterator but not torch.utils.data.Sampler; adapting code from torchvision's references where a real sampler is created first.

Related errors


AI-assisted analysis of WZMIAOMIAO/deep-learning-for-image-processing@1ec3fe6f37 (2026-08-30). Data as JSON: /api/errors/46c2a49185657c4b. Report an issue: GitHub.