ValueError: empty range for randrange() (0,-14, -14)

tavishjain: <p>I was building an Image Classification model using PyTorch, where I came across this error while training.</p>
<blockquote>
<p>ValueError: empty range for randrange() (0,-14, -14)</p>
</blockquote>
<p>I am using the dataset available on Kaggle <a href="https://www.kaggle.com/puneet6060/intel-image-classification" rel="noopener nofollow ugc">here</a>.<br>
I wasn’t able to identify what might be the issue here.<br>
I attaching the relevant code:</p>
<p>Model Definition:</p>
<pre><code class="lang-auto">class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = nn.Conv2d(3, 16, kernel_size = (3, 3))
        self.conv2 = nn.Conv2d(16, 64, kernel_size = (3, 3))
        self.conv3 = nn.Conv2d(64, 256, kernel_size = (3, 3))
        self.maxpool = nn.MaxPool2d(2, stride = 3)
        self.flatten = nn.Flatten()
        self.fc1 = nn.Linear(4*4*256, 256)
        self.fc2 = nn.Linear(256, 32)
        self.fc3 = nn.Linear(32, 10)
            
    def forward(self, image):
        image = F.relu(self.conv1(image))
        image = self.maxpool(image)
        image = F.relu(self.conv2(image))
        image = self.maxpool(image)
        image = F.relu(self.conv3(image))
        image = self.maxpool(image)
        
        image = self.flatten(image)
        
        image = F.relu(self.fc1(image))
        image = F.relu(self.fc2(image))
        image = image.reshape(image.shape[0], -1)
        image = F.relu(self.fc3(image))
        
        return image
        
model = Model()
</code></pre>
<p>And the training script:</p>
<pre><code class="lang-auto">device = 'cpu'
model = model.to(device)
optimizer = torch.optim.Adam(model.parameters(), lr = 0.01)
criterion = nn.CrossEntropyLoss()

epochs = 5
training_loss = []
accuracy = []
thresh = 50
iters = 0
total_loss = 0
for e in range(epochs):
    for sample, label in image_loader:
        sample, label = sample.to(device), label.to(device)
        optimizer.zero_grad()
        output = model(sample)
        loss = criterion(output, label)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
        if iters%thresh == 0:
            pred = torch.argmax(output, dim = 1)
            correct = pred.eq(label)
            acc = torch.mean(correct.float())
            print('[Epoch {}/{}] Iteration {} -&gt; Train Loss: {:.4f}, Accuracy: {:.3f}'.format(e+1, epochs, iters, loss/thresh, acc))
            training_loss.append(loss)
            accuracy.append(acc)
            total_loss = 0
        iters += 1
plt.plot(loss_list, label='loss')
plt.plot(acc_list, label='accuracy')
plt.legend()
plt.title('training loss and accuracy')
plt.show()
</code></pre>
<p>Also, the logs:</p>
<pre><code class="lang-auto">---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
&lt;ipython-input-22-db0270104083&gt; in &lt;module&gt;
     11 total_loss = 0
     12 for e in range(epochs):
---&gt; 13     for sample, label in image_loader:
     14         sample, label = sample.to(device), label.to(device)
     15         optimizer.zero_grad()

/opt/conda/lib/python3.7/site-packages/torch/utils/data/dataloader.py in __next__(self)
    361 
    362     def __next__(self):
--&gt; 363         data = self._next_data()
    364         self._num_yielded += 1
    365         if self._dataset_kind == _DatasetKind.Iterable and \

/opt/conda/lib/python3.7/site-packages/torch/utils/data/dataloader.py in _next_data(self)
    401     def _next_data(self):
    402         index = self._next_index()  # may raise StopIteration
--&gt; 403         data = self._dataset_fetcher.fetch(index)  # may raise StopIteration
    404         if self._pin_memory:
    405             data = _utils.pin_memory.pin_memory(data)

/opt/conda/lib/python3.7/site-packages/torch/utils/data/_utils/fetch.py in fetch(self, possibly_batched_index)
     42     def fetch(self, possibly_batched_index):
     43         if self.auto_collation:
---&gt; 44             data = [self.dataset[idx] for idx in possibly_batched_index]
     45         else:
     46             data = self.dataset[possibly_batched_index]

