PanelWidgets

This creates a ImageClassifierCleaner variation which works with ImageDataLoaders which can be displayed on static export

Open In Colab

Compatibility Block

Check Platform

IN_COLAB = 'google.colab' in sys.modules
IN_KAGGLE = 'kaggle_secrets' in sys.modules
IS_REMOTE = IN_COLAB or IN_KAGGLE

Platform & Environment Configuration

Imports

Public Imports

Private Imports

Pandemic Safety

Our dataset consist of images labelled as mask or no_mask. We will do following steps

  1. Build a classifier on raw version of data
  2. Review images with highest confusion. Identify images we would, like to keep, relabel or skip

DataBlocks and DataLoaders

In present example, I will use image.csv to generate items and labels. Advantages are:-

  • I don’t have to delete any file
  • I can manage modifications to dataset in a new csv file and upload the version on Datasette for future review
  • dataloaders has a path argument. To be consistent with fastai dataloader we need to supply path for df execution

We will get list of fnames and labels from dataframe. If we require cleaning we will save any data modifications in new csv which we can then upload to datasette. This way our data stays immutable.

doc(DataBlock)

DataBlock

DataBlock(blocks:list=None, dl_type:TfmdDL=None, getters:list=None, n_inp:int=None, item_tfms:list=None, batch_tfms:list=None, get_items=None, splitter=None, get_y=None, get_x=None)

Generic container to quickly build `Datasets` and `DataLoaders`.

Show in docs

def get_image_df(path, csvfile='image.csv', rel_path_col='rel_path',  folder_col='label', fname_col='fn'):
    df = pd.read_csv(path/csvfile)
    if rel_path_col not in df.columns.tolist():
        df[rel_path_col] = df[[folder_col, fname_col]].apply(lambda x: f'{x[0]}/{x[1]}', axis=1)
    return df

def get_images_from_df(path, df=None, rel_path_col='rel_path'):
    if df is None or df.empty: raise Exception(("df is required"))
    return L(df[rel_path_col].values.tolist()).map(lambda x: path/x)
df = get_image_df(path)
get_images_from_df(path, df=df)
(#309) [Path('/mnt/d/rahuketu/programming/AIKING_HOME/data/PandemicSafety/No_Mask/7a8b0909-4f5c-4d53-b1bc-f35a83a022c9.jpg'),Path('/mnt/d/rahuketu/programming/AIKING_HOME/data/PandemicSafety/No_Mask/1f54d9ac-4a0e-42fe-98cb-09938a3104b0.jpg'),Path('/mnt/d/rahuketu/programming/AIKING_HOME/data/PandemicSafety/No_Mask/d08a498f-27cf-4668-a4f1-af32dfd15416.jpg'),Path('/mnt/d/rahuketu/programming/AIKING_HOME/data/PandemicSafety/No_Mask/52601346-132e-4217-ab57-6c324c1e4eee.jpg'),Path('/mnt/d/rahuketu/programming/AIKING_HOME/data/PandemicSafety/No_Mask/78ac55fb-2db3-48e9-bdcc-4caa2a50e3f6.jpg'),Path('/mnt/d/rahuketu/programming/AIKING_HOME/data/PandemicSafety/No_Mask/5eeec12d-174e-4d1d-a261-8dcd99ea9b8b.jpg'),Path('/mnt/d/rahuketu/programming/AIKING_HOME/data/PandemicSafety/No_Mask/f048f38a-3758-428d-8d9f-8462a4e272d0.jpeg'),Path('/mnt/d/rahuketu/programming/AIKING_HOME/data/PandemicSafety/No_Mask/cfbe3224-4ec8-47f6-8ee8-d637572b2787.jpg'),Path('/mnt/d/rahuketu/programming/AIKING_HOME/data/PandemicSafety/No_Mask/b2b14d80-ddf9-4e4a-9b61-afdbabb1cf9d.jpg'),Path('/mnt/d/rahuketu/programming/AIKING_HOME/data/PandemicSafety/No_Mask/d7a7b4e3-4756-4294-88d6-6c23a7ba6741.jpg')...]
def get_y_df(o, path=None, df=None, label_col='label', rel_path_col='rel_path'):
    if df is None or df.empty: raise Exception(("df is required"))
    if path is None: raise Exception("Path is required")
    return df.loc[df['rel_path']==str(o.relpath(path)), 'label'][0]
o = get_images_from_df(path, df=df)[0]; (o, str(o.relpath(path)))
get_y_df(o, path=path, df=df)
'No_Mask'

Model Training

Classification Interpretation

Where do we see high losses?
  • When model predicts incorrect class with high confidence.
  • When model predicts correct class but the confidence low.

Data Cleaning Widget using Panel

# url = "https://thumbs.dreamstime.com/b/close-up-face-pretty-woman-walking-city-wearing-leather-jacket-concept-positive-emotions-urban-look-young-female-person-113846433.jpg"i
# im_with_dd(url)

source

im_with_dd

 im_with_dd (fn, val, opts=['<Keep>', '<Delete>'], w=192, h=192,
             clbck=None)

source

get_values

 get_values (c)

source

PanelImageClassifierCleaner

 PanelImageClassifierCleaner (learn, h=128, w=192, max_n=30,
                              ds_opts='Train, Valid')

Inherit from this to have all attr accesses in self._xtra passed down to self.default