Please help to get EfficientNet working with MultiCategoryBlock

I got EfficientNet working well for PETS dataset, where only 1 label per image is enough. Unfortunately, when I tried EfficientNet with with multiple labels per image, I encountered a problem. After creating datablock with MultiCategoryBlock, I try to run fine_tune():

learner = Learner(dls, model, metrics=accuracy_multi, splitter=lambda m: [params(m._conv_stem), params(m._blocks), params(m._conv_head)]).to_fp16()
learner.fine_tune(5)

And I get the following error:

ValueError: Target size (torch.Size([1088])) must be the same as input size (torch.Size([64000]))

But if I run instead cnn_learner() with resnet, the same code works fine:

learner = cnn_learner(dls, resnet50, metrics=accuracy_multi).to_fp16()
learner.fine_tune(5)

But I cannot figure out how to make this work with EfficientNet. Perhaps I’m doing something wrong?

Planet dataset with fastai2 and EfficientNet.ipynb in Colab - here you can find full source code.

What does learn.loss_func give you?

learner = Learner(dls, model, metrics=accuracy_multi, splitter=lambda m: [params(m._conv_stem), params(m._blocks), params(m._conv_head)]).to_fp16()
learner.loss_func
FlattenedLoss of BCEWithLogitsLoss()

It is the same for both EfficientNet and resnet.

It turns out the fix is simple, I need to explicitly specify number of categories (num_classes) when creating EfficientNet model. Planet dataset has 17 tags, so num_classes=17.

model = EfficientNet.from_pretrained(model_name, advprop=True, num_classes=17)

1 Like

Ahhh yes. I was wondering about that. Another technique is to use create_body and create_head so it’s more fastai-like (fastai has it’s own head it uses). See my efficientnet notebook here:

1 Like