Update app.py
Browse files
app.py
CHANGED
@@ -160,6 +160,68 @@ def find_last_dense_layer(model):
|
|
160 |
raise ValueError("Aucune couche Dense trouvée dans le modèle.")
|
161 |
|
162 |
# ---- GRAD-CAM ----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
def generate_gradcam_ui():
|
164 |
global current_image, current_predictions
|
165 |
if current_image is None or current_predictions is None:
|
@@ -197,7 +259,7 @@ def generate_gradcam_ui():
|
|
197 |
print(f"❌ Erreur dans generate_gradcam_ui: {e}")
|
198 |
import traceback; traceback.print_exc()
|
199 |
yield None, 0
|
200 |
-
|
201 |
# ---- GESTION ASYNCHRONE / ÉTAT ----
|
202 |
current_image = None
|
203 |
current_predictions = None
|
|
|
160 |
raise ValueError("Aucune couche Dense trouvée dans le modèle.")
|
161 |
|
162 |
# ---- GRAD-CAM ----
|
163 |
+
# ---- GESTION ASYNCHRONE / ÉTAT ----
|
164 |
+
current_image = None
|
165 |
+
current_predictions = None
|
166 |
+
|
167 |
+
# ---- Fonctions pour l'UI Gradio ----
|
168 |
+
def quick_predict_ui(image_pil):
|
169 |
+
global current_image, current_predictions
|
170 |
+
if image_pil is None:
|
171 |
+
return "Veuillez uploader une image.", None, None
|
172 |
+
try:
|
173 |
+
current_image = image_pil
|
174 |
+
all_preds = predict_single(image_pil)
|
175 |
+
current_predictions = all_preds
|
176 |
+
ensemble_probs = all_preds["ensemble"]
|
177 |
+
|
178 |
+
# Débogage : Afficher les probabilités brutes
|
179 |
+
print("Probabilités brutes (ensemble):", ensemble_probs)
|
180 |
+
print("Somme des probabilités brutes:", ensemble_probs.sum())
|
181 |
+
|
182 |
+
# Vérification et normalisation explicite si nécessaire
|
183 |
+
if ensemble_probs.sum() > 1.0: # Si les probabilités dépassent 1, renormaliser
|
184 |
+
ensemble_probs = _renorm_safe(ensemble_probs)
|
185 |
+
print("Probabilités renormées:", ensemble_probs)
|
186 |
+
print("Somme après renorm:", ensemble_probs.sum())
|
187 |
+
|
188 |
+
top_class_idx = int(np.argmax(ensemble_probs))
|
189 |
+
top_class_name = CLASS_NAMES[top_class_idx]
|
190 |
+
global_diag = diagnosis_map[top_class_name]
|
191 |
+
|
192 |
+
# Conversion en pourcentages pour le DataFrame
|
193 |
+
confidences = {CLASS_NAMES[i]: float(ensemble_probs[i] * 100) for i in range(len(CLASS_NAMES))} # En pourcentages
|
194 |
+
df = pd.DataFrame.from_dict(confidences, orient='index', columns=['Probabilité']).reset_index().rename(columns={'index': 'Classe'})
|
195 |
+
df = df.sort_values(by='Probabilité', ascending=False)
|
196 |
+
|
197 |
+
# Ajout d'une colonne pour les étiquettes avec pourcentages
|
198 |
+
df['Pourcentage'] = df['Probabilité'].apply(lambda x: f"{x:.1f}%")
|
199 |
+
|
200 |
+
# Génération du graphique avec texte dynamique
|
201 |
+
fig = px.bar(df,
|
202 |
+
x="Classe",
|
203 |
+
y="Probabilité",
|
204 |
+
color="Probabilité",
|
205 |
+
color_continuous_scale=px.colors.sequential.Viridis,
|
206 |
+
title="Probabilités par classe",
|
207 |
+
text="Pourcentage") # Utilise la colonne Pourcentage pour les étiquettes
|
208 |
+
|
209 |
+
# Définir textposition comme une liste personnalisée
|
210 |
+
text_positions = []
|
211 |
+
for val in df['Probabilité']:
|
212 |
+
if val <= 10: # Si la probabilité est ≤ 10%, texte à l'extérieur
|
213 |
+
text_positions.append("outside")
|
214 |
+
else: # Sinon, texte à l'intérieur
|
215 |
+
text_positions.append("inside")
|
216 |
+
fig.update_traces(textposition=text_positions) # Appliquer les positions personnalisées
|
217 |
+
|
218 |
+
fig.update_layout(xaxis_title="", yaxis_title="Probabilité (%)", height=400)
|
219 |
+
|
220 |
+
return f"{global_diag} ({top_class_name.upper()})", fig, None
|
221 |
+
except Exception as e:
|
222 |
+
print(f"Erreur dans quick_predict_ui: {e}")
|
223 |
+
return f"Erreur: {e}", None, None
|
224 |
+
|
225 |
def generate_gradcam_ui():
|
226 |
global current_image, current_predictions
|
227 |
if current_image is None or current_predictions is None:
|
|
|
259 |
print(f"❌ Erreur dans generate_gradcam_ui: {e}")
|
260 |
import traceback; traceback.print_exc()
|
261 |
yield None, 0
|
262 |
+
|
263 |
# ---- GESTION ASYNCHRONE / ÉTAT ----
|
264 |
current_image = None
|
265 |
current_predictions = None
|