jeysshon commited on
Commit
28becee
·
verified ·
1 Parent(s): 4bbcd31

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +213 -45
app.py CHANGED
@@ -1,50 +1,218 @@
1
  import gradio as gr
2
  import numpy as np
3
- import tensorflow as tf
4
  from tensorflow.keras.models import load_model
5
- from tensorflow.keras.preprocessing import image
6
-
7
- MODEL_ISATRON_JEY = 'modelo_isatron_jeysshonl.h5'
8
-
9
- cnn_model = load_model(MODEL_ISATRON_JEY)
10
-
11
- def make_prediction(test_image):
12
- test_image = image.load_img(test_image, target_size=(224, 224))
13
- test_image = image.img_to_array(test_image) / 255.
14
- test_image = np.expand_dims(test_image, axis=0)
15
- result = cnn_model.predict(test_image)
16
- return {"Normal": str(result[0][0]), "Neumonia": str(result[0][1])}
17
-
18
- # Actualización del tipo de entrada de imagen
19
- image_input = gr.Image(type="filepath")
20
-
21
- description = ("El modelo IsaTron es una Red Neuronal Convolucional (CNN) diseñada como un método de apoyo medico "
22
- "para el diagnóstico en imágenes radiológicas de neumonía pediátrica. Isatron arroja un porcentaje para "
23
- "lograr interpretar la radiografía torácica. En la parte inferior encontrará unas imágenes que pueden "
24
- "ser usadas para ejemplificar el funcionamiento del modelo. "
25
- "https://repositorio.unbosque.edu.co/handle/20.500.12495/9514")
26
-
27
- examples = [
28
- ['1normal.jpeg'],
29
- ['image1_pneumonia_virus.jpeg'],
30
- ['image1_pneumonia_bacteria.jpeg'],
31
- ['image2_normal.jpeg'],
32
- ['image2_pneumonia_bacteria.jpeg'],
33
- ['image3_normal.jpeg'],
34
- ['image4_normal.jpeg'],
35
- ]
36
-
37
- article = "<p style='text-align: center'><span style='font-size: 15pt;'>IsaTron . Jeysshon Bustos . 2022. </span></p>"
38
-
39
- interface = gr.Interface(
40
- fn=make_prediction,
41
- inputs=image_input,
42
- outputs='label',
43
- title="Modelo (CNN) IsaTron",
44
- description=description,
45
- article=article,
46
- examples=examples
47
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
- interface.launch(share=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
 
 
 
 
1
  import gradio as gr
2
  import numpy as np
3
+ import cv2
4
  from tensorflow.keras.models import load_model
5
+ import tensorflow as tf
6
+ from tensorflow import keras
7
+
8
+ # Cargar el modelo entrenado
9
+ MODEL_PATH = 'modelo_isatron_jeysshonl.h5'
10
+ model = load_model(MODEL_PATH)
11
+
12
+ # Función para encontrar la última capa convolucional
13
+ def find_last_conv_layer(model):
14
+ """Encuentra la última capa convolucional en el modelo"""
15
+ for layer in reversed(model.layers):
16
+ if 'conv' in layer.name.lower():
17
+ return layer.name
18
+ raise ValueError("No se encontró una capa convolucional en el modelo.")
19
+
20
+ # Obtener el nombre de la última capa convolucional
21
+ try:
22
+ last_conv_layer_name = find_last_conv_layer(model)
23
+ print(f"Última capa convolucional encontrada: {last_conv_layer_name}")
24
+ except ValueError as e:
25
+ print(f"Advertencia: {e}")
26
+ last_conv_layer_name = None
27
+
28
+ # Definir tamaño de imagen (tu modelo usa 224x224)
29
+ IMG_SIZE = 224
30
+
31
+ def load_and_preprocess_image(img):
32
+ """Preprocesa la imagen para el modelo"""
33
+ # Convertir imagen de Gradio (PIL Image) a array numpy
34
+ img = np.array(img)
35
+
36
+ # Si la imagen es RGB, convertir a escala de grises si el modelo lo requiere
37
+ # Tu modelo parece usar RGB (224, 224, 3), así que mantenemos RGB
38
+ if len(img.shape) == 2: # Si es escala de grises
39
+ img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
40
+
41
+ # Redimensionar imagen al tamaño requerido
42
+ img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))
43
+
44
+ # Normalizar imagen
45
+ img = img / 255.0
46
+
47
+ # Expandir dimensiones para batch
48
+ img = np.expand_dims(img, axis=0)
49
+
50
+ return img
51
+
52
+ def make_gradcam_heatmap(img_array, model, last_conv_layer_name, pred_index=None):
53
+ """Genera un mapa de calor Grad-CAM"""
54
+ if last_conv_layer_name is None:
55
+ return None
56
+
57
+ try:
58
+ # Crear un modelo que mapee la imagen de entrada a las activaciones
59
+ grad_model = keras.models.Model(
60
+ [model.inputs],
61
+ [model.get_layer(last_conv_layer_name).output, model.output]
62
+ )
63
 
