In [1]:
#|default_exp app
In [2]:
#|export
import gradio as gr
from fastai.vision.all import *
import platform, pathlib # Specifically for handling Unix vs Windows
In [3]:
#|export
# Monkey patch PosixPath to WindowsPath if on Windows
if platform.system() == 'Windows':
pathlib.PosixPath = pathlib.WindowsPath
# doc(load_learner)
learn_inf = load_learner("2025-06-13-res18x25p-v7.pkl", cpu=True)
d:\Users\mores\miniconda3\envs\spaces\Lib\site-packages\fastai\learner.py:455: UserWarning: load_learner` uses Python's insecure pickle module, which can execute malicious arbitrary code when loading. Only load files you trust. If you only need to load model weights and optimizer state, use the safe `Learner.load` instead. warn("load_learner` uses Python's insecure pickle module, which can execute malicious arbitrary code when loading. Only load files you trust.\nIf you only need to load model weights and optimizer state, use the safe `Learner.load` instead.")
In [4]:
# Make a prediction
learn_inf.predict('test_images/Castor_canadensis.JPG')
Out[4]:
('Castor_canadensis', tensor(3), tensor([7.9373e-06, 7.8704e-05, 2.6030e-04, 9.9913e-01, 4.8686e-04, 8.5241e-06, 5.2863e-06, 2.3881e-05]))
In [5]:
learn_inf.dls.vocab
Out[5]:
['Actitis_macularius', 'Anas_platyrhynchos', 'Branta_canadensis', 'Castor_canadensis', 'Sylvilagus_floridanus', 'Trachemys_scripta_elegans', 'Turdus_migratorius', 'blank']
In [6]:
#|export
species_dict = {
"Actitis_macularius": "Spotted Sandpiper",
"Anas_platyrhynchos": "Mallard",
"Branta_canadensis": "Canada Goose",
"Castor_canadensis": "North American Beaver",
"Sylvilagus_floridanus": "Eastern Cottontail",
"Trachemys_scripta_elegans": "Red-eared Slider",
"Turdus_migratorius": "American Robin",
"blank": "No Animal Detected"
}
In [7]:
#|export
def top_3_preds(image_path):
pred_class, pred_idx, pred_probs = learn_inf.predict(image_path)
# Convert vocab class name to common name
def common_name(name):
return species_dict.get(name, name)
top3 = [
f"{common_name(learn_inf.dls.vocab[i])}: {float(pred_probs[i]):.4f}"
for i in pred_probs.argsort(descending=True)[:3]
]
results = {
"prediction": {
"class": str(pred_class),
"common_name": common_name(str(pred_class)),
"probability": round(float(pred_probs[pred_idx]), 4)
},
"top3": top3
}
markdown_result = (
f"### Prediction\n"
f"**Class**: {common_name(str(pred_class))}\n"
f"**Probability**: {float(pred_probs[pred_idx]):.4f}\n\n"
f"### Top 3 Classes\n" + "\n".join([f"- {x}" for x in top3])
)
return markdown_result, results
In [8]:
md_result, json_result = top_3_preds("test_images/Castor_canadensis.jpg")
print(md_result)
display(json_result)
### Prediction **Class**: North American Beaver **Probability**: 0.9991 ### Top 3 Classes - North American Beaver: 0.9991 - Eastern Cottontail: 0.0005 - Canada Goose: 0.0003
{'prediction': {'class': 'Castor_canadensis', 'common_name': 'North American Beaver', 'probability': 0.9991}, 'top3': ['North American Beaver: 0.9991', 'Eastern Cottontail: 0.0005', 'Canada Goose: 0.0003']}
In [9]:
#|export
with gr.Blocks() as demo:
gr.Markdown("""
## 🦆🦫 UrbanRivers CameraTrap Classifier 🐇🐢
✅ Species this model can recognize (~78% confidence): *Spotted Sandpiper , Mallard , Canada Goose , North American Beaver , Eastern Cottontail , Red-eared Slider , American Robin.*
""")
with gr.Row():
with gr.Column(scale=1):
image_input = gr.Image(type="filepath", image_mode="RGB", width=300, height=200, label="Upload Image")
submit_btn = gr.Button("Classify")
with gr.Column(scale=2):
md_output = gr.Markdown(label="Prediction Results")
with gr.Column(scale=2):
json_output = gr.JSON(label="Raw JSON")
examples = gr.Examples(
examples=[
"./test_images/Anas_platyrhynchos.jpg",
"./test_images/Branta_canadensis.jpg",
"./test_images/Castor_canadensis.jpg",
"./test_images/Sylvilagus_floridanus.jpg",
"./test_images/Trachemys_scripta_elegans.jpg"
],
inputs=image_input
)
submit_btn.click(fn=top_3_preds, inputs=image_input, outputs=[md_output, json_output])
demo.launch(inline=False)
* Running on local URL: http://127.0.0.1:7860 * To create a public link, set `share=True` in `launch()`.
Out[9]:
Export to app¶
In [ ]:
import nbdev
nbdev.export.nb_export('app.ipynb', ".")
print('Export successful')
Export successful