RuntimeError: invalid argument 2: upper bound and larger bound inconsistent with step sign at /Users/soumith/code/builder/wheel/pytorch-src/aten/src/TH/generic/THTensorMath.cpp:2948

I don’t know how mean this error on my script:

import os
import glob
from torch import nn
import torch
from torch.utils.data import Dataset, DataLoader
import torchvision.transforms as transforms
import tensorflow as tf
from PIL import Image
from torch.autograd.variable import Variable
#cat
#Concatena la data sequenza di tensori seq nella dimensione specificata.
# Tutti i tensori devono avere la stessa forma (eccetto la dimensione concatenante) o essere vuoti.
class MySampler(torch.utils.data.Sampler):
    def __init__(self, end_idx, seq_length):
        indices = []
        for i in range(len(end_idx) - 1):
            start = end_idx[i]
            end = end_idx[i + 1] - seq_length
            indices.append(torch.arange(start, end))
        indices = torch.cat(indices)
        self.indices = indices

    def __iter__(self):
        indices = self.indices[torch.randperm(len(self.indices))]
        return iter(indices.tolist())

    def __len__(self):
        return len(self.indices)


class MyDataset(Dataset):

    def __init__(self, image_paths, seq_length, transform, length):
        self.image_paths = image_paths
        self.seq_length = seq_length
        self.transform = transform
        self.length = length

    def __getitem__(self, index):
        start = index
        end = index + self.seq_length
        print('Getting images from {} to {}'.format(start, end))
        indices = list(range(start, end))
        images = []
        for i in indices:
            image_path = self.image_paths[i][0]
            image = Image.open(image_path)
            if self.transform:
                image = self.transform(image)
            images.append(image)
        x = torch.stack(images)
        y = torch.tensor([self.image_paths[start][1]], dtype=torch.long)

        return x, y

    def __len__(self):
        return self.length


root_dir = '/.../train'
class_paths = [d.path for d in os.scandir(root_dir) if d.is_dir]

class_image_paths = []
end_idx = []
for c, class_path in enumerate(class_paths):
    for d in os.scandir(class_path):
        if d.is_dir:
            paths = sorted(glob.glob(os.path.join(d.path, '*.jpg')))
            # Add class idx to paths
            paths = [(p, c) for p in paths]
            class_image_paths.extend(paths)
            end_idx.extend([len(paths)])

end_idx = [0, *end_idx]
end_idx = torch.cumsum(torch.tensor(end_idx), 0)#Restituisce la somma cumulativa di elementi di input nella dimensione dim
seq_length = 30# è importante settare la dimensione delle immagini che prendo

sampler = MySampler(end_idx, seq_length)
transform = transforms.Compose([
    transforms.Resize((32, 32)),
    transforms.ToTensor()
])

dataset = MyDataset(
    image_paths=class_image_paths,
    seq_length=seq_length,
    transform=transform,
    length=len(sampler))

data_loader = DataLoader(
    dataset,
    batch_size=1,
    sampler=sampler,
    shuffle = True
)

Hi,

I guess that when you run torch.arange(start, end), end is smaller than start and so since the default step between them is 1, this is invalid. You should either make the step -1 or make sure that start < end.

Hi, thanks for answering me so fast,
So what would you do specifically? What should I change?

Hi,

I would print the value of start and end at that line : indices.append(torch.arange(start, end)) and check that they are what you expect.

I made this change to the code because I realized that at the last iteration ‘start = tensor (1054) and end = tensor (1028)’, but I would probably lose data.
Do you have any better ideas?

class MySampler(torch.utils.data.Sampler):
    def __init__(self, end_idx, seq_length):
        indices = []
        for i in range(len(end_idx) - 1):
            start = end_idx[i]
            end = end_idx[i + 1] - seq_length
            if start > end:
                pass
            else:
                indices.append(torch.arange(start, end))
        indices = torch.cat(indices)
        self.indices = indices

Or maybe this one

class MySampler(torch.utils.data.Sampler):
    def __init__(self, end_idx, seq_length):
        indices = []
        for i in range(len(end_idx) - 1):
            start = end_idx[i]
            end = end_idx[i + 1] - seq_length
            if start > end:
                indices.append(torch.arange(end, start))
            else:
                indices.append(torch.arange(start, end))
        indices = torch.cat(indices)
        self.indices = indices