How to create label in custom dataset for multi-label classification?

Nisucuk: <p>I have 3 separate image folders for train, test and validation set.<br>
Both train and validation set have multiple labels of varying number.<br>
The labels are provided in a .csv file where 1st column is filename of images in training set and second column has varying number of labels.</p>
<p>import torch<br>
import pandas as pd<br>
df= pd.read_csv(‘/home/nis/Downloads/trialdata/Training-Concepts.csv’,sep=‘;’,header=None)<br>
print(df.head())</p>
<pre><code>             0                                             1
</code></pre>
<p>0  ROCO_CLEF_07350                             C0203126,C0203051<br>
1  ROCO_CLEF_19073  C0772294,C0023884,C0221198,C0412555,C0041618<br>
2  ROCO_CLEF_60501           C0233492,C2985494,C0262950,C1306232<br>
3  ROCO_CLEF_05564                             C0521530,C0817096<br>
4  ROCO_CLEF_55020                             C0935598,C1184743</p>
<p>I created a custom dataset named myCustomDataset  reading pytorch tutorials.<br>
Is this approach right?</p>
<p>class myCustomDataset(Dataset):<br>
“”“my dataset.”“”</p>
<pre><code>def __init__(self, csv_file, root_dir, transform=None):
    """
    Args:
        csv_file (string): Path to the csv file with annotations.
        root_dir (string): Directory with all the images.
        transform (callable, optional): Optional transform to be applied
            on a sample.
    """
    self.conceptframe = pd.read_csv(csv_file,sep=';',header=None)
    self.root_dir = root_dir
    self.transform = transform

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

def __getitem__(self, index):
    img_name = os.path.join(self.root_dir,
                            self.conceptframe.iloc[index, 0])
    image = io.imread(img_name)
    label = self.conceptframe.iloc[index, 1]
    sample = {'image': image, 'label': label}

    if self.transform:
        sample = self.transform(sample)

    return sample
</code></pre>
<p>Now,I need to use transfer learning Resnet 50.<br>
If, i am not wrong, I need to use nn.BCEloss<br>
and i need to use sigmoid Function.<br>
But I could not know how to use it.I was doubtful about it.<br>
The maximum number of labels is 100 per image.<br>
If i am not wrong, I should replace 2 with 100, in nn.linear() and logSoftmax with sigmoid.</p>
<p>Please let me know how to solve it.<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/2X/9/9d698f6da17c74ef65a972097cb2b7b099d6c958.png" data-download-href="https://discuss.pytorch.org/uploads/default/9d698f6da17c74ef65a972097cb2b7b099d6c958" title="Screenshot_2019-06-20%20transferl(3)"><img src="https://discuss.pytorch.org/uploads/default/optimized/2X/9/9d698f6da17c74ef65a972097cb2b7b099d6c958_2_690x248.png" alt="Screenshot_2019-06-20%20transferl(3)" data-base62-sha1="msx7JiMMq0eUtpYgUS73g80Uvl6" width="690" height="248" srcset="https://discuss.pytorch.org/uploads/default/optimized/2X/9/9d698f6da17c74ef65a972097cb2b7b099d6c958_2_690x248.png, https://discuss.pytorch.org/uploads/default/original/2X/9/9d698f6da17c74ef65a972097cb2b7b099d6c958.png 1.5x, https://discuss.pytorch.org/uploads/default/original/2X/9/9d698f6da17c74ef65a972097cb2b7b099d6c958.png 2x" data-dominant-color="F0F1F1"><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">Screenshot_2019-06-20%20transferl(3)</span><span class="informations">976×351 26.6 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>

ptrblck: <p>If your target is a multi-hot encoded tensor, then your changes should work.<br>
I’m currently unsure, if <code>label</code> is a tensor or if it contains the class names as given in the data frame.<br>
Anyway, for a multi-label classification, your target should have the same output shape as the model’s output, containing ones for each active class.</p>
<p>Also, as you already explained, <code>nn.BCELoss</code> expects a sigmoid input.</p>

