import fastbook
from fastbook import *
from fastai.vision.all import *
from fastai.vision.widgets import *
import timm
from duckduckgo_search import ddg_images
from time import sleep
import os
import gradio
Trail Cam Deer, Elk and Moose Classifier
Python
Deep Learning
Computer Vision
Project
def search_images(term, max_images=100):
print(f"Searching for '{term}'")
return L(ddg_images(term, max_results=max_images)).itemgot('image')
= 'moose', 'deer', 'elk'
searches = Path('trail_cam')
path
for o in searches:
= (path/o)
dest =True, parents=True)
dest.mkdir(exist_ok= search_images(f'{o} trail cam photo'))
download_images(dest, urls 10)
sleep(= search_images(f'{o} trail cam photo day'))
download_images(dest, urls 10)
sleep(= search_images(f'{o} trail cam photo night'))
download_images(dest, urls 10)
sleep(/o, max_size=400, dest=path/o) resize_images(path
Searching for 'moose trail cam photo'
Searching for 'moose trail cam photo day'
Searching for 'moose trail cam photo night'
Searching for 'deer trail cam photo'
Searching for 'deer trail cam photo day'
Searching for 'deer trail cam photo night'
Searching for 'elk trail cam photo'
Searching for 'elk trail cam photo day'
Searching for 'elk trail cam photo night'
= get_image_files(path)
fns len(fns)
877
= verify_images(fns)
failed map(Path.unlink)
failed.= get_image_files(path)
fns len(failed), len(fns)
(12, 865)
os.getcwd()for i, filename in enumerate(os.listdir(path/'deer')):
"trail_cam/deer/" + filename, "trail_cam/deer/deer_" + str(i) + ".jpg")
os.rename(for i, filename in enumerate(os.listdir(path/'moose')):
"trail_cam/moose/" + filename, "trail_cam/moose/moose_" + str(i) + ".jpg")
os.rename(for i, filename in enumerate(os.listdir(path/'elk')):
"trail_cam/elk/" + filename, "trail_cam/elk/elk_" + str(i) + ".jpg") os.rename(
= ImageDataLoaders.from_name_func('.',
dls =0.2, seed=42,
get_image_files(path), valid_pct=RegexLabeller(pat = r'^([^/]+)_\d+'),
label_func=Resize(224)) item_tfms
=4) dls.valid.show_batch(max_n
= vision_learner(dls, resnet34, metrics=error_rate)
learn 5) learn.fine_tune(
epoch | train_loss | valid_loss | error_rate | time |
---|---|---|---|---|
0 | 2.002779 | 1.369467 | 0.586207 | 00:07 |
epoch | train_loss | valid_loss | error_rate | time |
---|---|---|---|---|
0 | 1.426437 | 1.002604 | 0.425287 | 00:03 |
1 | 1.082575 | 0.859882 | 0.413793 | 00:03 |
2 | 0.907559 | 0.716293 | 0.333333 | 00:03 |
3 | 0.748531 | 0.688598 | 0.252874 | 00:03 |
4 | 0.647351 | 0.693779 | 0.264368 | 00:03 |
= ClassificationInterpretation.from_learner(learn)
interp interp.plot_confusion_matrix()
6, nrows=1) interp.plot_top_losses(
= ImageClassifierCleaner(learn)
cleaner cleaner
for idx in cleaner.delete(): cleaner.fns[idx].unlink()
for idx,cat in cleaner.change(): shutil.move(str(cleaner.fns[idx]), path/cat)
= ImageDataLoaders.from_name_func('.',
dls =0.2, seed=42,
get_image_files(path), valid_pct=RegexLabeller(pat = r'^([^/]+)_\d+'),
label_func=Resize(224)) item_tfms
= vision_learner(dls, 'convnext_tiny_in22k', metrics=error_rate).to_fp16()
learn 10) learn.fine_tune(
epoch | train_loss | valid_loss | error_rate | time |
---|---|---|---|---|
0 | 1.692869 | 3.532001 | 0.581395 | 00:03 |
epoch | train_loss | valid_loss | error_rate | time |
---|---|---|---|---|
0 | 0.983810 | 1.380556 | 0.313953 | 00:03 |
1 | 0.885328 | 0.899624 | 0.232558 | 00:03 |
2 | 0.792400 | 0.785097 | 0.255814 | 00:03 |
3 | 0.720126 | 0.789632 | 0.197674 | 00:03 |
4 | 0.623536 | 0.744941 | 0.186047 | 00:03 |
5 | 0.556991 | 0.737408 | 0.209302 | 00:03 |
6 | 0.512330 | 0.754599 | 0.197674 | 00:03 |
7 | 0.464188 | 0.772003 | 0.197674 | 00:03 |
8 | 0.431808 | 0.771565 | 0.197674 | 00:03 |
9 | 0.404420 | 0.780129 | 0.197674 | 00:03 |
from fastdownload import download_url
= search_images_ddg('trail cam deer')
urls 0]
urls[2], 'deer.jpg')
download_url(urls[
= Image.open('deer.jpg')
im 190,190) im.to_thumb(
100.58% [196608/195476 00:00<00:00]
= search_images_ddg('trail cam elk')
urls 0]
urls[0], 'elk.jpg')
download_url(urls[
= Image.open('elk.jpg')
im 190,190) im.to_thumb(
116.39% [40960/35192 00:00<00:00]
= search_images_ddg('trail cam moose')
urls 1]
urls[1], 'moose.jpg')
download_url(urls[
= Image.open('moose.jpg')
im 190,190) im.to_thumb(
100.81% [270336/268163 00:00<00:00]
= PILImage.create("deer.jpg")
im 192, 192))
im.thumbnail(( im
learn.predict(im)
('deer', TensorBase(0), TensorBase([0.6719, 0.0927, 0.2354]))
Pickel and export model to be uploaded to gradio
'model.pkl') learn.export(
from fastai.vision.all import *
import gradio as gr
= load_learner('model.pkl')
learn = learn.dls.vocab
categories
def classify_image(img):
= PILImage.create(img)
img = learn.predict(img)
pred, idx, probs return dict(zip(categories, map(float,probs)))
= gr.inputs.Image(shape=(192,192))
image = gr.outputs.Label()
label = ['deer.jpg', 'elk.jpg', 'moose.jpg']
examples
= gr.Interface(fn=classify_image, inputs=image, outputs=label, examples=examples)
intf =False, share=True) intf.launch(inline
/usr/local/lib/python3.9/dist-packages/gradio/inputs.py:256: UserWarning: Usage of gradio.inputs is deprecated, and will not be supported in the future, please import your component from gradio.components
warnings.warn(
/usr/local/lib/python3.9/dist-packages/gradio/deprecation.py:40: UserWarning: `optional` parameter is deprecated, and it has no effect
warnings.warn(value)
/usr/local/lib/python3.9/dist-packages/gradio/outputs.py:196: UserWarning: Usage of gradio.outputs is deprecated, and will not be supported in the future, please import your components from gradio.components
warnings.warn(
/usr/local/lib/python3.9/dist-packages/gradio/deprecation.py:40: UserWarning: The 'type' parameter has been deprecated. Use the Number component instead.
warnings.warn(value)
Running on local URL: http://127.0.0.1:7860
Running on public URL: https://27270.gradio.app
This share link expires in 72 hours. For free permanent hosting, check out Spaces: https://huggingface.co/spaces
(<gradio.routes.App at 0x7f8110cc3040>,
'http://127.0.0.1:7860/',
'https://27270.gradio.app')