In this article, we will make a image classification model that attempts to differentiate between aliens and ghosts.
But you may say, aliens and ghosts are not real. Well, their existence is not proven scientifically, yet. But it doesn’t mean we cannot search images online for them. With those images, we will create a model. Hopefully we may be able to create the real alien vs. ghosts model in the future, but let’s start with this.
For training, I will use FastAI library because there are many great courses for learning. Although it is possible to only use CPU to train the model, it is faster to use GPU. I am on Google colab, which provides free GPU. After training, we will save the model so that we can use it for deployment on Hugging Face spaces. You can check out the final product before we begin!
We use duckduckgo to search and download images. FastAI provides search_images_ddg so that we do not have to go to a search engine and download an image one by one!
We now create DataBlocks. Simply put, it is a bridge between raw data and a model. We specify input and output for the model, how to get the input, how to split train data from validation data, how data are labelled, and what transfroms are needed for the input.
dblock = DataBlock( blocks=(ImageBlock, CategoryBlock), # We take images and try to classify them based on categories. get_items=get_image_files, # inputs are images. splitter=RandomSplitter(valid_pct=0.2, seed=42), # randomly pick 20% of the input for validation. get_y=parent_label, # parent directory name is the label for each image. item_tfms=Resize(128)) # Resize each image to 128.
dls = dblock.dataloaders(path)dls
<fastai.data.core.DataLoaders>
Look at the images and labels to make sure everything looks right. Seems like images are correctly labelled. At this point, it is okay to have some wrong images or labels. We will fix that later.
dls.valid.show_batch(max_n=4, nrows=1)
We can add data augmentation (transforms) into images so that we can train more efficiently with less data.
/usr/local/lib/python3.7/dist-packages/PIL/Image.py:960: UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images
"Palette images with Transparency expressed in bytes should be "
epoch
train_loss
valid_loss
error_rate
time
0
0.587268
0.345220
0.155844
00:17
1
0.503984
0.289026
0.090909
00:18
2
0.407598
0.316117
0.103896
00:16
3
0.376871
0.302991
0.090909
00:17
/usr/local/lib/python3.7/dist-packages/PIL/Image.py:960: UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images
"Palette images with Transparency expressed in bytes should be "
/usr/local/lib/python3.7/dist-packages/PIL/Image.py:960: UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images
"Palette images with Transparency expressed in bytes should be "
/usr/local/lib/python3.7/dist-packages/PIL/Image.py:960: UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images
"Palette images with Transparency expressed in bytes should be "
/usr/local/lib/python3.7/dist-packages/PIL/Image.py:960: UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images
"Palette images with Transparency expressed in bytes should be "
There are some errors. We can look at the errors by looking at the confusion matrix and top losses.
/usr/local/lib/python3.7/dist-packages/PIL/Image.py:960: UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images
"Palette images with Transparency expressed in bytes should be "
/usr/local/lib/python3.7/dist-packages/PIL/Image.py:960: UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images
"Palette images with Transparency expressed in bytes should be "
# Check the high lossesinterp.plot_top_losses(10, nrows=2)
/usr/local/lib/python3.7/dist-packages/PIL/Image.py:960: UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images
"Palette images with Transparency expressed in bytes should be "
Some images are not labelled correctly or wrong images. We can easily fix it by using the cleaner.
# Pick which ones to delete or to move to another categorycleaner = ImageClassifierCleaner(learn)cleaner
/usr/local/lib/python3.7/dist-packages/PIL/Image.py:960: UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images
"Palette images with Transparency expressed in bytes should be "
# make cleaner take effectfor idx in cleaner.delete(): cleaner.fns[idx].unlink()for idx,cat in cleaner.change(): shutil.move(str(cleaner.fns[idx]), path/cat)
After cleaning, we train again for the cleaned data. So, we go back up to DataLoaders and come back down here. After that, we can export the model. We can then download the model so that we can deploy it into Hugging Face Spaces.
learn.export()
# check if file is pickledpath = Path()path.ls(file_exts='.pkl')
(#1) [Path('export.pkl')]
That’s it. If this notebook was run locally, there will be the the model in the same directory as the notebook. If this notebook was run on Google colab, the model has to be downloaded from the directory from the panel on the left.