Detecting Chihuahuas vs Muffins

Setup

%matplotlib inline
%reload_ext autoreload
%autoreload 2

from fastai import *
from fastai.vision import *
# Use in case of retina display
from IPython.display import set_matplotlib_formats
set_matplotlib_formats('retina')
path = Path('/home/duguet/data/chihuahua-muffin')
path_string = str(path)
!tree -d $path_string
/home/duguet/data/chihuahua-muffin
├── models
├── other
├── test
│ ├── chihuahua
│ └── muffin
└── train
├── chihuahua
└── muffin

8 directories
testset = path/'test'; trainset=path/'train'
!tree $path_string/test/home/duguet/data/chihuahua-muffin/test
├── chihuahua
│ ├── test12.png
│ ├── test14.png
│ ├── test15.png
│ ├── test2.png
│ ├── test4.png
│ ├── test6.png
│ ├── test7.png
│ └── test9.png
└── muffin
├── test1.png
├── test10.png
├── test11.png
├── test13.png
├── test16.png
├── test3.png
├── test5.png
└── test8.png

2 directories, 16 files

Test ImageNet Pretrained Network

The PyTorch way

s = open('/home/duguet/data/imagenet/imagenet1000_clsid_to_human.txt', 'r')
imagenet_classes = eval(s.read())
#imagenet_classes = pickle.load(open('/home/duguet/data/imagenet/classes.pkl', 'rb'))
imagenet_model = models.resnet34(pretrained=True).eval()
print(list(imagenet_classes.values()).index('Chihuahua'))
print(list(imagenet_classes.values()).index('muffin'))
151---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-9-603ad247df74> in <module>
1 print(list(imagenet_classes.values()).index('Chihuahua'))
----> 2 print(list(imagenet_classes.values()).index('muffin'))

ValueError: 'muffin' is not in list
import glob
# Evaluate the old PyTorch way
testlist = glob.glob(str(testset/'*/*'))

fig,ax = plt.subplots(4,4,figsize=(15,10))

for i,ax_ in enumerate(ax.flatten()):
try:
img_file = testlist[i]
img = open_image(img_file).resize(224)
batch = torch.stack([img.data])
out = imagenet_model(batch)
solution = to_np(out.detach())
idx = solution.argmax()
img.show(ax=ax_, title=imagenet_classes[idx])
# print(f'file: {img_file.name}. Detected {imagenet_classes[idx]}, {solution.max()}')
except:
continue

The fastai way

If you’re still interested in seeing how it would work:

data = ImageDataBunch.single_from_classes(path, list(imagenet_classes.values()), tfms=get_transforms(), size=224).normalize(imagenet_stats)
learner = create_cnn(data, models.resnet34, pretrained=True)
# Evaluate the old PyTorch way
learner.model.eval()
for img_file in (testset/'muffin').ls():
try:
img = open_image(img_file).resize(224)
pred,_,_ = learner.predict(img)
print(f'file: {img_file.name}. Detected {pred}')
except:
continue
file: test16.png. Detected sweatshirt
file: test5.png. Detected wreck
file: test13.png. Detected scale, weighing machine
file: test10.png. Detected French horn, horn
file: test8.png. Detected hook, claw
file: test3.png. Detected sweatshirt
file: test11.png. Detected ruddy turnstone, Arenaria interpres
file: test1.png. Detected sweatshirt

Train Network to Chihuahas and Muffins

classes = ['chihuahua', 'muffin']
#Download images
for c in classes:
download_images(path/f'{c}.txt', trainset/c, max_pics=700)
Error https://dechihuahua.org/wp-content/uploads/2018/10/chihuahua-en-el-rio.jpg ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Error https://dechihuahua.org/wp-content/uploads/2018/11/bolsos-tienda.jpg ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Error https://www.zooportraits.com/wp-content/uploads/2018/05/Chihuahua-Dog-Puppy-Canis-Lupus-Familiaris.jpg ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Error https://dechihuahua.org/wp-content/uploads/2018/11/cuadro-pintura-rosa-color.jpg ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Error https://dechihuahua.org/wp-content/uploads/2018/11/cuadros-tienda.jpg ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Error https://dechihuahua.org/wp-content/uploads/2018/11/cuadro-chihuahua-7-300x300.jpg ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Error https://dechihuahua.org/wp-content/uploads/2018/11/cuadro-chihuahua-playa-gafas.jpg ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Error https://dechihuahua.org/wp-content/uploads/2018/11/chihuahua-playa-dividido.jpg ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Error https://dechihuahua.org/wp-content/uploads/2018/11/cuadro-chihuahua-5-300x300.jpg ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Error https://dechihuahua.org/wp-content/uploads/2018/11/cuadro-chihuahua-12.jpg ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
# Verify images 
for c in classes:
print(c)
verify_images(trainset/c, delete=True, max_size=500)
chihuahua
muffin
# Create DataBunch
np.random.seed(42)
data= ImageDataBunch.from_folder(path, valid='test', ds_tfms=get_transforms(), size=224, num_workers=4).normalize(imagenet_stats)
data.show_batch(rows=3, figsize=(7,8))
data.classes, data.c, len(data.train_ds), len(data.valid_ds)
(['chihuahua', 'muffin'], 2, 1270, 16)

Train model

learn = create_cnn(data, models.resnet34, metrics=error_rate)
learn.fit_one_cycle(4)

Results

acc = accuracy(*learn.get_preds()); acc.item()
1.0
learn.show_results(rows=4)
interp = ClassificationInterpretation.from_learner(learn)
interp.plot_confusion_matrix()

One last image for testing

img = open_image(path/'other/get.jpeg').resize(224)
pred,_,_ = learn.predict(img)
img.show(title=pred)

Utopic technogaianist. I believe creativity can be enhanced by making AI collaborate with humans.