Transform vs ItemTransform (MidLevel-API)

I’m really getting a hard time wrapping my head around the difference between Transform and ItemTransform and why we might want to want to use one or the other when creating our one custom transforms using the MidLevel API.

Here is a screenshort from the mid-level api tutorial using the pets dataset from the official fastai docs:

Here is my notebook too: Colab

It says: To prevent a Transform from dispatching over a tuple, we just have to make it an ItemTransform.
Then checking the documentation, ItemTransform says: A transform that always take tuples as items

Don’t the two above statements contradict each other? Or what is dispatching in this case?

Also: My intuition is that ItemTransform is equivalent to item_tfms when using the DataBlock API. Is this true?

I’d appreciate if anyone can give me a simple explanation

1 Like

EDIT: I Have been doing some research and I found this

It explains that ItemTransform is the class to use to opt out of the default behavior of the Transform

It sheds some light, I still don’t get the difference completely, but I will leave this here in case someone else with the same question finds it useful or if my future self needs this

1 Like

To make it short, just use regular Transforms.
ItemTransforms it is a overcomplicated thing that is useful when you want to transform the x and y at the same time, it is rarely used in fastai anyway.
The notebooks is not very clear, as they don’t re create the ItemTransform after updating the class.

Try this:

class PetTfm(Transform):
    def __init__(self, vocab, o2i, lblr): self.vocab,self.o2i,self.lblr = vocab,o2i,lblr
    def encodes(self, o): return (resized_image(o), self.o2i[self.lblr(o)])
    def decodes(self, x): return TitledImage(x[0],self.vocab[x[1]])

pets = PetTfm(vocab,o2i,labeller)

dec = pets.decode(pets(items[0]))

this will fail as the transform is trying to decode each element of the tuple indepedently, if you replace the encodes by this:

def encodes(self, o): return [resized_image(o), self.o2i[self.lblr(o)]]

it will work, so as it says, the ItemTransform is deactivating the dispatch on the tuple.

1 Like

Nice Summary there. Thanks