Nisucuk: <p>I think i have problem on how to create label in case of dataset. I followed the  link <a href="https://www.kaggle.com/mratsim/starting-kit-for-pytorch-deep-learning" class="inline-onebox" rel="noopener nofollow ugc">Starting Kit for PyTorch Deep Learning | Kaggle</a> .</p>
<p>I have 5529 labels(string concepts) in total. Just to check , i converted them to numpy array.<br>
Each of my image contains variable number of labels as you can see my training concepts.<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/2X/9/965fc4c59c058c1bc333f2ef5b92022719181642.png" data-download-href="https://discuss.pytorch.org/uploads/default/965fc4c59c058c1bc333f2ef5b92022719181642" title="Screenshot_2019-07-04%20validationsettrasnferlearnkaggle"><img src="https://discuss.pytorch.org/uploads/default/optimized/2X/9/965fc4c59c058c1bc333f2ef5b92022719181642_2_689x339.png" alt="Screenshot_2019-07-04%20validationsettrasnferlearnkaggle" data-base62-sha1="lsgNQjI7XGNu1BX4egq3dR9UMn0" width="689" height="339" srcset="https://discuss.pytorch.org/uploads/default/optimized/2X/9/965fc4c59c058c1bc333f2ef5b92022719181642_2_689x339.png, https://discuss.pytorch.org/uploads/default/optimized/2X/9/965fc4c59c058c1bc333f2ef5b92022719181642_2_1033x508.png 1.5x, https://discuss.pytorch.org/uploads/default/original/2X/9/965fc4c59c058c1bc333f2ef5b92022719181642.png 2x" data-dominant-color="F3F3F3"><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">Screenshot_2019-07-04%20validationsettrasnferlearnkaggle</span><span class="informations">1299×639 68.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><br>
I used multi binarizer to convert my labels into my multi hot encoded tensor.<br>
One of the link mentioned used the total number of classes within the multilabel binarizer , to convert the labels, whereas, most of the links don’t do so.<br>
When I run the following code,</p>
<p>class myCustomDataset(Dataset):<br>
“”“my dataset.”“”</p>
<pre><code>def __init__(self, csv_file, root_dir,img_ext,transform=None):
    """
    Args:
        csv_file (string): Path to the csv file with annotations.
        root_dir (string): Directory with all the images.
        transform (callable, optional): Optional transform to be applied
            on a sample.
    """
    #.iloc[:,0]=[[0]]
     #
    tmp_df = pd.read_csv(csv_file,sep=';',header=None)
    assert tmp_df.iloc[:,0].apply(lambda x: os.path.isfile(root_dir + x + img_ext)).all(), \
</code></pre>
<p>“Some images referenced in the CSV file were not found”<br>
<span class="hashtag-raw">#global</span> r</p>
<pre><code>    self.mlb = MultiLabelBinarizer()
    
    self.root_dir = root_dir
    self.img_ext = img_ext
    self.transform = transform

    self.X_train = tmp_df.iloc[:,0]
    self.y_train = self.mlb.fit_transform(tmp_df.iloc[:,1].str.split(',')).astype(np.float32)
    
    #'float'
    
def __len__(self):
    return len(self.X_train.index)

def __getitem__(self, index):
    
    img = Image.open(self.root_dir + self.X_train[index] + self.img_ext)
    img = img.convert('RGB')
    if self.transform is not None:
        img = self.transform(img)
    
    label =torch.from_numpy(self.y_train[index])
    #from_numpy(self.y[index])
    return img, label
</code></pre>
<p>After this i print the following code,I made a   custom dataset and then dataloader accordingly:</p>
<p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/2X/6/64a9faf594080f29d52b4b7e9254ef40086d9bd9.jpeg" data-download-href="https://discuss.pytorch.org/uploads/default/64a9faf594080f29d52b4b7e9254ef40086d9bd9" title="first"><img src="https://discuss.pytorch.org/uploads/default/optimized/2X/6/64a9faf594080f29d52b4b7e9254ef40086d9bd9_2_690x325.jpeg" alt="first" data-base62-sha1="emvVxV1qOI95Y2Z1MQb9qemTbYZ" width="690" height="325" srcset="https://discuss.pytorch.org/uploads/default/optimized/2X/6/64a9faf594080f29d52b4b7e9254ef40086d9bd9_2_690x325.jpeg, https://discuss.pytorch.org/uploads/default/original/2X/6/64a9faf594080f29d52b4b7e9254ef40086d9bd9.jpeg 1.5x, https://discuss.pytorch.org/uploads/default/original/2X/6/64a9faf594080f29d52b4b7e9254ef40086d9bd9.jpeg 2x" data-dominant-color="F2F3F2"><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">first</span><span class="informations">854×403 43.3 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>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/2X/d/df68b2ef0bc2f0ff26d9276b5dab4802c97f06c0.jpeg" data-download-href="https://discuss.pytorch.org/uploads/default/df68b2ef0bc2f0ff26d9276b5dab4802c97f06c0" title="second"><img src="https://discuss.pytorch.org/uploads/default/optimized/2X/d/df68b2ef0bc2f0ff26d9276b5dab4802c97f06c0_2_690x430.jpeg" alt="second" data-base62-sha1="vSmN7YvTwuPjVrZ8Ce4RKJZ1Mwo" width="690" height="430" srcset="https://discuss.pytorch.org/uploads/default/optimized/2X/d/df68b2ef0bc2f0ff26d9276b5dab4802c97f06c0_2_690x430.jpeg, https://discuss.pytorch.org/uploads/default/original/2X/d/df68b2ef0bc2f0ff26d9276b5dab4802c97f06c0.jpeg 1.5x, https://discuss.pytorch.org/uploads/default/original/2X/d/df68b2ef0bc2f0ff26d9276b5dab4802c97f06c0.jpeg 2x" data-dominant-color="F0F1F0"><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">second</span><span class="informations">707×441 46.6 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 like to ask If i should provide my numpy array ‘r’ while writing<br>
self.mlb = MultiLabelBinarizer()<br>
inside the braces or not.<br>
I don’t know if i am going good or not.<br>
My other question is, why is  torch size 3233 in the later case.<br>
When i put  ‘r’ inside multilabel binarizer, my  label size in case of trainloader and validloader changes from 5216 and 3233 to 5528 for both and my torch size changes from 3323 to 5528.<br>
I am unable to understand which one is correct and how should i proceed ahead.<br>
Please provide me your suggestions.</p>