Hemant0000's picture
Update app.py
ee0fc9d verified
raw
history blame
8.11 kB
#Data Preprocessing
import os
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from PIL import Image
# Set image size and batch size
IMAGE_SIZE = (224, 224)
BATCH_SIZE = 32
# Paths to your dataset
TRAIN_PATH = 'Covid_19 Image Data'
# Data generator for loading and preprocessing images
datagen = ImageDataGenerator(rescale=1./255, validation_split=0.15)
train_data = datagen.flow_from_directory(
TRAIN_PATH,
target_size=IMAGE_SIZE,
batch_size=BATCH_SIZE,
class_mode='binary',
subset='training' # Set as training data
)
val_data = datagen.flow_from_directory(
TRAIN_PATH,
target_size=IMAGE_SIZE,
batch_size=BATCH_SIZE,
class_mode='binary',
subset='validation' # Set as validation data
)
#CNN Model Setup (Transfer Learning)
import tensorflow as tf
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout
from tensorflow.keras.models import Model
# Define the input shape
input_shape = (224, 224, 3)
# Load ResNet50 with input shape and without the top layer
base_model = ResNet50(weights='imagenet', include_top=False, input_shape=input_shape)
# Freeze the layers in the base model
base_model.trainable = False
# Add custom layers on top
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(128, activation='relu')(x)
x = Dropout(0.5)(x)
predictions = Dense(1, activation='sigmoid')(x)
# Define the model
model = Model(inputs=base_model.input, outputs=predictions)
# Compile the model
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# Model summary
model.summary()
#Training the Model
# Train the model
history = model.fit(
train_data,
validation_data=val_data,
epochs=10, # Adjust epochs as needed
verbose=1
)
import matplotlib.pyplot as plt
# Plot the training and validation accuracy
plt.figure(figsize=(12, 6))
# Accuracy plot
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Model Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')
plt.grid(True)
# Loss plot
plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Model Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend(loc='upper right')
plt.grid(True)
# Show the plot
plt.tight_layout()
plt.show()
#Explainable AI Integration (Grad-CAM)
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.keras.models import Model
from PIL import Image
def make_gradcam_heatmap(img_array, model, last_conv_layer_name):
grad_model = Model(
inputs=[model.inputs],
outputs=[model.get_layer(last_conv_layer_name).output, model.output]
)
# Record operations for automatic differentiation
with tf.GradientTape() as tape:
conv_outputs, predictions = grad_model(img_array)
loss = predictions[:, 0] # Assuming binary classification (0 = Healthy, 1 = COVID-19)
# Compute gradients
grads = tape.gradient(loss, conv_outputs)
pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
conv_outputs = conv_outputs[0]
heatmap = tf.reduce_mean(tf.multiply(pooled_grads, conv_outputs), axis=-1)
heatmap = np.maximum(heatmap, 0) / np.max(heatmap) # Normalize between 0 and 1
return heatmap
def display_gradcam(img_path, heatmap, alpha=0.4):
img = Image.open(img_path)
img = img.resize((224, 224)) # Resize the image to match model input size
heatmap = np.uint8(255 * heatmap) # Convert heatmap to 0-255 scale
heatmap = Image.fromarray(heatmap).resize((img.size), Image.LANCZOS)
heatmap = np.array(heatmap)
# Create figure to plot the image and heatmap
fig, ax = plt.subplots(1, 2, figsize=(10, 5))
ax[0].imshow(img)
ax[1].imshow(img)
ax[1].imshow(heatmap, cmap='jet', alpha=alpha) # Overlay the heatmap
plt.show()
# Load and preprocess the image
def preprocess_image(image_path):
img = Image.open(image_path)
img = img.resize((224, 224)) # Resize to match the input shape of the model
img = np.array(img) / 255.0 # Normalize pixel values between 0 and 1
img = np.expand_dims(img, axis=0) # Add batch dimension
return img
# Path to the image
img_path = 'Covid_19 Image Data/1/COVID-19 (10).jpg'
# Preprocess the image
img_array = preprocess_image(img_path)
# Get the heatmap
heatmap = make_gradcam_heatmap(img_array, model, 'conv5_block3_out') # Replace with your last conv layer's name
# Display the original image with the Grad-CAM heatmap overlay
display_gradcam(img_path, heatmap)
#Evaluation
# Evaluate model on validation data
test_loss, test_acc = model.evaluate(val_data, verbose=2)
print(f'Test Accuracy: {test_acc:.2f}')
#Gradio User Interface
import gradio as gr
import numpy as np
from PIL import Image
import tensorflow as tf
from tensorflow.keras.models import Model
import matplotlib.pyplot as plt
import cv2 # For color mapping the heatmap
# Define the Grad-CAM function
def make_gradcam_heatmap(img_array, model, last_conv_layer_name):
grad_model = Model([model.inputs], [model.get_layer(last_conv_layer_name).output, model.output])
with tf.GradientTape() as tape:
conv_outputs, predictions = grad_model(img_array)
loss = predictions[:, 0] # For binary classification
grads = tape.gradient(loss, conv_outputs)
pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
conv_outputs = conv_outputs[0]
heatmap = tf.reduce_mean(tf.multiply(pooled_grads, conv_outputs), axis=-1)
heatmap = np.maximum(heatmap, 0) # ReLU activation to make it non-negative
heatmap = heatmap / np.max(heatmap) # Normalize between 0 and 1
return heatmap
# Function to overlay the heatmap on the original image
def apply_heatmap_to_image(img, heatmap):
# Resize heatmap to match image size
heatmap = cv2.resize(heatmap, (img.size[0], img.size[1]))
# Convert heatmap to RGB (apply 'jet' colormap)
heatmap_colored = cv2.applyColorMap(np.uint8(255 * heatmap), cv2.COLORMAP_JET)
# Convert to RGB mode (since OpenCV uses BGR)
heatmap_colored = cv2.cvtColor(heatmap_colored, cv2.COLOR_BGR2RGB)
# Overlay the heatmap on the original image
overlay = np.array(img) * 0.6 + heatmap_colored * 0.4
overlay = np.clip(overlay, 0, 255).astype('uint8')
return Image.fromarray(overlay)
# Define the prediction and explainability function
def predict_and_explain(img):
img = Image.fromarray(img).resize((224, 224)) # Resize image for the model
img_array = np.array(img) / 255.0 # Normalize pixel values
img_array = np.expand_dims(img_array, axis=0) # Add batch dimension
# Get the prediction
prediction = model.predict(img_array)
confidence = float(prediction[0][0])
result = "COVID-19 Positive" if confidence > 0.5 else "Healthy"
# Generate the Grad-CAM heatmap
last_conv_layer_name = 'conv5_block3_out' # Update with the actual last convolution layer name
heatmap = make_gradcam_heatmap(img_array, model, last_conv_layer_name)
# Apply heatmap on the image
heatmap_img = apply_heatmap_to_image(img, heatmap)
# Display confidence and heatmap
confidence_text = f"Confidence: {confidence:.2f}"
return result, confidence_text, heatmap_img
# Gradio interface
def create_interface():
gr_interface = gr.Interface(
fn=predict_and_explain,
inputs=gr.Image(type="numpy"),
outputs=[gr.Textbox(label="Prediction"), gr.Textbox(label="Confidence"), gr.Image(label="Heatmap")],
title="COVID-19 X-ray Classification with Explainability",
description="Upload an X-ray image to predict if the patient has COVID-19, see the confidence score, and view the Grad-CAM heatmap."
)
return gr_interface
# Launch the interface
gr_interface = create_interface()
gr_interface.launch()