64
+ # Calcular el gradiente de la clase predicha
65
+ with tf.GradientTape() as tape:
66
+ last_conv_layer_output, preds = grad_model(img_array)
67
+ if pred_index is None:
68
+ pred_index = np.argmax(preds[0])
69
+ class_channel = preds[:, pred_index]
70
+
71
+ # Calcular los gradientes
72
+ grads = tape.gradient(class_channel, last_conv_layer_output)
73
+
74
+ # Pooling global de los gradientes
75
+ pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
76
+
77
+ # Multiplicar cada canal por su importancia
78
+ last_conv_layer_output = last_conv_layer_output[0]
79
+ heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis]
80
+ heatmap = tf.squeeze(heatmap)
81
+
82
+ # Normalizar el mapa de calor entre 0 y 1
83
+ heatmap = tf.maximum(heatmap, 0) / tf.reduce_max(heatmap)
84
+ heatmap = heatmap.numpy()
85
+
86
+ return heatmap
87
+ except Exception as e:
88
+ print(f"Error generando Grad-CAM: {e}")
89
+ return None
90
+
91
+ def overlay_heatmap(heatmap, img, alpha=0.4):
92
+ """Superpone el mapa de calor en la imagen original"""
93
+ # Redimensionar mapa de calor al tamaño de la imagen
94
+ heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))
95
+
96
+ # Convertir mapa de calor a RGB
97
+ heatmap = np.uint8(255 * heatmap)
98
+ heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
99
+
100
+ # Asegurar que img esté en formato correcto
101
+ if len(img.shape) == 2: # Escala de grises
102
+ img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
103
+ elif img.shape[2] == 3: # RGB
104
+ img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
105
+
106
+ # Aplicar mapa de calor a la imagen original
107
+ overlayed_img = heatmap * alpha + img
108
+ overlayed_img = np.uint8(overlayed_img)
109
+
110
+ # Convertir de nuevo a RGB para Gradio
111
+ overlayed_img = cv2.cvtColor(overlayed_img, cv2.COLOR_BGR2RGB)
112
+
113
+ return overlayed_img
114
+
115
+ def image_classifier(img):
116
+ """Función principal de clasificación con Grad-CAM"""
117
+ # Mantener la imagen original para superponer
118
+ orig_img = np.array(img)
119
+
120
+ # Preprocesar la imagen
121
+ img_array = load_and_preprocess_image(img)
122
+
123
+ # Realizar predicción
124
+ preds = model.predict(img_array, verbose=0)
125
+
126
+ # Tu modelo devuelve [Normal, Neumonía]
127
+ normal_prob = float(preds[0][0])
128
+ pneumonia_prob = float(preds[0][1])
129
+
130
+ # Determinar el índice de la clase predicha
131
+ pred_index = np.argmax(preds[0])
132
+
133
+ # Generar mapa de calor si es posible
134
+ if last_conv_layer_name:
135
+ heatmap = make_gradcam_heatmap(img_array, model, last_conv_layer_name, pred_index=pred_index)
136
+ if heatmap is not None:
137
+ overlayed_img = overlay_heatmap(heatmap, orig_img)
138
+ else:
139
+ overlayed_img = orig_img
140
+ else:
141
+ overlayed_img = orig_img
142
+
143
+ # Preparar resultado de predicción
144
+ prediction_result = {
145
+ 'NORMAL': normal_prob,
146
+ 'NEUMONÍA': pneumonia_prob
147
+ }
148
+
149
+ return overlayed_img, prediction_result
150
+
151
+ # Crear interfaz Gradio mejorada
152
+ demo = gr.Interface(
153
+ fn=image_classifier,
154
+ inputs=gr.Image(type="pil", label="Subir imagen de rayos X"),
155
+ outputs=[
156
+ gr.Image(type="numpy", label="Imagen con Mapa de Calor (Grad-CAM)"),
157
+ gr.Label(label="Predicción", num_top_classes=2)
158
+ ],
159
+ title="<h1 style='text-align: center;'>IsaTron V2: Herramienta de Apoyo al Diagnóstico de Neumonía</h1>",
160
+ description="""
161
+ <div style='text-align: justify;'>
162
+ IsaTron es una herramienta de inteligencia artificial desarrollada con redes neuronales convolucionales (CNN)
163
+ para apoyar el diagnóstico de neumonía pediátrica a partir de imágenes de rayos X de tórax. La IA analiza las
164
+ imágenes y produce un mapa de calor Grad-CAM que resalta las áreas de mayor relevancia para la predicción del
165
+ modelo, lo cual ayuda a los profesionales de la salud a visualizar mejor las zonas potencialmente afectadas.
166
+ </div>
167
+ <br>
168
+ <div style='text-align: justify;'>
169
+ <strong>⚠️ Advertencia Importante:</strong> IsaTron está diseñado exclusivamente como una herramienta de apoyo
170
+ al diagnóstico y NO reemplaza una evaluación médica profesional. Es crucial que los resultados generados por
171
+ esta herramienta sean interpretados por personal de salud calificado. Esta herramienta no debe utilizarse para
172
+ tomar decisiones clínicas sin la supervisión de un médico especialista.
173
+ </div>
174
+ """,
175
+ examples=[
176
+ ['1normal.jpeg'],
177
+ ['image1_pneumonia_virus.jpeg'],
178
+ ['image1_pneumonia_bacteria.jpeg'],
179
+ ['image2_normal.jpeg'],
180
+ ['image2_pneumonia_bacteria.jpeg'],
181
+ ['image3_normal.jpeg'],
182
+ ['image4_normal.jpeg']
183
+ ],
184
+ article="""
185
+ <div style='text-align: justify;'>
186
+ <h3>Sobre IsaTron</h3>
187
+ <p>
188
+ Este proyecto utiliza tecnologías avanzadas de inteligencia artificial, incluyendo redes neuronales
189
+ convolucionales (CNN) y Grad-CAM (Gradient-weighted Class Activation Mapping), para mejorar la
190
+ interpretabilidad de los resultados. IsaTron ha sido entrenado con imágenes médicas de rayos X de tórax
191
+ y es capaz de predecir neumonía con un alto grado de confianza.
192
+ </p>
193
+ <p>
194
+ <strong>Grad-CAM</strong> permite visualizar qué regiones de la imagen son más importantes para la decisión
195
+ del modelo, proporcionando transparencia en el proceso de clasificación y ayudando a los profesionales
196
+ médicos a comprender mejor el razonamiento de la IA.
197
+ </p>
198
+ <p>
199
+ Los resultados obtenidos deben ser confirmados por un médico especialista para realizar un diagnóstico
200
+ clínico adecuado. Para más información sobre el proyecto, visite:
201
+ <a href="https://repositorio.unbosque.edu.co/handle/20.500.12495/9514" target="_blank">
202
+ Repositorio Institucional Universidad El Bosque
203
+ </a>
204
+ </p>
205
+ </div>
206
+ <br>
207
+ <div style='text-align: center;'>
208
+ <p><strong>IsaTron V2 - Desarrollado por Jeysshon Bustos</strong></p>
209
+ <p>Universidad El Bosque © 2022-2024</p>
210
+ </div>
211
+ """,
212
+ theme=gr.themes.Soft(),
213
+ allow_flagging="never"
214
+ )
215
 
216
+ # Ejecutar la interfaz
217
+ if __name__ == "__main__":
218
+ demo.launch(share=True)