ericjedha commited on
Commit
7c78074
·
verified ·
1 Parent(s): 6c5b26a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -33
app.py CHANGED
@@ -57,10 +57,8 @@ def predict_single(image_pil, weights=(0.45, 0.25, 0.30)):
57
  preds_ensemble[:, mel_idx] = (0.5 * preds_ensemble[:, mel_idx] + 0.5 * pred_d[:, mel_idx])
58
 
59
  return {
60
- "ensemble": preds_ensemble[0],
61
- "xception": pred_x[0],
62
- "resnet50": pred_r[0],
63
- "densenet201": pred_d[0]
64
  }
65
 
66
  # ---- Grad-CAM ----
@@ -95,6 +93,11 @@ def make_gradcam(image_pil, model, last_conv_layer_name, class_index):
95
  heatmap = tf.maximum(heatmap, 0) / (tf.math.reduce_max(heatmap) + 1e-8)
96
  heatmap = heatmap.numpy()
97
 
 
 
 
 
 
98
  heatmap = np.uint8(255 * heatmap)
99
  heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
100
 
@@ -103,52 +106,51 @@ def make_gradcam(image_pil, model, last_conv_layer_name, class_index):
103
 
104
  return cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB)
105
 
106
- # ---- Fonction Gradio (avec la logique de diagnostic corrigée) ----
107
  def gradio_predict(image_pil):
108
  if image_pil is None: return "Veuillez uploader une image.", None, None
109
  try:
110
  all_preds = predict_single(image_pil)
111
  ensemble_probs = all_preds["ensemble"]
112
 
113
- # ===== NOUVELLE LOGIQUE DE DIAGNOSTIC (bien meilleure) =====
114
- # 1. On trouve la classe avec le plus haut score
115
  top_class_idx = np.argmax(ensemble_probs)
116
  top_class_name = CLASS_NAMES[top_class_idx]
117
-
118
- # 2. Le diagnostic global est celui de cette classe unique
119
  global_diag = diagnosis_map[top_class_name]
120
- # ==========================================================
121
 
122
- # Préparation du bar plot (inchangé)
123
  confidences = {CLASS_NAMES[i]: float(ensemble_probs[i]) for i in range(len(CLASS_NAMES))}
124
  df = pd.DataFrame.from_dict(confidences, orient='index', columns=['Probabilité'])
125
  df = df.sort_values(by='Probabilité', ascending=False)
126
  df.index.name = "Classe"
127
  df = df.reset_index()
128
 
129
- # Logique Grad-CAM dynamique (inchangée, elle utilisait déjà le top_class_idx)
130
- model_confidences = {
131
- "xception": all_preds["xception"][top_class_idx],
132
- "resnet50": all_preds["resnet50"][top_class_idx],
133
- "densenet201": all_preds["densenet201"][top_class_idx]
134
- }
135
- explainer_model_name = max(model_confidences, key=model_confidences.get)
136
-
137
- model_map = {"xception": model_xcept, "resnet50": model_resnet50, "densenet201": model_densenet}
138
- layer_map = {
139
- "xception": "block14_sepconv2_act",
140
- "resnet50": "conv5_block3_out",
141
- "densenet201": "relu"
142
- }
143
-
144
- explainer_model = model_map[explainer_model_name]
145
- explainer_layer = layer_map[explainer_model_name]
146
-
147
- gradcam_img = make_gradcam(image_pil, explainer_model, explainer_layer, class_index=top_class_idx)
 
 
 
 
148
 
149
  return global_diag, df, gradcam_img
 
150
  except Exception as e:
151
- print(f"Erreur dans gradio_predict : {e}")
152
  import traceback
153
  traceback.print_exc()
154
  return "Erreur lors du traitement de l'image.", None, None
@@ -157,8 +159,7 @@ def gradio_predict(image_pil):
157
  example_paths = ["exemple1.jpg", "exemple2.jpg", "exemple3.jpg"]
158
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
159
  gr.Markdown("# Analyse de lésions cutanées (Ensemble de modèles + Grad-CAM)")
160
- gr.Markdown("Cet outil propose une prédiction de la nature de la lésion (Bénin/Malin) avec explication visuelle dynamique. "
161
- "Le diagnostic global est déterminé par la classe unique ayant le score le plus élevé.")
162
  with gr.Row():
163
  with gr.Column(scale=1):
