Open In Colab

from IPython.display import YouTubeVideo
YouTubeVideo('-Sw87Dyh3Kss')

Setup

!nvidia-smi
Fri Oct 15 16:26:50 2021       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.74       Driver Version: 460.32.03    CUDA Version: 11.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Tesla V100-SXM2...  Off  | 00000000:00:04.0 Off |                    0 |
| N/A   35C    P0    23W / 300W |      0MiB / 16160MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
!pip install -Uqqq fastai
from fastai.vision.all import *

Baixando o dataset

L(dir(URLs))
(#95) ['ADULT_SAMPLE','AG_NEWS','AMAZON_REVIEWS','AMAZON_REVIEWS_POLARITY','BIWI_HEAD_POSE','BIWI_SAMPLE','CALTECH_101','CAMVID','CAMVID_TINY','CARS'...]
URLs.PETS
'https://s3.amazonaws.com/fast-ai-imageclas/oxford-iiit-pet.tgz'
path = untar_data(URLs.PETS)/'images'
path
Path('/root/.fastai/data/oxford-iiit-pet/images')

EDA (Explorando o Dataset)

files = get_image_files(path)
files
(#7390) [Path('/root/.fastai/data/oxford-iiit-pet/images/British_Shorthair_204.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/boxer_165.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/basset_hound_125.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/Bombay_185.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/wheaten_terrier_92.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/yorkshire_terrier_47.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/Siamese_31.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/British_Shorthair_74.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/beagle_157.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/shiba_inu_176.jpg')...]
Image.open(path/'pug_116.jpg')
Image.open(path/'British_Shorthair_201.jpg')

Dataloader

def labeler(x): return 'Gato' if x.name[0].isupper() else 'Cachorro'
labeler(path/'British_Shorthair_201.jpg')
'Gato'
labeler(path/'pug_116.jpg')
'Cachorro'
files = get_image_files(path)
files
(#7390) [Path('/root/.fastai/data/oxford-iiit-pet/images/British_Shorthair_204.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/boxer_165.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/basset_hound_125.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/Bombay_185.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/wheaten_terrier_92.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/yorkshire_terrier_47.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/Siamese_31.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/British_Shorthair_74.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/beagle_157.jpg'),Path('/root/.fastai/data/oxford-iiit-pet/images/shiba_inu_176.jpg')...]
labeler(files[0])
'Gato'
dblock = DataBlock(
    blocks = [ImageBlock, CategoryBlock], # blocos que formata os dados
    splitter = RandomSplitter(valid_pct = 0.2, seed = 42),
    get_items = get_image_files, # função que carrega os dados
    get_y = labeler,
    # get_x = ... 
    item_tfms = Resize(224),
)
dls = dblock.dataloaders(path, num_workers = 2, bs = 64)
dls.show_batch()
xb, yb = dls.one_batch()

Learner

learn = cnn_learner(dls, resnet50, metrics=accuracy)
/usr/local/lib/python3.7/dist-packages/torch/nn/functional.py:718: UserWarning: Named tensors and all their associated APIs are an experimental feature and subject to change. Please do not use them for anything important until they are released as stable. (Triggered internally at  /pytorch/c10/core/TensorImpl.h:1156.)
  return torch.max_pool2d(input, kernel_size, stride, padding, dilation, ceil_mode)

Transfer Learning

learn.fine_tune(3)
epoch train_loss valid_loss accuracy time
0 0.090986 0.022098 0.993911 00:51
epoch train_loss valid_loss accuracy time
0 0.075581 0.028851 0.991204 00:52
1 0.034629 0.010006 0.995940 00:51
2 0.016202 0.002749 0.999323 00:51
0.999323 ** 12
0.9919061815543482

Verificação

learn.show_results()
interp = ClassificationInterpretation.from_learner(learn)
interp.plot_confusion_matrix()
(996+1+1+480) / 7390
0.2

Testando com uma nova imagem

import ipywidgets as widgets
uploader = widgets.FileUpload()
uploader
img = PILImage.create(uploader.data[0])
label, _, probs = learn.predict(img)
if label == 'Gato':
    print(f'Isso é um {label} com {(probs[1].item()*100):.1f}% de certeza')
else:
    print(f'Isso é um {label} com {(probs[0].item()*100):.1f}% de certeza')
img.to_thumb(300)
Isso é um Gato com 100.0% de certeza

Problemas a serem resolvidos

  • E se a foto for de um leão?
  • E se o cachorro for o Pluto?
  • E se tivermos gatos e cachorros na foto?
  • E se a foto for de uma cadeira?

Data Augmentation

dblock = DataBlock(
    blocks = [ImageBlock, CategoryBlock],
    get_items = get_image_files,
    get_y = labeler,
    item_tfms = Resize(256),
    batch_tfms = aug_transforms(mult = 2, size = 224)
)
dls = dblock.dataloaders(path, num_workers = 2)
dls.show_batch(unique = True)