Using fastai for Segmentation, receiving a CUDA device-side assertion error

#20

You can predict 0 or 1 with CrossEntropy (as long as it can’t be 0 and 1 at the same time, which is the case in segmentation). Your problem is the same as everyone else: your mask is encoded with 0 and 255s, not 0s and 1s, so you need to subclass SegmentationItemList and its open method to return open_mask(bla, div=True).

1 Like

(Thomas) #21

Thanks, it appears to be that, do you know why open_image does that [0,255] instead of 0,1? My images are saved as 1bit with PIL.
This solved the issue:

class MySegmentationLabelList(SegmentationLabelList):
  def open(self, fn): return open_mask(fn, div=True)

class MySegmentationItemList(ImageItemList):
    "`ItemList` suitable for segmentation tasks."
    _label_cls,_square_show_res = MySegmentationLabelList,False
2 Likes

#22

It depends on how your masks are encoded I guess.

0 Likes

(Pietro La Torre) #23

Can you also show how you use those classes to create databunch?

0 Likes

(Thomas) #24

I am trying to solve this problem, any tips on how I could get good segmentation masks?

  src = (MySegmentationItemList.from_folder(path_img)
       .random_split_by_pct(.2)
       .label_from_func(get_y_fn, classes=['background','solar_module']))
  data = (src.transform(get_transforms(), size=size, tfm_y=True)
        .databunch(bs=bs)
        .normalize(imagenet_stats))
0 Likes

#25

[quote=“sgugger, post:3, topic:30292”]
Not that any time you get a CUDA error, you have to rest
[/quote]But I use:mask = open_mask(get_y_fn(img_f), div=True)
mask.show(figsize=(5,5), alpha=1)
, then the mask shows all black. No mask now, right?

0 Likes

#26

My images are .jpg, masks are .png, I tried mask.data[0][50][20:600] to see the data, and found lots of values are 38, the others are 0

0 Likes

(Danielh Carranza) #27

If it’s a binary task and you have values of 38 and 0, you must divide by 38 your images or set every value greater than 0 to 1, for example here’s some code tha I use in a similar case:

def open_mk(fn:PathOrStr, div:bool=False, convert_mode:str='L', cls:type=ImageSegment,
        after_open:Callable=None)->Image:
    "Return `Image` object created from image in file `fn`."
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", UserWarning) # EXIF warning from TiffPlugin
        x = PIL.Image.open(fn).convert(convert_mode)
    if after_open: x = after_open(x)
    x = pil2tensor(x,np.float32)
    x[x>0]=1  #MODIFIDED
    if div: x.div_(255)
    return cls(x)

class CustomSegmentationLabelList(SegmentationLabelList):
    def open(self,fn): return open_mk(fn)
    
class CustomSegmentationItemList(ImageList):
    _label_cls= CustomSegmentationLabelList
1 Like

(Patrick Trampert) #28

For all segmentation tasks, make sure that your labels are always starting at 0 and increasing till the number of classes minus 1. For 10 classes your labels should be 0,…,9.

Best is preprocessing the masks and saving the correct format on disk. Best use ImageJ / Fiji for this task, then you can also check that everything fits. Sure you can do it with python, but transforming your data on the fly when loading it for learning is too resource intense, so I would not do that.

0 Likes

(hari rajeev) #29

@alex_zhang has the segmentation worked for you ?

0 Likes

#30

@harikrishnanrajeev Yes, I fixed it with pietro.latorre’s method with updated fastai, and I also added '0’class to the class list, then fit_one_cycle works. Maybe I needn’t generat the mask, but just load from coco json file, I haven’t tried that yet.

1 Like

(hari rajeev) #31

Does anybody know why the mask shows all black ?. Is this as expected ?

1 Like

(Patrick Trampert) #32

Change the displayed range to 0 … N (where N is the number of classes).

0 Likes

(Pravinvignesh S K) #33

Hey, I am also facing the same problem. I had values of 76 and 0 when i print the mask.data values. Have u found the trick how to solve. If yes please let me know.

0 Likes

(hari rajeev) #34

Please have a look at the approach in this link

this works

2 Likes

(Pravinvignesh S K) #35

thanks. it works absolutely fine.

1 Like

(Julian) #36

My brain was almost exploding because I did not find an error in my code but could not train a segmentation model. Just knowing that the accuracy metric no longer works for segmentation saved my life. Thank you.

0 Likes

(hari rajeev) #37

Would be good to use DICE or even DICE + BCE . Thanks .

0 Likes

(moein hasani) #38

the problem is masks are gone .show batch and prediction doesn’t bring them.did u manage to solve it?

0 Likes

(Evgeniya) #39

Hello,
hope that’ll be useful for someone…

How I saw something wrong in my code: open_mask(‘path to mask’).data contains values out of [0, classes-1]

2)I had mask in rle format, so I generated files with mask myself. But. I used ImageSegment.save(filename) without png format. So storing mask as png resolved my problem.

(this code from ImageSegment.save, I has copied it to my code, to add ‘png’
x = get_image(mask, shape)
x = image2np(x.data).astype(np.uint8)
PIL.Image.fromarray(x).save(LBL_PATH/file_name,‘png’)

Thanks

0 Likes