Loading and preprocessing Images initially

Hi all,

is there an easy way to initially load Images into the ImageList class? I figured out that the Images are not fetched before ImageList -> get -> open is invoked. This can lead to increasing training duration. I suppose it is done that way to keep memory low?!?

I did a work around to load a small MNIST-set initially here. The full load is happening through from_df():

class PixelImageItemList(ImageList):
    
    def __init__(self, myimages = {}, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.myimages = myimages 
    
    def open(self,fn):
        return self.myimages.get(fn)
    
    @classmethod
    def from_df(cls, df:DataFrame, path:PathOrStr, cols:IntsOrStrs=0, folder:PathOrStr=None, suffix:str='', **kwargs)->'ItemList':
        "Get the filenames in `cols` of `df` with `folder` in front of them, `suffix` at the end."
        res = super().from_df(df, path=path, cols=cols, **kwargs)
        
        # full load of all images
        for i, row in df.drop(labels=['label','fn'],axis=1).iterrows():
            # Numpy to Image conversion from
            # https://www.kaggle.com/heye0507/fastai-1-0-with-customized-itemlist
            img_pixel = row.values.reshape(28,28)
            img_pixel = np.stack((img_pixel,)*3,axis=-1)
            res.myimages[res.items[i]]=vision.Image(pil2tensor(img_pixel,np.float32).div_(255))

        return res

It speeds up training time by x15.

1 Like

Thank you for posting this!

With the Kannada MNIST, I also noticed that the code took a suspiciously long time to run, and suspected that it was due to the open function accessing the DataFrame each time a digit was needed. I was a bit stumped on how to speed up the process, and was happy to find your elegant solution.

I incorporated your code into my current Kannada MNIST attempts using model ensembling. This speed up will allow my models to train a bit longer, hopefully improving the score.

1 Like

I’m glad it helped. Sadly, when I used get_transforms(…) performance went down again. I didn’t looked up where transform gets applied. But learner.mixup() works fine.
I add some transformation during preprocessing. You can see it in the public kernel now where I just added a channel with a blurred representation of the image.

Btw, I used one of your early kernels as my starter. So thanks for sharing.