164
  input_image = gr.Image(type="pil", label="Uploader une image de lésion")
 
57
  preds_ensemble[:, mel_idx] = (0.5 * preds_ensemble[:, mel_idx] + 0.5 * pred_d[:, mel_idx])
58
 
59
  return {
60
+ "ensemble": preds_ensemble[0], "xception": pred_x[0],
61
+ "resnet50": pred_r[0], "densenet201": pred_d[0]
 
 
62
  }
63
 
64
  # ---- Grad-CAM ----
 
93
  heatmap = tf.maximum(heatmap, 0) / (tf.math.reduce_max(heatmap) + 1e-8)
94
  heatmap = heatmap.numpy()
95
 
96
+ # ===== CORRECTION FINALE ET CRUCIALE =====
97
+ # On redimensionne la heatmap (ex: 7x7) à la taille de l'image (ex: 224x224)
98
+ heatmap = cv2.resize(heatmap, (img_resized.shape[1], img_resized.shape[0]))
99
+ # =======================================
100
+
101
  heatmap = np.uint8(255 * heatmap)
102
  heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
103
 
 
106
 
107
  return cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB)
108
 
109
+ # ---- Fonction Gradio (avec gestion d'erreur pour Grad-CAM) ----
110
  def gradio_predict(image_pil):
111
  if image_pil is None: return "Veuillez uploader une image.", None, None
112
  try:
113
  all_preds = predict_single(image_pil)
114
  ensemble_probs = all_preds["ensemble"]
115
 
 
 
116
  top_class_idx = np.argmax(ensemble_probs)
117
  top_class_name = CLASS_NAMES[top_class_idx]
 
 
118
  global_diag = diagnosis_map[top_class_name]
 
119
 
 
120
  confidences = {CLASS_NAMES[i]: float(ensemble_probs[i]) for i in range(len(CLASS_NAMES))}
121
  df = pd.DataFrame.from_dict(confidences, orient='index', columns=['Probabilité'])
122
  df = df.sort_values(by='Probabilité', ascending=False)
123
  df.index.name = "Classe"
124
  df = df.reset_index()
125
 
126
+ # --- BLOC GRAD-CAM SÉCURISÉ ---
127
+ gradcam_img = None # Initialisation à None
128
+ try:
129
+ model_confidences = {
130
+ "xception": all_preds["xception"][top_class_idx],
131
+ "resnet50": all_preds["resnet50"][top_class_idx],
132
+ "densenet201": all_preds["densenet201"][top_class_idx]
133
+ }
134
+ explainer_model_name = max(model_confidences, key=model_confidences.get)
135
+
136
+ model_map = {"xception": model_xcept, "resnet50": model_resnet50, "densenet201": model_densenet}
137
+ layer_map = {"xception": "block14_sepconv2_act", "resnet50": "conv5_block3_out", "densenet201": "relu"}
138
+
139
+ explainer_model = model_map[explainer_model_name]
140
+ explainer_layer = layer_map[explainer_model_name]
141
+
142
+ print(f"Génération du Grad-CAM avec le modèle '{explainer_model_name}' sur la couche '{explainer_layer}'.")
143
+ gradcam_img = make_gradcam(image_pil, explainer_model, explainer_layer, class_index=top_class_idx)
144
+ except Exception as e:
145
+ print(f"--- ERREUR LORS DE LA GÉNÉRATION DE GRAD-CAM (le reste de l'app continue) ---")
146
+ print(e)
147
+ # gradcam_img reste à None, Gradio affichera une boîte vide
148
+ # --- FIN DU BLOC SÉCURISÉ ---
149
 
150
  return global_diag, df, gradcam_img
151
+
152
  except Exception as e:
153
+ print(f"Erreur majeure dans gradio_predict : {e}")
154
  import traceback
155
  traceback.print_exc()
156
  return "Erreur lors du traitement de l'image.", None, None
 
159
  example_paths = ["exemple1.jpg", "exemple2.jpg", "exemple3.jpg"]
160
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
161
  gr.Markdown("# Analyse de lésions cutanées (Ensemble de modèles + Grad-CAM)")
162
+ gr.Markdown("Cet outil propose une prédiction de la nature de la lésion (Bénin/Malin) avec explication visuelle dynamique.")
 
163
  with gr.Row():
164
  with gr.Column(scale=1):
165
  input_image = gr.Image(type="pil", label="Uploader une image de lésion")