Dataloaders and L object is not callable

Hi, I am new to fast.ai and I find it really helpful and interesting.
This is my imports and the path for the image folders

import torchvision
import fastcore
from fastai import *
from fastai.vision.all import *
from fastai.callback import *
from fastai.basics import *
from fastai.data import *
import pandas as pd
import numpy
import matplotlib.pyplot as plt
%matplotlib inline

start_data = ‘/content/drive/MyDrive/ColabNotebooks/Datas/plantvillage-dataset/color’

the structure of the folders is

the getter function has this output that by my understanding works like it should

get_img_data = get_image_files(start_data)

(#54305) [Path('/content/drive/MyDrive/ColabNotebooks/Datas/plantvillage-dataset/color/Apple___Apple_scab/00075aa8-d81a-4184-8541-b692b78d398a___FREC_Scab 3335.JPG'),Path('/content/drive/MyDrive/ColabNotebooks/Datas/plantvillage-dataset/color/Apple___Apple_scab/01f3deaa-6143-4b6c-9c22-620a46d8be04___FREC_Scab 3112.JPG').....

this is the rest of my code that i had no error

#function that splits by default our data train–valid 80–20
seed = 42
splitter = RandomSplitter(seed=seed)

#get the labels from the folders of our items
get_y = parent_label

#block that we will use Image for images and Multi because is multi classification
blocks=(ImageBlock,MultiCategoryBlock)

#our batches
batches = 16

tfms = [Rotate(draw = rotate),
FlipItem(p=1.1),
Zoom(draw=1.5),
Brightness(draw=scale),
Contrast(draw=contrast),
Saturation(draw=saturation)
]

#we combine all the transforms
comp = setup_aug_tfms(tfms)

#item transforms for CPU
item_tfms = Resize(448)

#Transforms for batches in GPU
batch_tfms =[comp,Normalize.from_stats(*imagenet_stats)]

#Define our Datablock ready to be in a dls (dataloader)
plant= DataBlock(blocks=blocks,
get_items=get_img_data,
get_y=get_y,
splitter=splitter,
item_tfms=item_tfms,
batch_tfms=batch_tfms)

when i pass it in to the dataloader

dls= plant.dataloaders(start_data)

i have the following error and i tried to identify the problem or at least understand it but with no outcome

TypeError Traceback (most recent call last)
in ()
1 #Our dataloader
2 path= “/content/drive/MyDrive/ColabNotebooks/Datas/plantvillage-dataset/color”
----> 3 dls= plant.dataloaders(start_data)

1 frames
/usr/local/lib/python3.7/dist-packages/fastai/data/block.py in dataloaders(self, source, path, verbose, **kwargs)
111
112 def dataloaders(self, source, path=’.’, verbose=False, **kwargs):
→ 113 dsets = self.datasets(source, verbose=verbose)
114 kwargs = {**self.dls_kwargs, **kwargs, ‘verbose’: verbose}
115 return dsets.dataloaders(path=path, after_item=self.item_tfms, after_batch=self.batch_tfms, **kwargs)

/usr/local/lib/python3.7/dist-packages/fastai/data/block.py in datasets(self, source, verbose)
105 def datasets(self, source, verbose=False):
106 self.source = source ; pv(f"Collecting items from {source}", verbose)
→ 107 items = (self.get_items or noop)(source) ; pv(f"Found {len(items)} items", verbose)
108 splits = (self.splitter or RandomSplitter())(items)
109 pv(f"{len(splits)} datasets of sizes {’,’.join([str(len(s)) for s in splits])}", verbose)

TypeError: ‘L’ object is not callable

I would like some help to overcome this problem but also to understand it
thank you for your time

Since we’re in colab from what it seems like, what does this give you?

!pip3 show fastai fastcore
1 Like

Hi sir, yes i run it from collab.

Name: fastai Version: 2.5.3 Summary: fastai simplifies training fast and accurate neural nets using modern best practices Home-page: https://github.com/fastai/fastai/tree/master/ Author: Jeremy Howard, Sylvain Gugger, and contributors Author-email: info@fast.ai License: Apache Software License 2.0 Location: /usr/local/lib/python3.7/dist-packages Requires: packaging, pillow, spacy, requests, fastcore, fastdownload, scipy, pip, matplotlib, scikit-learn, torch, torchvision, pandas, pyyaml, fastprogress Required-by:


Name: fastcore Version: 1.3.26 Summary: Python supercharged for fastai development Home-page: https://github.com/fastai/fastcore/tree/master/ Author: Jeremy Howard and Sylvain Gugger Author-email: infos@fast.ai License: Apache Software License 2.0 Location: /usr/local/lib/python3.7/dist-packages Requires: packaging, pip Required-by: fastdownload, fastai

This refers to the structure of the code before the DataBlock

path='/content/drive/MyDrive/ColabNotebooks/Datas/plantvillage-dataset/color'

get_imgs = get_image_files(path)

So get_imgs is fastcore.foundation.L type

#54305) [Path('/content/drive/MyDrive/ColabNotebooks/Datas/plantvillage-dataset/color/Apple___Apple_scab/00075aa8-d81a-4184-8541-b692b78d398a___FREC_Scab 3335.JPG'),Path('/content/drive/MyDrive/ColabNotebooks/Datas/plantvillage-dataset/color/Apple___Apple_scab/01f3deaa-6143-4b6c-9c22-620a46d8be04___FREC_Scab 3112.JPG').....

the

I’m using MultiCategoryBlock, so I worked with the label retrieval.
so from

get_y=parent_label

Reformed to

def parent_label_multi(o):
    return [Path(o).parent.name]

get_y=Pipeline([parent_label_multi])

the get_y is fastcore.transform.Pipeline type
now we return a list

lb=[get_y(o) for o in get_imgs] 
lb[30000]

lb is a list

['Corn_(maize)___healthy'],
 ['Corn_(maize)___healthy'],
 ['Corn_(maize)___healthy'],
 ['Grape___Black_rot'],
 ['Grape___Black_rot'],
 ['Grape___Black_rot'],
 ['Grape___Black_rot'],
 ['Grape___Black_rot'],
 ['Grape___Black_rot'],

plant= DataBlock(blocks=blocks,
                 get_items=get_imgs,
                 get_y=get_y,
                 splitter=splitter,
                 item_tfms=item_tfms,
                 batch_tfms=batch_tfms)

plant.summary(path)

but still, I have this error

Setting-up type transforms pipelines
Collecting items from /content/drive/MyDrive/ColabNotebooks/Datas/plantvillage-dataset/color
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-86-b0c9ac07543b> in <module>()
----> 1 plant.summary(path)

1 frames
/usr/local/lib/python3.7/dist-packages/fastai/data/block.py in datasets(self, source, verbose)
    105     def datasets(self, source, verbose=False):
    106         self.source = source                     ; pv(f"Collecting items from {source}", verbose)
--> 107         items = (self.get_items or noop)(source) ; pv(f"Found {len(items)} items", verbose)
    108         splits = (self.splitter or RandomSplitter())(items)
    109         pv(f"{len(splits)} datasets of sizes {','.join([str(len(s)) for s in splits])}", verbose)

TypeError: 'L' object is not callable

I would like some help, haha

I think the problem here was that you’d specified:

get_imgs = get_image_files(path)

and later you define:

plant= DataBlock(blocks=blocks,
                 get_items=get_imgs,
                 get_y=get_y,
                 splitter=splitter,
                 item_tfms=item_tfms,
                 batch_tfms=batch_tfms)

Therefore, within this (on the second line), you effectively have:

get_items = get_image_files(path)

However, I believe that this should actually just be:

get_items = get_image_files

As is displayed in 02_production.ipynb in the jupyter notebook equivalent of the fastai book (where the model is being trained initially).

I had this exact same problem; when I passed path as the argument of the get_image_files function, I would get the following error message:

TypeError: 'L' object is not callable

Hopefully this helps anyone who encounters the same problem.

5 Likes