Hemant0000 commited on
Commit
cd33b88
·
verified ·
1 Parent(s): 9753a39

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +253 -0
app.py ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ **Data Preprocessing**
2
+
3
+ import os
4
+ import numpy as np
5
+ import tensorflow as tf
6
+ from tensorflow.keras.preprocessing.image import ImageDataGenerator
7
+ from PIL import Image
8
+
9
+ # Set image size and batch size
10
+ IMAGE_SIZE = (224, 224)
11
+ BATCH_SIZE = 32
12
+
13
+ # Paths to your dataset
14
+ TRAIN_PATH = 'Covid_19 Image Data'
15
+
16
+ # Data generator for loading and preprocessing images
17
+ datagen = ImageDataGenerator(rescale=1./255, validation_split=0.15)
18
+
19
+ train_data = datagen.flow_from_directory(
20
+ TRAIN_PATH,
21
+ target_size=IMAGE_SIZE,
22
+ batch_size=BATCH_SIZE,
23
+ class_mode='binary',
24
+ subset='training' # Set as training data
25
+ )
26
+
27
+ val_data = datagen.flow_from_directory(
28
+ TRAIN_PATH,
29
+ target_size=IMAGE_SIZE,
30
+ batch_size=BATCH_SIZE,
31
+ class_mode='binary',
32
+ subset='validation' # Set as validation data
33
+ )
34
+
35
+ ** CNN Model Setup (Transfer Learning)**
36
+
37
+ import tensorflow as tf
38
+ from tensorflow.keras.applications import ResNet50
39
+ from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout
40
+ from tensorflow.keras.models import Model
41
+
42
+ # Define the input shape
43
+ input_shape = (224, 224, 3)
44
+
45
+ # Load ResNet50 with input shape and without the top layer
46
+ base_model = ResNet50(weights='imagenet', include_top=False, input_shape=input_shape)
47
+
48
+ # Freeze the layers in the base model
49
+ base_model.trainable = False
50
+
51
+ # Add custom layers on top
52
+ x = base_model.output
53
+ x = GlobalAveragePooling2D()(x)
54
+ x = Dense(128, activation='relu')(x)
55
+ x = Dropout(0.5)(x)
56
+ predictions = Dense(1, activation='sigmoid')(x)
57
+
58
+ # Define the model
59
+ model = Model(inputs=base_model.input, outputs=predictions)
60
+
61
+ # Compile the model
62
+ model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
63
+
64
+ # Model summary
65
+ model.summary()
66
+
67
+ **Training the Model**
68
+
69
+ # Train the model
70
+ history = model.fit(
71
+ train_data,
72
+ validation_data=val_data,
73
+ epochs=10, # Adjust epochs as needed
74
+ verbose=1
75
+ )
76
+
77
+ import matplotlib.pyplot as plt
78
+
79
+ # Plot the training and validation accuracy
80
+ plt.figure(figsize=(12, 6))
81
+
82
+ # Accuracy plot
83
+ plt.subplot(1, 2, 1)
84
+ plt.plot(history.history['accuracy'], label='Training Accuracy')
85
+ plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
86
+ plt.title('Model Accuracy')
87
+ plt.xlabel('Epoch')
88
+ plt.ylabel('Accuracy')
89
+ plt.legend(loc='lower right')
90
+ plt.grid(True)
91
+
92
+ # Loss plot
93
+ plt.subplot(1, 2, 2)
94
+ plt.plot(history.history['loss'], label='Training Loss')
95
+ plt.plot(history.history['val_loss'], label='Validation Loss')
96
+ plt.title('Model Loss')
97
+ plt.xlabel('Epoch')
98
+ plt.ylabel('Loss')
99
+ plt.legend(loc='upper right')
100
+ plt.grid(True)
101
+
102
+ # Show the plot
103
+ plt.tight_layout()
104
+ plt.show()
105
+
106
+ **Explainable AI Integration (Grad-CAM)**
107
+
108
+ import numpy as np
109
+ import tensorflow as tf
110
+ import matplotlib.pyplot as plt
111
+ from tensorflow.keras.models import Model
112
+ from PIL import Image
113
+
114
+ def make_gradcam_heatmap(img_array, model, last_conv_layer_name):
115
+ grad_model = Model(
116
+ inputs=[model.inputs],
117
+ outputs=[model.get_layer(last_conv_layer_name).output, model.output]
118
+ )
119
+
120
+ # Record operations for automatic differentiation
121
+ with tf.GradientTape() as tape:
122
+ conv_outputs, predictions = grad_model(img_array)
123
+ loss = predictions[:, 0] # Assuming binary classification (0 = Healthy, 1 = COVID-19)
124
+
125
+ # Compute gradients
126
+ grads = tape.gradient(loss, conv_outputs)
127
+ pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
128
+
129
+ conv_outputs = conv_outputs[0]
130
+ heatmap = tf.reduce_mean(tf.multiply(pooled_grads, conv_outputs), axis=-1)
131
+ heatmap = np.maximum(heatmap, 0) / np.max(heatmap) # Normalize between 0 and 1
132
+ return heatmap
133
+
134
+ def display_gradcam(img_path, heatmap, alpha=0.4):
135
+ img = Image.open(img_path)
136
+ img = img.resize((224, 224)) # Resize the image to match model input size
137
+
138
+ heatmap = np.uint8(255 * heatmap) # Convert heatmap to 0-255 scale
139
+ heatmap = Image.fromarray(heatmap).resize((img.size), Image.ANTIALIAS)
140
+ heatmap = np.array(heatmap)
141
+
142
+ # Create figure to plot the image and heatmap
143
+ fig, ax = plt.subplots(1, 2, figsize=(10, 5))
144
+ ax[0].imshow(img)
145
+ ax[1].imshow(img)
146
+ ax[1].imshow(heatmap, cmap='jet', alpha=alpha) # Overlay the heatmap
147
+ plt.show()
148
+
149
+ # Load and preprocess the image
150
+ def preprocess_image(image_path):
151
+ img = Image.open(image_path)
152
+ img = img.resize((224, 224)) # Resize to match the input shape of the model
153
+ img = np.array(img) / 255.0 # Normalize pixel values between 0 and 1
154
+ img = np.expand_dims(img, axis=0) # Add batch dimension
155
+ return img
156
+
157
+ # Path to the image
158
+ img_path = 'Covid_19 Image Data/1/COVID-19 (10).jpg'
159
+
160
+ # Preprocess the image
161
+ img_array = preprocess_image(img_path)
162
+
163
+ # Get the heatmap
164
+ heatmap = make_gradcam_heatmap(img_array, model, 'conv5_block3_out') # Replace with your last conv layer's name
165
+
166
+ # Display the original image with the Grad-CAM heatmap overlay
167
+ display_gradcam(img_path, heatmap)
168
+
169
+ **Evaluation**
170
+
171
+ # Evaluate model on validation data
172
+ test_loss, test_acc = model.evaluate(val_data, verbose=2)
173
+ print(f'Test Accuracy: {test_acc:.2f}')
174
+
175
+ **Gradio User Interface**
176
+
177
+ !pip install gradio
178
+
179
+ import gradio as gr
180
+ import numpy as np
181
+ from PIL import Image
182
+ import tensorflow as tf
183
+ from tensorflow.keras.models import Model
184
+ import matplotlib.pyplot as plt
185
+ import cv2 # For color mapping the heatmap
186
+
187
+ # Define the Grad-CAM function
188
+ def make_gradcam_heatmap(img_array, model, last_conv_layer_name):
189
+ grad_model = Model([model.inputs], [model.get_layer(last_conv_layer_name).output, model.output])
190
+ with tf.GradientTape() as tape:
191
+ conv_outputs, predictions = grad_model(img_array)
192
+ loss = predictions[:, 0] # For binary classification
193
+ grads = tape.gradient(loss, conv_outputs)
194
+ pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
195
+ conv_outputs = conv_outputs[0]
196
+ heatmap = tf.reduce_mean(tf.multiply(pooled_grads, conv_outputs), axis=-1)
197
+ heatmap = np.maximum(heatmap, 0) # ReLU activation to make it non-negative
198
+ heatmap = heatmap / np.max(heatmap) # Normalize between 0 and 1
199
+ return heatmap
200
+
201
+ # Function to overlay the heatmap on the original image
202
+ def apply_heatmap_to_image(img, heatmap):
203
+ # Resize heatmap to match image size
204
+ heatmap = cv2.resize(heatmap, (img.size[0], img.size[1]))
205
+
206
+ # Convert heatmap to RGB (apply 'jet' colormap)
207
+ heatmap_colored = cv2.applyColorMap(np.uint8(255 * heatmap), cv2.COLORMAP_JET)
208
+
209
+ # Convert to RGB mode (since OpenCV uses BGR)
210
+ heatmap_colored = cv2.cvtColor(heatmap_colored, cv2.COLOR_BGR2RGB)
211
+
212
+ # Overlay the heatmap on the original image
213
+ overlay = np.array(img) * 0.6 + heatmap_colored * 0.4
214
+ overlay = np.clip(overlay, 0, 255).astype('uint8')
215
+ return Image.fromarray(overlay)
216
+
217
+ # Define the prediction and explainability function
218
+ def predict_and_explain(img):
219
+ img = Image.fromarray(img).resize((224, 224)) # Resize image for the model
220
+ img_array = np.array(img) / 255.0 # Normalize pixel values
221
+ img_array = np.expand_dims(img_array, axis=0) # Add batch dimension
222
+
223
+ # Get the prediction
224
+ prediction = model.predict(img_array)
225
+ confidence = float(prediction[0][0])
226
+ result = "COVID-19 Positive" if confidence > 0.5 else "Healthy"
227
+
228
+ # Generate the Grad-CAM heatmap
229
+ last_conv_layer_name = 'conv5_block3_out' # Update with the actual last convolution layer name
230
+ heatmap = make_gradcam_heatmap(img_array, model, last_conv_layer_name)
231
+
232
+ # Apply heatmap on the image
233
+ heatmap_img = apply_heatmap_to_image(img, heatmap)
234
+
235
+ # Display confidence and heatmap
236
+ confidence_text = f"Confidence: {confidence:.2f}"
237
+ return result, confidence_text, heatmap_img
238
+
239
+ # Gradio interface
240
+ def create_interface():
241
+ gr_interface = gr.Interface(
242
+ fn=predict_and_explain,
243
+ inputs=gr.Image(type="numpy"),
244
+ outputs=[gr.Textbox(label="Prediction"), gr.Textbox(label="Confidence"), gr.Image(label="Heatmap")],
245
+ title="COVID-19 X-ray Classification with Explainability",
246
+ description="Upload an X-ray image to predict if the patient has COVID-19, see the confidence score, and view the Grad-CAM heatmap."
247
+ )
248
+ return gr_interface
249
+
250
+ # Launch the interface
251
+ gr_interface = create_interface()
252
+ gr_interface.launch()
253
+