To upload files, please first save the app
import os
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.resnet50 import ResNet50, preprocess_input as resnet_preprocess
from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input as vgg_preprocess
from tensorflow.keras.applications.inception_v3 import InceptionV3, preprocess_input as inception_preprocess
import time
import streamlit as st
from PIL import Image
import pandas as pd
import seaborn as sns
import requests
import io
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
# Set page configuration
st.set_page_config(
page_title="Brain Disorder ML Analysis",
page_icon="🧠",
layout="wide",
initial_sidebar_state="expanded"
)
# Add custom CSS
st.markdown("""
<style>
.main-header {
font-size: 2.5rem;
color: #4285F4;
text-align: center;
margin-bottom: 2rem;
}
.sub-header {
font-size: 1.5rem;
color: #34A853;
margin-bottom: 1rem;
}
.metric-card {
background-color: #f0f2f6;
border-radius: 10px;
padding: 1rem;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.model-section {
margin-bottom: 2rem;
padding: 1rem;
border-radius: 10px;
background-color: #f9f9f9;
}
</style>
""", unsafe_allow_html=True)
# Title and Introduction
st.markdown("<h1 class='main-header'>Comparative Analysis of ML Models on Brain Disorder Image Datasets</h1>", unsafe_allow_html=True)
st.markdown("""
This application allows you to analyze brain MRI images using different machine learning models
and compare their performance across various brain disorders including:
- Alzheimer's Disease (No/Very Mild/Mild/Moderate Impairment)
- Brain Tumors (Glioma, Meningioma, No Tumor, Pituitary)
- Parkinson's Disease
""")
# Initialize session state for storing results
if 'results' not in st.session_state:
st.session_state.results = {}
# Create sidebar for model selection
st.sidebar.title("Settings")
# Model selection
available_models = {
"AlexNet": "alexnet",
"ResNet-50": "resnet50",
"VGG-16": "vgg16",
"Inception V3": "inceptionv3"
}
selected_models = st.sidebar.multiselect(
"Select Models to Compare",
list(available_models.keys()),
default=["ResNet-50", "VGG-16"]
)
# Disorder selection
available_disorders = {
"Alzheimer's": {
"classes": ["No Impairment", "Very Mild Impairment", "Mild Impairment", "Moderate Impairment"],
"dataset_size": "5000+ images"
},
"Brain Tumor": {
"classes": ["Glioma", "Meningioma", "No Tumor", "Pituitary"],
"dataset_size": "7023 images"
},
"Parkinson's": {
"classes": ["Parkinson's", "Normal"],
"dataset_size": "830 images"
}
}
selected_disorders = st.sidebar.multiselect(
"Select Disorders to Analyze",
list(available_disorders.keys()),
default=["Brain Tumor"]
)
# Advanced settings
st.sidebar.markdown("---")
st.sidebar.markdown("<h3>Advanced Settings</h3>", unsafe_allow_html=True)
display_metrics = st.sidebar.checkbox("Show Detailed Metrics", value=True)
show_comparison_charts = st.sidebar.checkbox("Show Comparison Charts", value=True)
# Main content area split into two columns
col1, col2 = st.columns([1, 2])
# File uploader in the first column
with col1:
st.markdown("<h2 class='sub-header'>Upload Brain MRI Image</h2>", unsafe_allow_html=True)
uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"])
if uploaded_file is not None:
image_pil = Image.open(uploaded_file)
st.image(image_pil, caption="Uploaded MRI Image", use_column_width=True)
# Function to preprocess the image for different models
def preprocess_image(img, model_name, target_size=(224, 224)):
img_resized = img.resize(target_size)
img_array = image.img_to_array(img_resized)
img_array = np.expand_dims(img_array, axis=0)
if model_name == "resnet50":
return resnet_preprocess(img_array)
elif model_name == "vgg16":
return vgg_preprocess(img_array)
elif model_name == "inceptionv3":
return inception_preprocess(img_array)
else: # alexnet and others
return img_array / 255.0
# Second column for results and visualizations
with col2:
if uploaded_file is not None and selected_models and selected_disorders:
st.markdown("<h2 class='sub-header'>Analysis Results</h2>", unsafe_allow_html=True)
# Progress bar for analysis
progress_bar = st.progress(0)
status_text = st.empty()
# Initialize results dictionary
results = {}
# Analyze image with selected models and disorders
total_steps = len(selected_models) * len(selected_disorders)
current_step = 0
for model_name in selected_models:
model_key = available_models[model_name]
results[model_name] = {}
for disorder in selected_disorders:
current_step += 1
progress = current_step / total_steps
progress_bar.progress(progress)
status_text.text(f"Analyzing with {model_name} for {disorder}...")
# Simulate loading a pre-trained model
time.sleep(1) # Simulating model loading time
# Preprocess the image
preprocessed_img = preprocess_image(image_pil, model_key)
# Simulate prediction
time_start = time.time()
# In a real implementation, you would use an actual model:
# model = load_your_model(model_key, disorder)
# predictions = model.predict(preprocessed_img)
# Simulating prediction results
prediction_time = time.time() - time_start
# Simulate prediction results based on the disorder
if disorder == "Alzheimer's":
class_names = available_disorders[disorder]["classes"]
# Mock predictions - in real app, use actual model predictions
confidences = np.random.dirichlet(np.ones(len(class_names)))
predicted_class = class_names[np.argmax(confidences)]
accuracy = 0.85 + np.random.random() * 0.1 # 85-95% accuracy
elif disorder == "Brain Tumor":
class_names = available_disorders[disorder]["classes"]
# Mock predictions
confidences = np.random.dirichlet(np.ones(len(class_names)))
predicted_class = class_names[np.argmax(confidences)]
accuracy = 0.88 + np.random.random() * 0.11 # 88-99% accuracy
elif disorder == "Parkinson's":
class_names = available_disorders[disorder]["classes"]
# Mock predictions
confidences = np.random.dirichlet(np.ones(len(class_names)))
predicted_class = class_names[np.argmax(confidences)]
accuracy = 0.82 + np.random.random() * 0.15 # 82-97% accuracy
# Calculate additional metrics (simulated)
precision = accuracy - 0.02 + np.random.random() * 0.04
recall = accuracy - 0.03 + np.random.random() * 0.06
f1 = 2 * (precision * recall) / (precision + recall)
# Store results
results[model_name][disorder] = {
"predicted_class": predicted_class,
"confidences": confidences,
"class_names": class_names,
"accuracy": accuracy,
"precision": precision,
"recall": recall,
"f1_score": f1,
"prediction_time": prediction_time
}
# Save results to session state
st.session_state.results = results
# Clear progress indicators
progress_bar.empty()
status_text.empty()
# Display results
st.markdown("<h3>Results Summary</h3>", unsafe_allow_html=True)
# Create tabs for each disorder
tabs = st.tabs(selected_disorders)
for i, disorder in enumerate(selected_disorders):
with tabs[i]:
st.write(f"### {disorder} Analysis")
# Create a dataframe for all models' results for this disorder
model_results = []
for model_name in selected_models:
res = results[model_name][disorder]
model_results.append({
"Model": model_name,
"Predicted Class": res["predicted_class"],
"Confidence": f"{np.max(res['confidences']):.2%}",
"Accuracy": f"{res['accuracy']:.2%}",
"Precision": f"{res['precision']:.2%}",
"Recall": f"{res['recall']:.2%}",
"F1 Score": f"{res['f1_score']:.2%}",
"Analysis Time": f"{res['prediction_time']:.4f} sec"
})
# Display results as a table
df_results = pd.DataFrame(model_results)
st.dataframe(df_results)
# If detailed metrics are requested
if display_metrics:
st.write("#### Detailed Class Probabilities")
for model_name in selected_models:
res = results[model_name][disorder]
st.write(f"**{model_name}**")
# Create a dataframe for class probabilities
probs_df = pd.DataFrame({
'Class': res["class_names"],
'Probability': res["confidences"]
})
# Plot bar chart of probabilities
fig, ax = plt.subplots(figsize=(8, 3))
sns.barplot(x='Probability', y='Class', data=probs_df, ax=ax)
ax.set_xlim(0, 1)
ax.set_title(f"{model_name} - {disorder} Class Probabilities")
st.pyplot(fig)
# Show comparison charts if requested
if show_comparison_charts and len(selected_models) > 1:
st.write("#### Model Comparison")
# Extract metrics for comparison
metrics_df = pd.DataFrame([
{
"Model": model_name,
"Accuracy": results[model_name][disorder]["accuracy"],
"Precision": results[model_name][disorder]["precision"],
"Recall": results[model_name][disorder]["recall"],
"F1 Score": results[model_name][disorder]["f1_score"],
"Analysis Time (sec)": results[model_name][disorder]["prediction_time"]
}
for model_name in selected_models
])
# Create metrics comparison chart
fig, ax = plt.subplots(figsize=(10, 5))
metrics_df_melt = pd.melt(
metrics_df,
id_vars=['Model'],
value_vars=['Accuracy', 'Precision', 'Recall', 'F1 Score'],
var_name='Metric',
value_name='Value'
)
sns.barplot(x='Model', y='Value', hue='Metric', data=metrics_df_melt, ax=ax)
ax.set_title(f"Performance Metrics Comparison - {disorder}")
ax.set_ylim(0, 1)
st.pyplot(fig)
# Analysis time comparison
fig, ax = plt.subplots(figsize=(8, 3))
sns.barplot(x='Analysis Time (sec)', y='Model', data=metrics_df, ax=ax)
ax.set_title(f"Analysis Time Comparison - {disorder}")
st.pyplot(fig)
# Overall comparison if multiple disorders are selected
if len(selected_disorders) > 1:
st.markdown("---")
st.markdown("<h3>Cross-Disorder Comparison</h3>", unsafe_allow_html=True)
for model_name in selected_models:
st.write(f"### {model_name} Performance Across Disorders")
# Create dataframe for cross-disorder comparison
cross_disorder_df = pd.DataFrame([
{
"Disorder": disorder,
"Predicted Class": results[model_name][disorder]["predicted_class"],
"Accuracy": results[model_name][disorder]["accuracy"],
"Analysis Time (sec)": results[model_name][disorder]["prediction_time"]
}
for disorder in selected_disorders
])
st.dataframe(cross_disorder_df)
# Plot accuracy comparison across disorders
fig, ax = plt.subplots(figsize=(8, 4))
sns.barplot(x='Disorder', y='Accuracy', data=cross_disorder_df, ax=ax)
ax.set_title(f"{model_name} - Accuracy Across Disorders")
ax.set_ylim(0, 1)
st.pyplot(fig)
elif uploaded_file is not None:
st.warning("Please select at least one model and one disorder type to analyze.")
else:
st.info("Please upload an MRI image to begin analysis.")
# Additional information about the application
st.markdown("---")
st.markdown("<h2 class='sub-header'>About This Application</h2>", unsafe_allow_html=True)
st.write("""
This application demonstrates the comparative analysis of different machine learning models
for brain disorder detection from MRI images. The current implementation uses simulated results,
but in a production environment, it would load pre-trained models for each disorder type.
**Supported Model Architectures:**
- AlexNet
- ResNet-50
- VGG-16
- Inception V3
**Supported Brain Disorders:**
- Alzheimer's Disease (4 classes)
- Brain Tumors (4 classes)
- Parkinson's Disease (2 classes)
**Metrics Evaluated:**
- Accuracy
- Precision
- Recall
- F1 Score
- Analysis Time
""")
# Footer
st.markdown("---")
st.markdown("""
<div style="text-align: center">
Developed by Angel S Mushahary and Aman Singh<br>
Under the Supervision of Mr. Ashis Datta and Dr. Palash Ghosal
</div>
""", unsafe_allow_html=True)
# Function to run the app
def run_app():
st.empty()
if __name__ == "__main__":
run_app()
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?