Returning multiple images with Dataloader

Mrig: <p>So I was working with a  problem of Siamese network which requires the dataloader to output two random images and 1/0 based on if they are of the same class.</p>
<pre><code class="lang-auto">class Siamese(Dataset):
    def __init__(self,train_df):
        self.train_df=train_df
      
    def __len__(self):
        return(len(self.train_df))
    
    def __getitem__(self,idx):
        if torch.is_tensor(idx):
            idx = idx.tolist()
        img1=self.train_df.iloc[random.randint(0,177),:]
        img2=self.train_df.iloc[random.randint(0,177),:]
        while(img1['target']!=img2['target']):
            IMG1=img1.iloc[0:-1]
            IMG2=img2.iloc[0:-1]
            return IMG1,IMG2, torch.from_numpy(np.array([img1['target']==img2['target']],dtype=np.float32))

data=Siamese(digits.data)
vis_dataloader = DataLoader(data,
                        shuffle=True,
                           batch_size=2)
dataiter = iter(vis_dataloader)
next(dataiter)
</code></pre>
<p>gave me an error<br>
TypeError                                 Traceback (most recent call last)<br>
 in <br>
----&gt; 1 next(dataiter)</p>
<p>G:\ana\lib\site-packages\torch\utils\data\dataloader.py in <strong>next</strong>(self)<br>
558         if self.num_workers == 0:  # same-process loading<br>
559             indices = next(self.sample_iter)  # may raise StopIteration<br>
–&gt; 560             batch = self.collate_fn([self.dataset[i] for i in indices])<br>
561             if self.pin_memory:<br>
562                 batch = _utils.pin_memory.pin_memory_batch(batch)</p>
<p>G:\ana\lib\site-packages\torch\utils\data_utils\collate.py in default_collate(batch)<br>
68         return [default_collate(samples) for samples in transposed]<br>
69<br>
—&gt; 70     raise TypeError((error_msg_fmt.format(type(batch[0]))))</p>
<p>TypeError: batch must contain tensors, numbers, dicts or lists; found &lt;class ‘NoneType’&gt;</p>
<p>Sorry if this a real silly question, I am new to pytorch and coding.</p>

Nikronic: <p>Hi,</p>
<p>I think there is problem with your conditioning that leads to <code>NoneType</code> in <code>IMG1</code> and <code>IMG2</code>. Try to write python a function outside of and test that your approach is currect or not. Actually, I do not know about your data structure but I cannot understand the idea behind <code>imgx</code> and <code>IMGx</code>, mostly here.</p>
<aside class="quote no-group" data-username="Mrig" data-post="1" data-topic="86730">
<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/mrig/48/14538_2.png" class="avatar"> Mrig:</div>
<blockquote>
<pre><code class="lang-auto">IMG1=img1.iloc[0:-1]
IMG2=img2.iloc[0:-1]
</code></pre>
</blockquote>
</aside>
<p>I tried to simulate your case using <code>mnist</code> and found no error except that <code>IMG1</code> and <code>IMG2</code> cannot be pandas series objects and you need to convert them to <code>np.array</code>.<br>
In this simulation, each input in dataframe has 769 columns where first ones are target label and other 768 are 28x28 pixels of image.<br>
Here is the code I used for MNIST:</p>
<pre><code class="lang-auto">
class Siamese(data.Dataset):
    def __init__(self,train_df):
        self.train_df=train_df
      
    def __len__(self):
        return(len(self.train_df))
    
    def __getitem__(self,idx):
        if torch.is_tensor(idx):
            idx = idx.tolist()
        img1=self.train_df.iloc[random.randint(0,self.__len__()),:]
        img2=self.train_df.iloc[random.randint(0,self.__len__()),:]
        while(img1[0]!=img2[0]):
            img1=self.train_df.iloc[random.randint(0,self.__len__()),:]
            img2=self.train_df.iloc[random.randint(0,self.__len__()),:]
            # img1 = img1.iloc[0:-1]
            # img2 = img2.iloc[0:-1]
            return np.array(img1[0]), np.array(img2[0]), torch.from_numpy(np.array([img1[0]==img2[0]],dtype=np.float32))

train_data=pd.read_csv('sample_data/mnist_train_small.csv')
dataset_train=Siamese(train_data)
vis_dataloader = data.DataLoader(dataset_train, shuffle=True, batch_size=1)
dataiter = iter(vis_dataloader)
next(dataiter)
</code></pre>
<p>Bests</p>

Mrig: <p>Thank You very much. <img src="https://discuss.pytorch.org/images/emoji/apple/grinning.png?v=9" title=":grinning:" class="emoji" alt=":grinning:"></p>
<pre><code class="lang-auto">IMG1=img1.iloc[0:-1]
IMG2=img2.iloc[0:-1]
</code></pre>
<p>the CSV, I was using had pixel values and in the last column the label.<br>
So I had used the pixel values to store in the IMGx.</p>