/opt/conda/lib/python3.7/site-packages/torch/utils/data/_utils/fetch.py in &lt;listcomp&gt;(.0)
     42     def fetch(self, possibly_batched_index):
     43         if self.auto_collation:
---&gt; 44             data = [self.dataset[idx] for idx in possibly_batched_index]
     45         else:
     46             data = self.dataset[possibly_batched_index]

&lt;ipython-input-16-449d83383611&gt; in __getitem__(self, idx)
     10     def __getitem__(self, idx):
     11         image = Image.open(self.data['filename'][idx])
---&gt; 12         image = self.transform(image)
     13         image = image.numpy().astype('float32')
     14         label = self.data['labels'][idx]

/opt/conda/lib/python3.7/site-packages/torchvision/transforms/transforms.py in __call__(self, img)
     59     def __call__(self, img):
     60         for t in self.transforms:
---&gt; 61             img = t(img)
     62         return img
     63 

/opt/conda/lib/python3.7/site-packages/torchvision/transforms/transforms.py in __call__(self, img)
    518             img = F.pad(img, (0, self.size[0] - img.size[1]), self.fill, self.padding_mode)
    519 
--&gt; 520         i, j, h, w = self.get_params(img, self.size)
    521 
    522         return F.crop(img, i, j, h, w)

/opt/conda/lib/python3.7/site-packages/torchvision/transforms/transforms.py in get_params(img, output_size)
    496             return 0, 0, h, w
    497 
--&gt; 498         i = random.randint(0, h - th)
    499         j = random.randint(0, w - tw)
    500         return i, j, th, tw

/opt/conda/lib/python3.7/random.py in randint(self, a, b)
    220         """
    221 
--&gt; 222         return self.randrange(a, b+1)
    223 
    224     def _randbelow(self, n, int=int, maxsize=1&lt;&lt;BPF, type=type,

/opt/conda/lib/python3.7/random.py in randrange(self, start, stop, step, _int)
    198             return istart + self._randbelow(width)
    199         if step == 1:
--&gt; 200             raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
    201 
    202         # Non-unit step argument supplied.

ValueError: empty range for randrange() (0,-14, -14)
</code></pre>

ptrblck: <p>I guess you are using a random crop transformation, which apparently fails.<br>
Could you post the code for the <code>Dataset</code> and the transformations you are passing to it?</p>

tavishjain: <p>Yes, I am using the RandomCrop transformation<br>
Here is the code:</p>
<pre><code class="lang-auto">class ImageDataset(Dataset):
    def __init__(self, data, transform = None):
        self.data = data
        if transform != None:
            self.transform = transform
        else:
            self.transform = transforms.Compose([transforms.ToTensor()])
    def __len__(self):
        return len(self.data)
    def __getitem__(self, idx):
        image = Image.open(self.data['filename'][idx])
        image = self.transform(image)
        image = image.numpy().astype('float32')
        label = self.data['labels'][idx]
        return image, label
    
transform = transforms.Compose([
    transforms.ColorJitter(),
    transforms.RandomCrop(128),
    transforms.RandomHorizontalFlip(), 
    transforms.RandomVerticalFlip(),
    transforms.ToTensor()
])
</code></pre>

ptrblck: <p>Are you making sure the images are not smaller than the crop size of <code>128</code>?<br>
I get a similar issue, if I pass small images to the transformation:</p>
<pre><code class="lang-python">img = TF.to_pil_image(torch.randn(3, 50, 50))
crop = transforms.RandomCrop(128)
out = crop(img)
&gt; RuntimeError: random_ expects 'from' to be less than 'to', but got from=0 &gt;= to=-77
</code></pre>
<p>The error message might be different, if you are using an older <code>torchvision</code>, since the random size sampling was changed in <a href="https://github.com/pytorch/vision/pull/2342">this PR</a> to <code>torch.randint</code>.</p>

tavishjain: <p>I figured it out. The image size was 150X150. It is working now. I replaced RandomCrop with Resize and the model is now training.</p>
<p>Can you help me on this ? <a href="https://discuss.pytorch.org/t/loss-remains-constant-unchanged/99630" class="inline-onebox">Loss remains constant/unchanged</a></p>