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))