ericjedha commited on
Commit
ad465b4
·
verified ·
1 Parent(s): 30f12e8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +8 -16
app.py CHANGED
@@ -32,23 +32,15 @@ from tensorflow.keras.applications.densenet import preprocess_input as preproces
32
 
33
  # ---- Fonctions utilitaires robustes pour les modèles Keras ----
34
  def get_primary_input_name(model):
35
- """Retourne le nom de la couche d'input principale du modèle."""
36
- # ===== LA CORRECTION FINALE ET DÉFINITIVE EST ICI =====
37
- # L'attribut correct est `model.inputs`, qui est une liste de tenseurs.
38
- # On prend le premier tenseur de la liste et on récupère son nom.
39
  if isinstance(model.inputs, list) and len(model.inputs) > 0:
40
- # Le nom est souvent de la forme "input_layer:0", on ne garde que "input_layer"
41
  return model.inputs[0].name.split(':')[0]
42
- # Fallback au cas où, mais ne devrait pas être nécessaire
43
  return "input_1"
44
- # =======================================================
45
 
46
  def safe_forward(model, x):
47
- """Appelle un modèle en utilisant le nom d'input correct pour éviter les UserWarnings."""
48
  input_name = get_primary_input_name(model)
49
  return model({input_name: x}, training=False).numpy()
50
 
51
- # ---- Prédiction (utilise maintenant safe_forward) ----
52
  def predict_single(image_pil, weights=(0.45, 0.25, 0.30)):
53
  img_np = np.array(image_pil)
54
  img_299 = cv2.resize(img_np, (299, 299))
@@ -68,7 +60,7 @@ def predict_single(image_pil, weights=(0.45, 0.25, 0.30)):
68
  return preds[0]
69
 
70
 
71
- # ---- Grad-CAM (combine TOUTES les corrections) ----
72
  def make_gradcam(image_pil, model, last_conv_layer_name="conv5_block32_concat", class_index=None):
73
  img_np = np.array(image_pil)
74
  img_resized = cv2.resize(img_np, (224, 224))
@@ -81,28 +73,30 @@ def make_gradcam(image_pil, model, last_conv_layer_name="conv5_block32_concat",
81
 
82
  with tf.GradientTape() as tape:
83
  last_conv_layer_output, preds = grad_model(input_for_model, training=False)
84
-
85
  if isinstance(preds, list):
86
  preds = preds[0]
87
-
88
  if class_index is None:
89
  class_index = tf.argmax(preds[0])
90
  class_channel = preds[:, class_index]
91
 
92
  grads = tape.gradient(class_channel, last_conv_layer_output)
93
 
94
- pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
95
- last_conv_layer_output = last_conv_layer_output[0]
 
96
 
 
97
  heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis]
98
  heatmap = tf.squeeze(heatmap)
99
  heatmap = tf.maximum(heatmap, 0) / (tf.math.reduce_max(heatmap) + 1e-8)
100
  heatmap = heatmap.numpy()
101
 
102
  heatmap = np.uint8(255 * heatmap)
 
103
  heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
104
 
105
  img_bgr = cv2.cvtColor(img_resized, cv2.COLOR_RGB2BGR)
 
106
  superimposed_img = cv2.addWeighted(img_bgr, 0.6, heatmap, 0.4, 0)
107
 
108
  return cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB)
@@ -113,7 +107,6 @@ def gradio_predict(image_pil):
113
  return "Veuillez uploader une image.", None, None
114
  try:
115
  probs = predict_single(image_pil)
116
-
117
  benign_prob = sum(probs[i] for i, cls in enumerate(CLASS_NAMES) if diagnosis_map[cls] == "Bénin")
118
  malign_prob = sum(probs[i] for i, cls in enumerate(CLASS_NAMES) if diagnosis_map[cls] == "Malin")
119
  global_diag = "Bénin" if benign_prob >= malign_prob else "Malin"
@@ -136,7 +129,6 @@ def gradio_predict(image_pil):
136
 
