Data Loader seems to be pulling the same image

Jordan_Howell: <p>Hi.  It seems to me that my data loader is pulling the same image.  It’s transforming it differently but it’s still the same image.</p>
<p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/e/9/e92772f5a00535cc52b901370fe5a39cda5ee0fa.jpeg" data-download-href="https://discuss.pytorch.org/uploads/default/e92772f5a00535cc52b901370fe5a39cda5ee0fa" title="image"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/e/9/e92772f5a00535cc52b901370fe5a39cda5ee0fa_2_690x300.jpeg" alt="image" data-base62-sha1="xgzLJfFBQ358AKDBucZxes4Xnfk" width="690" height="300" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/e/9/e92772f5a00535cc52b901370fe5a39cda5ee0fa_2_690x300.jpeg, https://discuss.pytorch.org/uploads/default/original/3X/e/9/e92772f5a00535cc52b901370fe5a39cda5ee0fa.jpeg 1.5x, https://discuss.pytorch.org/uploads/default/original/3X/e/9/e92772f5a00535cc52b901370fe5a39cda5ee0fa.jpeg 2x" data-dominant-color="7F8A9D"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">805×350 86.8 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
<p>I would expect it to pull 10 different images with each batch of 10.</p>
<p>Below is the data loader:</p>
<pre><code class="lang-auto">class Inspection_Dataset(Dataset):
        """
        df: Dataframe containing all categorical, numerical and image columns
        numerical columns: list of numerical columns
        cat_columns: list of categorical columns
        image: column containing image file name
        root_dir: column containing root directory
        
        """
        def __init__(self, df, numerical_columns = None,
                     cat_columns = None,
                     image = None, 
                     root_dir = None, 
                     label = None, 
                     transform = None):
            
            #df
            self.df = df
            #transform
            self.transform = transform
            #image
            self.image_column = image
            self.root_dir = root_dir
            
            #length
            self.n = df.shape[0]
            
            #output column
            self.label = np.array(self.df.loc[:, label])
           
            #cat columns
            self.cat_columns = cat_columns if cat_columns else []
            self.numerical_columns = [col for col in df[numerical_columns]]
                            
            if self.cat_columns:
                for column in self.cat_columns:
                    df[column] = df.loc[:, column].astype('category')
                    df[column] = df[column].cat.codes
                self.cat_columns = np.array(df[cat_columns]) 
            else:
                self.cat_columns = np.zeros((self.n, 1))  
            
            #numerical columns
            if self.numerical_columns:
                self.numerical_columns = df[self.numerical_columns].astype(np.float32).values
            else:
                self.numerical_columns = np.zeros((self.n, 1))   
                     
        def __len__(self):
            return self.n

            
        def __getitem__(self, idx):
            idx = list(self.df.index)
            
            image = Image.open(os.path.join(self.df.loc[idx, self.root_dir].values[0],
                                              self.df.loc[idx, self.image_column].values[0]))
            
            image = self.transform(image)

            return self.label[idx], self.numerical_columns[idx], self.cat_columns[idx], image
</code></pre>
<p>Below is the code I used to test the data loader/print the images.</p>
<pre><code class="lang-auto">train_data = Inspection_Dataset(train_sample,
                                numerical_columns = numerical_columns,
                                cat_columns = non_loca_cat_columns,
                                image = 'file',
                                root_dir = 'root',
                                label = 'target',
                                transform = train_transform)

train_loader = DataLoader(train_data, batch_size = 10, shuffle = True)

count = 50
for i in range(count):
    for b , (label, numericals, cats, image) in enumerate(train_loader):
        break
   
print('Label:', label.numpy())

im = make_grid(image, nrow=5)  # the default nrow is 8

# Inverse normalize the images
inv_normalize = transforms.Normalize(
    mean=[-0.485/0.229, -0.456/0.224, -0.406/0.225],
    std=[1/0.229, 1/0.224, 1/0.225]
)
im_inv = inv_normalize(im)

# Print the images
plt.figure(figsize=(12,4))
plt.imshow(np.transpose(im_inv.numpy(), (1, 2, 0)));


What am I missing here?</code></pre>

ptrblck: <p>Could you check the path you are using to open the image:</p>
<pre><code class="lang-python">os.path.join(self.df.loc[idx, self.root_dir].values[0], self.df.loc[idx, self.image_column].values[0])
</code></pre>
<p>Could it be that <code>.values[0]</code> is indexing the first image only?</p>

