There are so many times CUDA device assist errors happen, and this is due to the pixels in your mask not aligning how they should be! (sometimes). For example, if I have a binary mask that is [0,255], it will not work because fastai
expects [0,1]. So how do we fix this? And how should we watch for this? Let’s look at a few tips and examples. (this is also a Wiki, if you have run into other segmentation issues that are not obvious fixes and fixed them feel free to post your solutions here)
Some go-to’s:
Ensure your masks are png
's. JPEG’s compression makes the labels get messed up occasionally.
Reassigning pixel values to classes
If we want to adjust it without remaking our entire dataset at one time, we can change how our get_y
works:
def n_codes(fnames, is_partial=True):
"Gather the codes from a list of `fnames`"
vals = set()
if is_partial:
random.shuffle(fnames)
fnames = fnames[:10]
for fname in fnames:
msk = np.array(PILMask.create(fname))
for val in np.unique(msk):
if val not in vals:
vals.add(val)
vals = list(vals)
p2c = dict()
for i,val in enumerate(vals):
p2c[i] = vals[i]
return p2c
def get_msk(fn, pix2class):
fn = path/'GT_png'/f'{fn.stem}_mask.png'
msk = np.array(PILMask.create(fn))
mx = np.max(msk)
for i, val in enumerate(pix2class):
msk[msk==pix2class[i]] = val
return PILMask.create(msk)
So if we take this example, this is similar to our lambda
function in the CamVid example. What we do here is see if our maximum number of classes present (the highest value) is greater than the classes we’re expecting. If so, then we need to re-map everything to make it all work.
To use it, simply make a new lambda function:
p2c = get_pixel_to_class(fnames)
(where fnames
is your list of masks)
get_y = lambda o: get_msk(o, p2c)