137
  # ---- Gradio UI ----
138
  example_paths = ["exemple1.jpg", "exemple2.jpg", "exemple3.jpg"]
139
-
140
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
141
  gr.Markdown("# Analyse de lésions cutanées (Ensemble de modèles + Grad-CAM)")
142
  gr.Markdown("Cet outil propose une prédiction de la nature de la lésion (Bénin/Malin) avec explication visuelle.")
 
32
 
33
  # ---- Fonctions utilitaires robustes pour les modèles Keras ----
34
  def get_primary_input_name(model):
 
 
 
 
35
  if isinstance(model.inputs, list) and len(model.inputs) > 0:
 
36
  return model.inputs[0].name.split(':')[0]
 
37
  return "input_1"
 
38
 
39
  def safe_forward(model, x):
 
40
  input_name = get_primary_input_name(model)
41
  return model({input_name: x}, training=False).numpy()
42
 
43
+ # ---- Prédiction ----
44
  def predict_single(image_pil, weights=(0.45, 0.25, 0.30)):
45
  img_np = np.array(image_pil)
46
  img_299 = cv2.resize(img_np, (299, 299))
 
60
  return preds[0]
61
 
62
 
63
+ # ---- Grad-CAM ----
64
  def make_gradcam(image_pil, model, last_conv_layer_name="conv5_block32_concat", class_index=None):
65
  img_np = np.array(image_pil)
66
  img_resized = cv2.resize(img_np, (224, 224))
 
73
 
74
  with tf.GradientTape() as tape:
75
  last_conv_layer_output, preds = grad_model(input_for_model, training=False)
 
76
  if isinstance(preds, list):
77
  preds = preds[0]
 
78
  if class_index is None:
79
  class_index = tf.argmax(preds[0])
80
  class_channel = preds[:, class_index]
81
 
82
  grads = tape.gradient(class_channel, last_conv_layer_output)
83
 
84
+ # ===== LA CORRECTION FINALE EST ICI : on ne moyenne que sur les axes spatiaux =====
85
+ pooled_grads = tf.reduce_mean(grads, axis=(0, 1))
86
+ # ===================================================================================
87
 
88
+ last_conv_layer_output = last_conv_layer_output[0]
89
  heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis]
90
  heatmap = tf.squeeze(heatmap)
91
  heatmap = tf.maximum(heatmap, 0) / (tf.math.reduce_max(heatmap) + 1e-8)
92
  heatmap = heatmap.numpy()
93
 
94
  heatmap = np.uint8(255 * heatmap)
95
+ # applyColorMap prend une image 1 canal et retourne une image 3 canaux (BGR)
96
  heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
97
 
98
  img_bgr = cv2.cvtColor(img_resized, cv2.COLOR_RGB2BGR)
99
+ # Les deux images ont maintenant la même taille (224, 224) et 3 canaux.
100
  superimposed_img = cv2.addWeighted(img_bgr, 0.6, heatmap, 0.4, 0)
101
 
102
  return cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB)
 
107
  return "Veuillez uploader une image.", None, None
108
  try:
109
  probs = predict_single(image_pil)
 
110
  benign_prob = sum(probs[i] for i, cls in enumerate(CLASS_NAMES) if diagnosis_map[cls] == "Bénin")
111
  malign_prob = sum(probs[i] for i, cls in enumerate(CLASS_NAMES) if diagnosis_map[cls] == "Malin")
112
  global_diag = "Bénin" if benign_prob >= malign_prob else "Malin"
 
129
 
130
  # ---- Gradio UI ----
131
  example_paths = ["exemple1.jpg", "exemple2.jpg", "exemple3.jpg"]
 
132
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
133
  gr.Markdown("# Analyse de lésions cutanées (Ensemble de modèles + Grad-CAM)")
134
  gr.Markdown("Cet outil propose une prédiction de la nature de la lésion (Bénin/Malin) avec explication visuelle.")