File size: 4,203 Bytes
617f13f 0cf4eee 617f13f bfbe14f 0cf4eee bfbe14f ee3a752 bfbe14f 0cf4eee bfbe14f 0cf4eee 3ebfb8f 0cf4eee bfbe14f 0cf4eee bfbe14f 0cf4eee bfbe14f 0cf4eee bfbe14f 0cf4eee bfbe14f 0cf4eee |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
import streamlit as st
st.set_page_config(page_title="PinoyPaws", layout="wide")
import tensorflow as tf
from PIL import Image
import numpy as np
import os
import json
from tensorflow.keras.models import load_model
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.utils import plot_model
import io
# === Page Configuration ===
st.sidebar.title("π PinoyPaws Navigation")
# === Sidebar Navigation ===
page = st.sidebar.selectbox("Navigate to", ["Overview", "Predict Breed", "Model Insights"])
with st.sidebar.expander("βΉοΈ About this App"):
st.markdown("Built with π TensorFlow and π§ MobileNetV2")
# === Load model ===
@st.cache_resource
def load_model():
model_path = os.path.join("src", "model", "dog_breed_classifier.h5")
model = tf.keras.models.load_model(model_path)
return model
model = load_model()
# === Load class names ===
@st.cache_data
def load_class_names():
labels_path = os.path.join("src", "model", "class_names.json")
with open(labels_path, "r") as f:
return json.load(f)
class_names = load_class_names()
# === Preprocess image ===
def preprocess_image(image: Image.Image) -> np.ndarray:
image = image.resize((224, 224))
image_array = np.array(image)
if image_array.shape[-1] == 4:
image_array = image_array[..., :3]
image_array = preprocess_input(image_array)
return np.expand_dims(image_array, axis=0)
# === Page: Overview ===
if page == "Overview":
st.title("πΎ PinoyPaws: Dog Breed Classifier")
st.markdown("""
Welcome to **PinoyPaws**, a dog breed classifier tailored to recognize common dog breeds found in the Philippines ππ΅π.
### π Features:
- π· Upload a dog image and let our AI guess the breed!
- π§ Built using **MobileNetV2** for fast and lightweight inference
- π Confidence score included
- π Trained on 5 local and common breeds:
- **Beagle**
- **Chihuahua**
- **Golden Retriever**
- **Shih Tzu**
- **Siberian Husky**
### π Input:
- Accepts `.jpg`, `.jpeg`, `.png` images
- Optimized for images where the dog is clearly visible
You can get started by choosing **Predict Breed** in the sidebar.
""")
# === Page: Predict Breed ===
elif page == "Predict Breed":
st.title("ππΆ Predict Dog Breed")
st.write(f"Upload an image of a dog and let the model predict its breed from {len(class_names)} common dog breeds.")
uploaded_file = st.file_uploader("π· Choose a dog image...", type=["jpg", "jpeg", "png"])
if uploaded_file is not None:
image = Image.open(uploaded_file).convert("RGB")
st.image(image, caption="Uploaded Image", use_container_width=True)
if st.button("Predict"):
with st.spinner("Classifying..."):
try:
input_tensor = preprocess_image(image)
prediction = model.predict(input_tensor)
predicted_index = int(np.argmax(prediction))
predicted_class = class_names[predicted_index]
confidence = np.max(prediction)
st.success(f"πΆ Predicted Breed: **{predicted_class}**")
st.info(f"π Confidence: {confidence * 100:.2f}%")
except Exception as e:
st.error(f"An error occurred: {e}")
# === Page: Model Insights ===
elif page == "Model Insights":
st.title("π Model Insights & Architecture")
st.markdown("### π§ Model Summary")
string_io = io.StringIO()
model.summary(print_fn=lambda x: string_io.write(x + "\n"))
summary_str = string_io.getvalue()
st.text(summary_str)
st.markdown("### 𧬠Model Details")
st.write(f"β’ Total parameters: `{model.count_params():,}`")
st.write("β’ Architecture: **MobileNetV2** base with custom dense layers")
st.markdown("### π Classes Detected")
st.write(f"The model can classify the following {len(class_names)} breeds:")
st.markdown(" - " + "\n - ".join(class_names)) |