Spaces:
Sleeping
Sleeping
File size: 6,239 Bytes
665a66c 8a9a28b 665a66c 155423f 7fdb879 2c202de 8a9a28b 665a66c 8a9a28b 155423f 7fdb879 2c202de 7fdb879 665a66c 2c202de 665a66c 2c202de 155423f 2c202de 7fdb879 155423f 2c202de 665a66c 2c202de 665a66c 2c202de 8a9a28b 2c202de 8a9a28b 2c202de 155423f 8a9a28b 2c202de 8a9a28b 155423f 8a9a28b 2c202de 8a9a28b 2c202de 155423f 2c202de 8a9a28b 155423f 8a9a28b 2c202de 665a66c 2c202de 8a9a28b 155423f 8a9a28b 665a66c 8a9a28b 2c202de 665a66c 2c202de 8a9a28b 2c202de 8a9a28b 2c202de 665a66c 8a9a28b 2c202de 8a9a28b 2c202de 8a9a28b 2c202de 665a66c 2c202de 7fdb879 2c202de 7fdb879 2c202de 7fdb879 2c202de 7fdb879 665a66c 2c202de 7fdb879 2c202de 7fdb879 2c202de |
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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
import streamlit as st
import tensorflow as tf
import numpy as np
import os
import pandas as pd
import altair as alt
from PIL import Image
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import zipfile
import io
import shutil
# π¨ App Title
st.title("πΆπ± Cat vs Dog Classifier")
# π About the App
st.write(
"""
## About This App
This is a machine learning application that classifies images into two categories:
**Cats π±** and **Dogs πΆ**. The model is trained using a deep learning architecture
called Convolutional Neural Networks (CNNs) and is able to distinguish between images
of cats and dogs with high accuracy.
### Features:
- **Dataset Overview**: View the number of images in the dataset, categorized by "Cats" and "Dogs".
- **Model Evaluation**: Check the model's performance on the validation set, including accuracy and loss.
- **Image Classification**: Upload an image, and the model will predict whether it's a cat or a dog, along with the confidence level.
- **Download Test Folder**: Download a ZIP file containing the test images.
The app is powered by **Streamlit** for an interactive user interface and **TensorFlow** for image classification.
"""
)
# β
Detect Environment & Set Dataset Path
BASE_DIR = "dataset" # In Hugging Face Spaces, the dataset folder should be at the root of the Space
ZIP_PATH = "dataset.zip" # If dataset is uploaded as a ZIP (make sure it's in the same directory as app.py)
TRAIN_DIR = os.path.join(BASE_DIR, "train")
TEST_DIR = os.path.join(BASE_DIR, "test")
# β
Extract Dataset if Needed (Hugging Face)
if ZIP_PATH and os.path.exists(ZIP_PATH):
if not os.path.exists(BASE_DIR): # Avoid re-extracting
with zipfile.ZipFile(ZIP_PATH, "r") as zip_ref:
zip_ref.extractall(BASE_DIR) # Extract into dataset folder
st.success("β
Dataset extracted!")
# π Check if dataset exists
if not os.path.exists(TRAIN_DIR):
st.error(f"β Dataset folder 'train' not found at {TRAIN_DIR}. Please upload the dataset.")
st.stop()
# π Verify Cats & Dogs Folders
cat_dir = os.path.join(TRAIN_DIR, "cats")
dog_dir = os.path.join(TRAIN_DIR, "dogs")
if not os.path.exists(cat_dir) or not os.path.exists(dog_dir):
st.error("β Missing 'cats' or 'dogs' folders inside 'train'. Please check your dataset.")
st.stop()
# π Constants
IMG_SIZE = (150, 150)
BATCH_SIZE = 32
MODEL_PATH = "cats_dogs_model.h5" # Ensure the model is uploaded to Hugging Face Space
# π― Load Model
if os.path.exists(MODEL_PATH):
model = tf.keras.models.load_model(MODEL_PATH)
else:
st.error("β No trained model found. Please upload 'cats_dogs_model.h5' to your Hugging Face repository.")
st.stop()
# π· Image Preprocessing
def preprocess_image(image):
image = image.convert('RGB').resize(IMG_SIZE)
img_array = np.array(image, dtype=np.float32) / 255.0
img_array = np.expand_dims(img_array, axis=0)
return img_array
# πΆπ± Classify Image
def classify_image(image):
processed_img = preprocess_image(image)
prediction = model.predict(processed_img)[0][0]
label = "Dog πΆ" if prediction > 0.5 else "Cat π±"
confidence = prediction if label == "Dog πΆ" else 1 - prediction
return label, confidence
# π Model Evaluation
def evaluate_model():
datagen = ImageDataGenerator(rescale=1.0 / 255, validation_split=0.2)
test_data = datagen.flow_from_directory(
TRAIN_DIR,
target_size=IMG_SIZE,
batch_size=BATCH_SIZE,
class_mode='binary',
subset='validation'
)
loss, accuracy = model.evaluate(test_data, verbose=0)
return accuracy, loss
# π Streamlit Tabs
tab1, tab2, tab3 = st.tabs(["π Dataset Preview", "π Model Performance", "πΆπ± Image Classification"])
# π Tab 1: Dataset Preview
with tab1:
st.write("### Dataset Overview")
dataset_info = {
"Total Images": len(os.listdir(cat_dir)) + len(os.listdir(dog_dir)),
"Cat Images": len(os.listdir(cat_dir)),
"Dog Images": len(os.listdir(dog_dir))
}
df_info = pd.DataFrame(list(dataset_info.items()), columns=["Category", "Count"])
st.dataframe(df_info)
# Visualization
st.write("### Image Distribution")
chart = alt.Chart(df_info).mark_bar().encode(
x="Category", y="Count", color="Category"
)
st.altair_chart(chart, use_container_width=True)
# π Tab 2: Model Performance
with tab2:
st.write("### Model Evaluation")
accuracy, loss = evaluate_model()
st.write(f"β
**Validation Accuracy:** {accuracy*100:.2f}%")
st.write(f"β
**Validation Loss:** {loss:.4f}")
# πΆπ± Tab 3: Image Classification
with tab3:
st.write("### Upload an Image for Classification")
uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "png", "jpeg"])
if uploaded_file:
image = Image.open(uploaded_file)
st.image(image, caption="Uploaded Image", use_container_width=True)
with st.spinner("Classifying..."):
label, confidence = classify_image(image)
st.subheader("Prediction:")
st.write(f"This is a **{label}** with **{confidence*100:.2f}%** confidence.")
# **New Feature: Download the 'test' folder as a ZIP**
def zip_folder(folder_path):
# Create an in-memory zip file
zip_buffer = io.BytesIO()
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
for root, dirs, files in os.walk(folder_path):
for file in files:
zip_file.write(os.path.join(root, file), os.path.relpath(os.path.join(root, file), folder_path))
zip_buffer.seek(0) # Go to the beginning of the file
return zip_buffer
# Button to download 'test' folder
if os.path.exists(TEST_DIR):
st.write("### Download Test Folder")
zip_buffer = zip_folder(TEST_DIR)
st.download_button(
label="Download Test Folder as ZIP",
data=zip_buffer,
file_name="test_folder.zip",
mime="application/zip"
)
else:
st.warning(f"β Test folder not found at {TEST_DIR}") |