iBrokeTheCode's picture
feat: Load saved models
0225bda
raw
history blame
5.71 kB
import gradio as gr
from predictor import predict
# πŸ“Œ CUSTOM CSS
css_code = """
#footer-container {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 1000;
background-color: var(--background-fill-primary);
padding: var(--spacing-md);
border-top: 1px solid var(--border-color-primary);
text-align: center;
}
.gradio-container {
padding-bottom: 70px !important;
}
"""
def update_inputs(mode: str):
if mode == "Multimodal":
return gr.Textbox(visible=True), gr.Image(visible=True)
elif mode == "Text Only":
return gr.Textbox(visible=True), gr.Image(visible=False)
elif mode == "Image Only":
return gr.Textbox(visible=False), gr.Image(visible=True)
else: # Default case
return gr.Textbox(visible=True), gr.Image(visible=True)
# πŸ“Œ USER INTERFACE
with gr.Blocks(
title="Multimodal Product Classification",
theme=gr.themes.Ocean(),
css=css_code,
) as demo:
with gr.Tabs():
# πŸ“Œ APP TAB
with gr.TabItem("App"):
gr.Markdown("""
<div style="text-align: center;">
<h1>πŸ›οΈ Multimodal Product Classification</h1>
</div>
<br><br>
""")
with gr.Row(equal_height=True):
# πŸ“Œ CLASSIFICATION INPUTS COLUMN
with gr.Column():
with gr.Column():
gr.Markdown("## πŸ“ Classification Inputs")
mode_radio = gr.Radio(
choices=["Multimodal", "Text Only", "Image Only"],
value="Multimodal",
label="Choose Classification Mode:",
)
text_input = gr.Textbox(
label="Product Description:",
placeholder="e.g., Apple iPhone 15 Pro Max 256GB",
)
image_input = gr.Image(
label="Product Image",
type="filepath",
visible=True,
height=350,
width="100%",
)
classify_button = gr.Button(
"✨ Classify Product", variant="primary"
)
# πŸ“Œ RESULTS COLUMN
with gr.Column():
with gr.Column():
gr.Markdown("## πŸ“Š Results")
gr.Markdown(
"""**πŸ’‘ How to use this app**
This app classifies a product based on its description and image.
- **Multimodal:** Uses both text and image for the most accurate prediction.
- **Text Only:** Uses only the product description.
- **Image Only:** Uses only the product image.
"""
)
gr.HTML("<hr>")
output_label = gr.Label(
label="Predict category", num_top_classes=5
)
# πŸ“Œ ABOUT TAB
with gr.TabItem("About"):
gr.Markdown("""
## About This Project
- This project is an image classification app powered by a Convolutional Neural Network (CNN).
- Simply upload an image, and the app predicts its category from over 1,000 classes using a pre-trained ResNet50 model.
- Originally developed as a multi-service ML system (FastAPI + Redis + Streamlit), this version has been adapted into a single Streamlit app for lightweight, cost-effective deployment on Hugging Face Spaces.
## Model & Description
- Model: ResNet50 (pre-trained on the ImageNet dataset with 1,000+ categories).
- Pipeline: Images are resized, normalized, and passed to the model.
- Output: The app displays the Top prediction with confidence score.
ResNet50 is widely used in both research and production, making it an excellent showcase of deep learning capabilities and transferable ML skills.
""")
# πŸ“Œ MODEL TAB
with gr.TabItem("Model"):
gr.Markdown("""
## Original Architecture
- FastAPI β†’ REST API for image processing
- Redis β†’ Message broker for service communication
- Streamlit β†’ Interactive web UI
- TensorFlow β†’ Deep learning inference engine
- Locust β†’ Load testing & benchmarking
- Docker Compose β†’ Service orchestration
## Simplified Version
- Streamlit only β†’ UI and model combined in a single app
- TensorFlow (ResNet50) β†’ Core prediction engine
- Docker β†’ Containerized for Hugging Face Spaces deployment
This evolution demonstrates the ability to design a scalable microservices system and also adapt it into a lightweight single-service solution for cost-effective demos.
""")
# πŸ“Œ FOOTER
# gr.HTML("<hr>")
with gr.Row(elem_id="footer-container"):
gr.HTML("""
<div>
<b>Connect with me:</b> πŸ’Ό <a href="https://www.linkedin.com/in/alex-turpo/" target="_blank">LinkedIn</a> β€’
🐱 <a href="https://github.com/iBrokeTheCode" target="_blank">GitHub</a> β€’
πŸ€— <a href="https://huggingface.co/iBrokeTheCode" target="_blank">Hugging Face</a>
</div>
""")
# πŸ“Œ EVENT LISTENERS
mode_radio.change(
fn=update_inputs,
inputs=mode_radio,
outputs=[text_input, image_input],
)
classify_button.click(
fn=predict, inputs=[mode_radio, text_input, image_input], outputs=output_label
)
demo.launch()