Change single label to multi label classification


To implement the prediction “this is NOT an object of classification a, b, c”, i am turning my single label classification to a multi label classification.

it feels suspiciously easy - so i assume i am missing something?
here’s what i did so far:
i collected all my image paths/names and labels in a cvs file with two columns
‘fname’ and ‘labels’

i read the cvs as df

then i define the datablock

data = DataBlock(

  • blocks=(ImageBlock, MultiCategoryBlock),*
  • get_x=ColReader(‘fname’),*
  • splitter=RandomSplitter(valid_pct=0.2, seed=42),*
  • get_y=ColReader(‘labels’, label_delim=’ '),*
  • item_tfms=[Resize(224, method=‘pad’, pad_mode=‘zeros’)]*
    (this is almost identical the the single label DataBlock)

then i ‘create’ dataloaders

dls = data.dataloaders(df)
(identical to single label version)

and then i ‘create’ the learner

learn = vision_learner(dls, ‘convnext_tiny_in22ft1k’, metrics=partial(accuracy_multi, thresh=0.25))

which again is almost identical to the single label version
except that i changed the metrics to accuracy_multi

and then i run learn.fine_tune…

is there anything i am missing?
in older posts/youtube videos i see the loss function BCEwithlogitslossflat() mentioned, but i wonder if that is outdated by now?

thanks again for any help. :slight_smile:

yes, it doesn’t seem to work.
accuracy_mult reaches very high numbers, but it only ever identifies only one category (of over 20)

looks like i need to do some more reading…

See here for and example of multi-label: Lesson 3 - Multi-Label Classification | walkwithfastai

Also, just to make sure: metrics (used to evaluate the prediction) is not the same as loss function (used during training/back-propagation).

yep, I learnt that last week.

the BCEwithlogitslossflat() function that I mentioned is the default loss function when multilabel classification is done. with threshold set to 0.5 by default.