DataBLock: get_y error - How to write a lambda function?

I get this error using the DataBLock structure for semantic segmentation task:

File /opt/conda/lib/python3.10/site-packages/fastai/data/block.py:144, in DataBlock.datasets(self, source, verbose)
    139 def datasets(self, 
    140     source, # The data source
    141     verbose:bool=False, # Show verbose messages
    142 ) -> Datasets:
    143     self.source = source                     ; pv(f"Collecting items from {source}", verbose)
--> 144     items = (self.get_items or noop)(source) ; pv(f"Found {len(items)} items", verbose)
    145     splits = (self.splitter or RandomSplitter())(items)
    146     pv(f"{len(splits)} datasets of sizes {','.join([str(len(s)) for s in splits])}", verbose)

TypeError: 'L' object is not callable

I assume it is due to how I set get_y attribute :

get_mask = lambda x: Path(MASKS_PATH)/f'{x}.png`
get_y = get_mask`

Where my intantion was to get all the .png files in MASKS_PATH

How can I wrote the lambda function correctly?

Hello @Redevil ,

The problem you are facing shows that L object is no callable. L objects are used to list the items that the model will use.

Since the exception is raised at self.get_items(source), it seems like your get_items is a L object, not a function that returns a L object. Could you have built your DataBlock with a line like that?

get_items = a_function(),

If you call the function, you get the result. In this case, try this instead:

get_items = a_function,

If none of this helps you, please, give us more information in order to help you =)
Rubén.

2 Likes

Thanks @ruescog !

This is my code:

PILMask._open_args = {'mode':'P'}

hubmap = DataBlock(blocks=(ImageBlock, MaskBlock(codes)),
                   get_items=get_image_files(IMAGES_PATH),
                   get_y=get_mask,
                   splitter=EndSplitter(valid_pct=0.35),
                   batch_tfms=[SegmentationAlbumentationsTransform(custom_aug()),
                               Normalize.from_stats(*[mean, std]),
])

dls = hubmap.dataloaders(IMAGES_PATH, bs=13)

I am quite sure that the error is about the masks remaining in L format, despite my attempt to fix this with the first line of code.

Hello again,

The get_items and get_y parameters expect a function as input (the get_image_files function for example, not a call to this function).

It seems like you are passing a list instead:

hubmap = DataBlock(blocks=(ImageBlock, MaskBlock(codes)),
                   # get_items=get_image_files(IMAGES_PATH), # replace this line by:
                   get_items=get_image_files, # just the function
                   get_y=get_mask,
                   splitter=EndSplitter(valid_pct=0.35),
                   batch_tfms=[SegmentationAlbumentationsTransform(custom_aug()),
                               Normalize.from_stats(*[mean, std]),
])

Remember that this get_items function expects only one parameter: the source of the images (then, when you call the dataloaders function, you can provide the image path).

If this function does nothing special, you may want to use the predefined one instead. See this link for more information.
Rubén.

PD.

1 Like