Jordan_Howell: <p>The image path is legit.  When I take the <code>[0]</code> off of the values, I get the following error:</p>
<pre><code class="lang-auto">
  File "&lt;ipython-input-120-d05164b59f9d&gt;", line 79, in &lt;module&gt;
    for label, numericals, cats, image in train_loader:

  File "C:\Users\JORDAN.HOWELL.GITDIR\AppData\Local\Continuum\anaconda3\envs\torch_env\lib\site-packages\torch\utils\data\dataloader.py", line 345, in __next__
    data = self._next_data()

  File "C:\Users\JORDAN.HOWELL.GITDIR\AppData\Local\Continuum\anaconda3\envs\torch_env\lib\site-packages\torch\utils\data\dataloader.py", line 385, in _next_data
    data = self._dataset_fetcher.fetch(index)  # may raise StopIteration

  File "C:\Users\JORDAN.HOWELL.GITDIR\AppData\Local\Continuum\anaconda3\envs\torch_env\lib\site-packages\torch\utils\data\_utils\fetch.py", line 44, in fetch
    data = [self.dataset[idx] for idx in possibly_batched_index]

  File "C:\Users\JORDAN.HOWELL.GITDIR\AppData\Local\Continuum\anaconda3\envs\torch_env\lib\site-packages\torch\utils\data\_utils\fetch.py", line 44, in &lt;listcomp&gt;
    data = [self.dataset[idx] for idx in possibly_batched_index]

  File "&lt;ipython-input-120-d05164b59f9d&gt;", line 57, in __getitem__
    self.df.loc[idx, self.image_column].values))

  File "C:\Users\JORDAN.HOWELL.GITDIR\AppData\Local\Continuum\anaconda3\envs\torch_env\lib\ntpath.py", line 76, in join
    path = os.fspath(path)

TypeError: expected str, bytes or os.PathLike object, not numpy.ndarray
</code></pre>
<p>I get the same if I take the whole <code>values[0]</code> off.</p>

Jordan_Howell: <p>When I put <code>value[i]</code> I get different pictures but the same picture per batch like the below:</p>
<p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/c/7/c76a34f91c5162edebd2df39649e3749fa7ac90b.jpeg" data-download-href="https://discuss.pytorch.org/uploads/default/c76a34f91c5162edebd2df39649e3749fa7ac90b" title="image"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/c/7/c76a34f91c5162edebd2df39649e3749fa7ac90b_2_690x301.jpeg" alt="image" data-base62-sha1="ss6yXFl4WBrKeKZPnbBx9RgxDGH" width="690" height="301" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/c/7/c76a34f91c5162edebd2df39649e3749fa7ac90b_2_690x301.jpeg, https://discuss.pytorch.org/uploads/default/original/3X/c/7/c76a34f91c5162edebd2df39649e3749fa7ac90b.jpeg 1.5x, https://discuss.pytorch.org/uploads/default/original/3X/c/7/c76a34f91c5162edebd2df39649e3749fa7ac90b.jpeg 2x" data-dominant-color="929BA4"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">804×351 99.4 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
<p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/6/9/69f88204fa71a493ac2016f50eeeb3d0e8e8167f.jpeg" data-download-href="https://discuss.pytorch.org/uploads/default/69f88204fa71a493ac2016f50eeeb3d0e8e8167f" title="image"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/6/9/69f88204fa71a493ac2016f50eeeb3d0e8e8167f_2_690x302.jpeg" alt="image" data-base62-sha1="f7syIZLlN1Ytxd6lRPbjeYaM7Ir" width="690" height="302" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/6/9/69f88204fa71a493ac2016f50eeeb3d0e8e8167f_2_690x302.jpeg, https://discuss.pytorch.org/uploads/default/original/3X/6/9/69f88204fa71a493ac2016f50eeeb3d0e8e8167f.jpeg 1.5x, https://discuss.pytorch.org/uploads/default/original/3X/6/9/69f88204fa71a493ac2016f50eeeb3d0e8e8167f.jpeg 2x" data-dominant-color="99A79A"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">803×352 121 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
<p>I think it’s something to do with batches.  When I change to batch of 1, I get different pictures each time.   I’m not sure how batches works with the custom datasets and how to get them to pull correctly.</p>

ptrblck: <aside class="quote no-group" data-username="Jordan_Howell" data-post="4" data-topic="87010">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/jordan_howell/48/16421_2.png" class="avatar"> Jordan_Howell:</div>
<blockquote>
<p>I’m not sure how batches works with the custom datasets and how to get them to pull correctly.</p>
</blockquote>
</aside>
<p>The <code>Dataset.__getitem__</code> will get an <code>index</code> as the argument from the <code>DataLoader</code> to create a batch.<br>
These indices will be in the range <code>[0, len(dataset)-1]</code>, so you would only have to make sure to load each corresponding sample using the passed <code>index</code>.</p>
<p>I would still recommend to check the path and make sure that the <code>idx</code> is used to load the right path.</p>