Multi Object Detection - Error lr_find() fastai v2

For the moment, I’ll keep the learn.export() function from the original code I have after calling learn.save(). If after showing the current code to my professors they tell me it’s not necessary to use learn.export() I’ll remove it.

Alright.

I agree, now all the posts you made that have helped me solve all the errors have a like.

1 Like

To clarify it, I want to communicate to @idraja & @muellerzr who I asked for help on this topic, that the problems for which I contacted them have been solved by applying the solutions @matdmiller proposed to me.

Hi @matdmiller,

I’ve been advancing the project for which I created this topic. To put you in context my project is about the analysis of lungs in X-ray images to detect COVID-19.
I’ve trained a lungs detection model.
Now I need to apply inference to predict the bounding boxes on images of a different dataset.
When I tried to execute the function “model.predict” I got an error related to the “custom_bb_pad” function. It’s a function you suggested me to implement to fix an issue I was having related to a mismatch of shapes between the CNN output (shape 1x8) and the target bounding boxes (shape 2x4).

I debugged the function “custom_bb_pad” to check what it was doing but I didn’t notice any change on the shape of the “bbox” parameter at the end of the debugging.
As I didn’t notice “custom_bb_pad” was necessary I commented it. After running the notebook I’ve been able to train the lungs detection model and to get the same metrics results (IoU) as when “custom_bb_pad” was uncommented. Plus, if I run model.predict() I no longer have an error.

I’d like to know why should I need to use “custom_bb_pad”.

Next, I show you the code you sent me to make matchable the shapes of the CNN model and the target bounding boxes.

Thank you.

# Cell
class NoLabelBBoxLabeler(Transform):
    """ Bounding box labeler with no label """
    def setups(self, x): noop
    def decode (self, x, **kwargs):
        self.bbox,self.lbls = None,None
        return self._call('decodes', x, **kwargs)

    def decodes(self, x:TensorBBox):
        self.bbox = x
        return self.bbox if self.lbls is None else LabeledBBox(self.bbox, self.lbls)
'''
def custom_bb_pad(samples, pad_idx=0):
    "Function that collect `samples` of bboxes and adds padding with `pad_idx`."
    # 'samples' is a list that contains a tuple with 2 elements: a TensorImage & a TensorBBox. TensorBBox size is (2,4)
    #   TensorImage size is [3, width, height]
    max_len = max([len(s[1]) for s in samples]) # s[1] is a TensorBBox. max_len equals to 2 (number of bboxes associated to a TensorBBox)
    def _f(img,bbox): # img is a TensorImage, bbox is a TensorBBox
        bbox = torch.cat([bbox,bbox.new_zeros(max_len-bbox.shape[0], 4)])        
        return img,bbox
    return [_f(*s) for s in samples] # _f function receives a TensorImage as first parameter (img) and a TensorBBox as second parameter (bbox)

CustomBboxBlock = TransformBlock(type_tfms=TensorBBox.create, 
                             item_tfms=[PointScaler, NoLabelBBoxLabeler], dls_kwargs = {'before_batch': custom_bb_pad})               
'''

CustomBboxBlock = TransformBlock(type_tfms=TensorBBox.create, 
                             item_tfms=[PointScaler, NoLabelBBoxLabeler])               

class BBoxReshape(DisplayedTransform):
    "Normalize/denorm batch of `TensorImage`"
    parameters,order = L(),100
    def __init__(self): 
        noop

    def setups(self, dl:DataLoader):
        noop

    def encodes(self, x:TensorBBox): return torch.reshape(x,(x.shape[0],8)) # x.shape original is (64,2,4) and it gets converted to (64,8)
    def decodes(self, x:TensorBBox): return torch.reshape(x,(x.shape[0],2,4)) # x.shape original is (64,8) and it gets converted to (64,2,4)```

The reshaping was moved here.

Because you always have exactly 2 bounding boxes, you probably don’t.

1 Like

Sorry for the delay.

Alright.
From the experiments I’ve done I noticed I don’t need to use the “custom_bb_pad” function.