Class Dataset, concatenating labels with the corresponding images

michelepy: <p>Hi everyone,<br>
I am new to Pytorch, and in the last couple of days I have been struggling with the class Dataset that lets you build your custom dataset.</p>
<p>I am working with this dataset (<a href="https://www.kaggle.com/ianmoone0617/flower-goggle-tpu-classification/kernels" rel="nofollow noopener">https://www.kaggle.com/ianmoone0617/flower-goggle-tpu-classification/kernels</a>) , the problem is that it has the images and their labels in separate folders, and I can’t figure out how to concatenate them.</p>
<p>I found this notebook (it’s not mine) where there is the code that performs the class Dataset, however I simply cannot understand it. The part I do not understand is the one where he iterates all files, could you guys be so kind to help me understand it? thank you so much in advance! <img src="https://discuss.pytorch.org/images/emoji/apple/sweat_smile.png?v=9" title=":sweat_smile:" class="emoji" alt=":sweat_smile:"></p>
<h1>class MyDataset(Dataset):</h1>
<pre><code>def __init__(self, image_dir, label_dir, transform=None):
    _images, _labels = [], []
    # total amount of dataset 
    _number = 0
    # Reading the categorical file
    label_df = pd.read_csv(label_dir)
    
    # Iterate all files including .jpg images 
    for subdir, dirs, files in tqdm(os.walk(image_dir)):
        for filename in files:
            if len(subdir.split(os.sep)) &gt;5:
                # 注意到 這裡如果不能讀檔一定是這裡發生問題,路徑要檢查一下
                corr_label = label_df[label_df['dirpath']==os.sep.join(subdir.split(os.sep)[5:])]['label'].values
                if corr_label.size!= 0 and filename.endswith(('jpg')):
                    _images.append(subdir + os.sep + filename)
                    _labels.append(corr_label)
                    _number+=1
    # Randomly arrange data pairs
    mapIndexPosition = list(zip(_images, _labels))
    random.shuffle(mapIndexPosition)
    _images, _labels = zip(*mapIndexPosition)

    self._image = iter(_images)
    self._labels = iter(_labels)
    self._number = _number
    self._category = label_df['label'].nunique()
    self.transform = transform
    
def __len__(self):
    return self._number

def __getitem__(self, index):    
    img = next(self._image)
    lab = next(self._labels)
    
    img = self._loadimage(img)
    if self.transform:
        img = self.transform(img)        
    return img, lab
 
def _categorical(self, label):
    return np.arange(self._category) == label[:,None]

def _loadimage(self, file):
    return Image.open(file).convert('RGB')

def get_categorical_nums(self):
    return self._category</code></pre>

bolt25: <p>I had a similar problem.<br>
This video will definitely help you understand how to write your own custom dataset class</p><div class="youtube-onebox lazy-video-container" data-video-id="ZoZHd0Zm3RY" data-video-title="How to build custom Datasets for Images in Pytorch" data-provider-name="youtube">
  <a href="https://www.youtube.com/watch?v=ZoZHd0Zm3RY" target="_blank" rel="noopener nofollow ugc">
    <img class="youtube-thumbnail" src="https://img.youtube.com/vi/ZoZHd0Zm3RY/maxresdefault.jpg" title="How to build custom Datasets for Images in Pytorch" width="690" height="388">
  </a>
</div>

<p>Feel free to ask if you still don’t get it.</p>
<p>Regards!</p>

michelepy: <p>Hi bolt25, thank you so much for your fast reply!<br>
I tried to implement the model, but when I create the DataLoader it gives me back this error: TypeError: join() argument must be str or bytes, not ‘int64’.<br>
I feel that the mistake is that I cannot properly attach the labels to the images.  I would be so grateful to understand this, thanks for your support!<br>
Here is the code I used:<br>
class MyDataset(Dataset):</p>
<pre><code>def __init__(self, csv_file, root_dir, transform=None):
    self.labels = pd.read_csv(csv_file)
    self.root_dir = root_dir
    self.transform = transform
    
def __len__(self):
    return len(self.labels)

def __getitem__(self, index):
    if torch.is_tensor(index):
        index = index.tolist()
        
    image_name = os.path.join(self.root_dir, self.labels.iloc[index, 0])
    image = io.imread(image_name)
    
    if self.transform:
        image = self.transform(image)
        
    return (image, labels)
</code></pre>
<p>ds = MyDataset(csv_file="…/input/flower-goggle-tpu-classification/flowers_idx.csv", root_dir="…/input/flower-goggle-tpu-classification/flower_tpu/flower_tpu/flowers_google/flowers_google", transform=transforms.ToTensor())</p>
<h2>This is the error:</h2>
<p>TypeError                                 Traceback (most recent call last)<br>
 in <br>
----&gt; 1 for image, label in data_dl:<br>
2     print(image)<br>
3     print(label)</p>
<p>/opt/conda/lib/python3.7/site-packages/torch/utils/data/dataloader.py in <strong>next</strong>(self)<br>
343<br>
344     def <strong>next</strong>(self):<br>
–&gt; 345         data = self._next_data()<br>
346         self._num_yielded += 1<br>
347         if self._dataset_kind == _DatasetKind.Iterable and \</p>
<p>/opt/conda/lib/python3.7/site-packages/torch/utils/data/dataloader.py in _next_data(self)<br>
383     def _next_data(self):<br>
384         index = self._next_index()  # may raise StopIteration<br>
–&gt; 385         data = self._dataset_fetcher.fetch(index)  # may raise StopIteration<br>
386         if self._pin_memory:<br>
387             data = _utils.pin_memory.pin_memory(data)</p>
<p>/opt/conda/lib/python3.7/site-packages/torch/utils/data/_utils/fetch.py in fetch(self, possibly_batched_index)<br>
42     def fetch(self, possibly_batched_index):<br>
43         if self.auto_collation:<br>
—&gt; 44             data = [self.dataset[idx] for idx in possibly_batched_index]<br>
45         else:<br>
46             data = self.dataset[possibly_batched_index]</p>
<p>/opt/conda/lib/python3.7/site-packages/torch/utils/data/_utils/fetch.py in (.0)<br>
42     def fetch(self, possibly_batched_index):<br>
43         if self.auto_collation:<br>
—&gt; 44             data = [self.dataset[idx] for idx in possibly_batched_index]<br>
45         else:<br>
46             data = self.dataset[possibly_batched_index]</p>
<p> in <strong>getitem</strong>(self, index)<br>
13             index = index.tolist()<br>
14<br>
—&gt; 15         image_name = os.path.join(self.root_dir, self.labels.iloc[index, 0])<br>
16         image = io.imread(image_name)<br>
17</p>
<p>/opt/conda/lib/python3.7/posixpath.py in join(a, *p)<br>
92                 path += sep + b<br>
93     except (TypeError, AttributeError, BytesWarning):<br>
—&gt; 94         genericpath._check_arg_types(‘join’, a, *p)<br>
95         raise<br>
96     return path</p>
<p>/opt/conda/lib/python3.7/genericpath.py in _check_arg_types(funcname, *args)<br>
151         else:<br>
152             raise TypeError(’%s() argument must be str or bytes, not %r’ %<br>
–&gt; 153                             (funcname, s.<strong>class</strong>.<strong>name</strong>)) from None<br>
154     if hasstr and hasbytes:<br>
155         raise TypeError(“Can’t mix strings and bytes in path components”) from None</p>
<p>TypeError: join() argument must be str or bytes, not ‘int64’</p>

bolt25: <p>Can you share a gist whats in the csv?<br>
Like what kind of labels does it have?<br>
Plus I think once you clear this error, this code will give one more error on the return line of your <strong>getitem</strong> function.</p>

michelepy: <p>Yep this is the inside of the csv:<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/4/2/42735edf69c1b5e9e798214523e3d9db7d24b8e1.png" data-download-href="https://discuss.pytorch.org/uploads/default/42735edf69c1b5e9e798214523e3d9db7d24b8e1" title="image"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/4/2/42735edf69c1b5e9e798214523e3d9db7d24b8e1_2_690x269.png" alt="image" data-base62-sha1="9tQGZtEO5NATCxaW4miK5geZMg9" width="690" height="269" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/4/2/42735edf69c1b5e9e798214523e3d9db7d24b8e1_2_690x269.png, https://discuss.pytorch.org/uploads/default/original/3X/4/2/42735edf69c1b5e9e798214523e3d9db7d24b8e1.png 1.5x, https://discuss.pytorch.org/uploads/default/original/3X/4/2/42735edf69c1b5e9e798214523e3d9db7d24b8e1.png 2x" data-dominant-color="272B32"><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">997×390 35.1 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><br>
I think that the problem is in the variable image_name = os.path.join(self.root_dir, self.labels.iloc[index, 0])<br>
but i really do not know why <img src="https://discuss.pytorch.org/images/emoji/apple/pensive.png?v=12" title=":pensive:" class="emoji" alt=":pensive:" loading="lazy" width="20" height="20"></p>
<p>p.s. yeah I noticed the error in the return of the getitem function already, but thanks!</p>

michelepy: <p>Also in case it is useful to you, this is the structure of the various folders:<br>
and the images are located in the last folder flowers_google<br>
<img src="https://discuss.pytorch.org/uploads/default/original/3X/7/b/7b407ba3f37477b615425f1442028d3bc4e9e9fc.png" alt="image" data-base62-sha1="hAkSKdM9L7a5jNtN2xc24KJKVac" width="578" height="446"></p>

bolt25: <p>Change the following line:-</p>
<aside class="quote no-group" data-username="michelepy" data-post="5" data-topic="85762">
<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/michelepy/48/25686_2.png" class="avatar"> michelepy:</div>
<blockquote>
<p>image_name = os.path.join(self.root_dir, self.labels.iloc[index, 0])</p>
</blockquote>
</aside>
<p>To:-<br>
<code>image_name = os.path.join(self.root_dir, str(self.labels.iloc[index, 0]))</code></p>
<p>and your label would be-<br>
<code>labels = self.labels.iloc[index, 1]</code></p>
<p>I hope this works out for you!</p>
<p>Feel free to text back!<br>
Regards</p>

michelepy: <p>Hi Dharmik! I just wanted to let you know that thanks to your advices I was able to build the dataset class, thank you so much man, I really appreciate!<br>
At the end I was able to attach each image to its label by its id, and then I only had to add the format extension at the end of each image_name and the class was able to unite them!<br>
Have a happy day! <img src="https://discuss.pytorch.org/images/emoji/apple/grin.png?v=9" title=":grin:" class="emoji" alt=":grin:"></p>

bolt25: <p>Congrats brother!<br>
Happy to help!<br>
Just make sure you click on the solution box to make my answer the solution to this thread! Maybe it’ll help others!</p>