ericjedha commited on
Commit
2641b39
·
verified ·
1 Parent(s): 79ec422

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +171 -13
app.py CHANGED
@@ -100,6 +100,31 @@ os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
100
  os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
101
  tf.config.set_visible_devices([], 'GPU')
102
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  # ---- Configuration ----
104
  CLASS_NAMES = ['akiec', 'bcc', 'bkl', 'df', 'nv', 'vasc', 'mel']
105
  label_to_index = {name: i for i, name in enumerate(CLASS_NAMES)}
@@ -481,6 +506,111 @@ def make_gradcam(image_pil, model, last_conv_layer_name, class_index, progress=N
481
  _update_progress(progress, 100, "❌ Erreur")
482
  return np.array(image_pil)
483
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
  # ---- GESTION ASYNCHRONE / ÉTAT ----
485
  current_image = None
486
  current_predictions = None
@@ -507,7 +637,8 @@ def quick_predict_ui(image_pil):
507
  "", # output_text vide
508
  gr.update(value="", visible=False), # output_warning masqué
509
  empty_fig, # Figure vide au lieu de None
510
- "❌ Erreur: Aucune image fournie."
 
511
  )
512
 
513
  try:
@@ -522,6 +653,10 @@ def quick_predict_ui(image_pil):
522
  # Probabilité de mélanome
523
  mel_idx = CLASS_NAMES.index("mel")
524
  mel_prob = ensemble_probs[mel_idx] * 100
 
 
 
 
525
 
526
  # Description
527
  desc_top = description.get(top_class_name, "")
@@ -568,6 +703,20 @@ def quick_predict_ui(image_pil):
568
  '''
569
  warning_visible = True
570
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
571
  # Création du graphique Plotly
572
  probabilities = [round(ensemble_probs[i] * 100, 2) for i in range(len(CLASS_NAMES))]
573
 
@@ -578,34 +727,33 @@ def quick_predict_ui(image_pil):
578
  go.Bar(
579
  x=CLASS_NAMES,
580
  y=probabilities,
581
- text=[f'{p:.2f}%' for p in probabilities], # Pourcentages avec 2 décimales
582
- textposition='outside', # POURCENTAGES EN DEHORS DES BARRES
583
  marker_color=colors,
584
  hovertemplate='<b>%{x}</b><br>Probabilité: %{y:.2f}%<extra></extra>'
585
  )
586
  ])
587
 
588
  fig.update_layout(
589
- #title="Probabilités par classe",
590
  xaxis_title="Classes",
591
  yaxis_title="Probabilité (%)",
592
- yaxis=dict(range=[0, max(probabilities) * 1.15]), # Ajuster la plage pour les labels externes
593
  height=450,
594
  template="plotly_white",
595
  showlegend=False,
596
  font=dict(size=12),
597
- margin=dict(l=50, r=50, t=70, b=100) # Marge du bas augmentée pour les labels x
598
  )
599
 
600
- # Rotation des labels x pour une meilleure lisibilité
601
  fig.update_xaxes(tickangle=45)
602
 
603
  return (
604
  global_diag_html,
605
  output_text_html,
606
  gr.update(value=warning_html, visible=warning_visible),
607
- fig, # Retourner la figure Plotly
608
- "✅ Analyse terminée."
 
609
  )
610
 
611
  except Exception as e:
@@ -618,6 +766,13 @@ def quick_predict_ui(image_pil):
618
  showlegend=False
619
  )
620
 
 
 
 
 
 
 
 
621
  return (
622
  f'<div class="diagnostic-global"><h2>Erreur: {str(e)}</h2></div>',
623
  "",
@@ -626,10 +781,11 @@ def quick_predict_ui(image_pil):
626
  ❌ Une erreur est survenue : {str(e)}
627
  </div>
628
  ''', visible=True),
629
- error_fig, # Figure d'erreur au lieu de None
630
- f"❌ Erreur: {str(e)}"
 
631
  )
632
-
633
  def generate_gradcam_ui(progress=gr.Progress()):
634
  global current_image, current_predictions
635
  if current_image is None or current_predictions is None:
@@ -732,6 +888,8 @@ with gr.Blocks(theme=theme, title="Analyse de lésions", css=css) as demo:
732
 
733
  # Configuration correcte du BarPlot
734
  output_plot = gr.Plot(label="Probabilités par classe")
 
 
735
 
736
  gr.Markdown(f"Ensemble de modèles utilisés : {', '.join(models_status) if models_status else 'AUCUN'}")
737
  gr.HTML(value="""
@@ -747,7 +905,7 @@ with gr.Blocks(theme=theme, title="Analyse de lésions", css=css) as demo:
747
  quick_btn.click(
748
  fn=quick_predict_ui,
749
  inputs=input_image,
750
- outputs=[output_label, output_text, output_warning, output_plot, output_status]
751
  )
752
 
753
  gradcam_btn.click(
 
100
  os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
101
  tf.config.set_visible_devices([], 'GPU')
102
 
103
+
104
+ # =============================================================================
105
+ # 1. IMPORTS ET CHARGEMENT DU MODÈLE (à ajouter en début de fichier)
106
+ # =============================================================================
107
+
108
+ from transformers import pipeline
109
+ import torch
110
+
111
+ # Chargement du modèle Microsoft BiomedBERT
112
+ med_nlp = None
113
+ try:
114
+ print("📥 Chargement du modèle médical Microsoft BiomedBERT...")
115
+ med_nlp = pipeline(
116
+ "text-classification",
117
+ model="microsoft/BiomedNLP-BiomedBERT-base-uncased-abstract",
118
+ framework="pt",
119
+ device=0 if torch.cuda.is_available() else -1 # GPU si disponible
120
+ )
121
+ print("✅ Microsoft BiomedBERT chargé avec succès")
122
+ except Exception as e:
123
+ print(f"❌ Erreur lors du chargement de Microsoft BiomedBERT: {e}")
124
+ med_nlp = None
125
+
126
+
127
+
128
  # ---- Configuration ----
129
  CLASS_NAMES = ['akiec', 'bcc', 'bkl', 'df', 'nv', 'vasc', 'mel']
130
  label_to_index = {name: i for i, name in enumerate(CLASS_NAMES)}
 
506
  _update_progress(progress, 100, "❌ Erreur")
507
  return np.array(image_pil)
508
 
509
+ # =============================================================================
510
+ # 2. FONCTION D'ANALYSE MÉDICALE (à ajouter après vos fonctions existantes)
511
+ # =============================================================================
512
+
513
+ def get_medical_analysis(top_class_name, confidence, mel_prob):
514
+ """
515
+ Analyse médicale utilisant Microsoft BiomedBERT
516
+ """
517
+ global med_nlp
518
+
519
+ if med_nlp is None:
520
+ return {
521
+ "status": "error",
522
+ "analysis": "Modèle médical non disponible",
523
+ "recommendation": "Consultez un dermatologue pour un diagnostic professionnel."
524
+ }
525
+
526
+ try:
527
+ # Construction du texte médical basé sur la prédiction
528
+ medical_context = f"""
529
+ Dermatology diagnosis: {top_class_name} detected with {confidence:.1f}% confidence.
530
+ Clinical findings suggest {CLASS_NAMES_FULL.get(top_class_name, top_class_name)}.
531
+ Melanoma probability: {mel_prob:.1f}%.
532
+ Patient requires medical evaluation for skin lesion assessment.
533
+ """
534
+
535
+ # Analyse avec BiomedBERT
536
+ result = med_nlp(medical_context)
537
+
538
+ # Interprétation des résultats
539
+ if result and len(result) > 0:
540
+ score = result[0].get('score', 0)
541
+ label = result[0].get('label', 'UNKNOWN')
542
+
543
+ # Génération de recommandations basées sur l'analyse
544
+ if score > 0.7:
545
+ recommendation_level = "urgent"
546
+ elif score > 0.5:
547
+ recommendation_level = "modéré"
548
+ else:
549
+ recommendation_level = "surveillance"
550
+
551
+ return {
552
+ "status": "success",
553
+ "biomed_score": score,
554
+ "biomed_label": label,
555
+ "recommendation_level": recommendation_level,
556
+ "analysis": f"Analyse BiomedBERT: {label} (score: {score:.3f})",
557
+ "recommendation": get_medical_recommendation(top_class_name, mel_prob, recommendation_level)
558
+ }
559
+ else:
560
+ return {
561
+ "status": "error",
562
+ "analysis": "Analyse BiomedBERT échouée",
563
+ "recommendation": "Consultez un dermatologue pour un diagnostic professionnel."
564
+ }
565
+
566
+ except Exception as e:
567
+ print(f"Erreur analyse BiomedBERT: {e}")
568
+ return {
569
+ "status": "error",
570
+ "analysis": f"Erreur technique: {str(e)}",
571
+ "recommendation": "Consultez un dermatologue pour un diagnostic professionnel."
572
+ }
573
+
574
+ def get_medical_recommendation(class_name, mel_prob, level):
575
+ """
576
+ Génère des recommandations médicales personnalisées
577
+ """
578
+ base_recommendations = {
579
+ "mel": "🚨 URGENT: Consultation immédiate chez un dermatologue recommandée.",
580
+ "bcc": "⚠️ Consultation dermatologique recommandée sous 2-4 semaines.",
581
+ "akiec": "📋 Surveillance dermatologique régulière conseillée.",
582
+ "bkl": "✅ Lésion généralement bénigne, surveillance de routine.",
583
+ "df": "📋 Suivi dermatologique pour confirmation diagnostique.",
584
+ "nv": "✅ Grain de beauté typique, surveillance habituelle.",
585
+ "vasc": "📋 Évaluation dermatologique pour suivi approprié."
586
+ }
587
+
588
+ base_rec = base_recommendations.get(class_name, "📋 Consultation dermatologique recommandée.")
589
+
590
+ if mel_prob > 10:
591
+ return f"{base_rec} ⚠️ Attention: Risque mélanome détecté ({mel_prob:.1f}%)."
592
+ elif level == "urgent":
593
+ return f"🚨 {base_rec} Analyse BiomedBERT indique une attention médicale prioritaire."
594
+ elif level == "modéré":
595
+ return f"⚠️ {base_rec} Surveillance médicale recommandée."
596
+ else:
597
+ return base_rec
598
+
599
+ # Dictionnaire des noms complets (à ajouter si pas déjà présent)
600
+ CLASS_NAMES_FULL = {
601
+ "mel": "Melanoma",
602
+ "bcc": "Basal Cell Carcinoma",
603
+ "akiec": "Actinic Keratosis",
604
+ "bkl": "Benign Keratosis",
605
+ "df": "Dermatofibroma",
606
+ "nv": "Melanocytic Nevus",
607
+ "vasc": "Vascular Lesion"
608
+ }
609
+
610
+ # --- Fin Bert Doctor
611
+
612
+
613
+
614
  # ---- GESTION ASYNCHRONE / ÉTAT ----
615
  current_image = None
616
  current_predictions = None
 
637
  "", # output_text vide
638
  gr.update(value="", visible=False), # output_warning masqué
639
  empty_fig, # Figure vide au lieu de None
640
+ "❌ Erreur: Aucune image fournie.",
641
+ "" # Nouveau output pour BiomedBERT
642
  )
643
 
644
  try:
 
653
  # Probabilité de mélanome
654
  mel_idx = CLASS_NAMES.index("mel")
655
  mel_prob = ensemble_probs[mel_idx] * 100
656
+ confidence = ensemble_probs[top_class_idx] * 100
657
+
658
+ # NOUVELLE: Analyse médicale avec BiomedBERT
659
+ medical_analysis = get_medical_analysis(top_class_name, confidence, mel_prob)
660
 
661
  # Description
662
  desc_top = description.get(top_class_name, "")
 
703
  '''
704
  warning_visible = True
705
 
706
+ # NOUVEAU: HTML pour l'analyse médicale BiomedBERT
707
+ biomed_html = f'''
708
+ <div class="medical-analysis" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 15px; border-radius: 10px; margin-top: 10px;">
709
+ <h3 style="margin: 0 0 10px 0; display: flex; align-items: center;">
710
+ 🧬 Analyse Médicale BiomedBERT
711
+ </h3>
712
+ <div style="background: rgba(255,255,255,0.1); padding: 10px; border-radius: 5px;">
713
+ <p><strong>Statut:</strong> {medical_analysis['status']}</p>
714
+ <p><strong>Analyse:</strong> {medical_analysis['analysis']}</p>
715
+ <p><strong>Recommandation:</strong> {medical_analysis['recommendation']}</p>
716
+ </div>
717
+ </div>
718
+ '''
719
+
720
  # Création du graphique Plotly
721
  probabilities = [round(ensemble_probs[i] * 100, 2) for i in range(len(CLASS_NAMES))]
722
 
 
727
  go.Bar(
728
  x=CLASS_NAMES,
729
  y=probabilities,
730
+ text=[f'{p:.2f}%' for p in probabilities],
731
+ textposition='outside',
732
  marker_color=colors,
733
  hovertemplate='<b>%{x}</b><br>Probabilité: %{y:.2f}%<extra></extra>'
734
  )
735
  ])
736
 
737
  fig.update_layout(
 
738
  xaxis_title="Classes",
739
  yaxis_title="Probabilité (%)",
740
+ yaxis=dict(range=[0, max(probabilities) * 1.15]),
741
  height=450,
742
  template="plotly_white",
743
  showlegend=False,
744
  font=dict(size=12),
745
+ margin=dict(l=50, r=50, t=70, b=100)
746
  )
747
 
 
748
  fig.update_xaxes(tickangle=45)
749
 
750
  return (
751
  global_diag_html,
752
  output_text_html,
753
  gr.update(value=warning_html, visible=warning_visible),
754
+ fig,
755
+ "✅ Analyse terminée.",
756
+ biomed_html # NOUVEAU: Retour de l'analyse BiomedBERT
757
  )
758
 
759
  except Exception as e:
 
766
  showlegend=False
767
  )
768
 
769
+ error_biomed_html = f'''
770
+ <div class="medical-analysis" style="background: #ffebee; color: #d32f2f; padding: 15px; border-radius: 10px; border: 1px solid #ef9a9a;">
771
+ <h3>🧬 Analyse Médicale BiomedBERT</h3>
772
+ <p>❌ Erreur lors de l'analyse médicale: {str(e)}</p>
773
+ </div>
774
+ '''
775
+
776
  return (
777
  f'<div class="diagnostic-global"><h2>Erreur: {str(e)}</h2></div>',
778
  "",
 
781
  ❌ Une erreur est survenue : {str(e)}
782
  </div>
783
  ''', visible=True),
784
+ error_fig,
785
+ f"❌ Erreur: {str(e)}",
786
+ error_biomed_html # NOUVEAU: Erreur BiomedBERT
787
  )
788
+
789
  def generate_gradcam_ui(progress=gr.Progress()):
790
  global current_image, current_predictions
791
  if current_image is None or current_predictions is None:
 
888
 
889
  # Configuration correcte du BarPlot
890
  output_plot = gr.Plot(label="Probabilités par classe")
891
+ # NOUVEAU: Output pour l'analyse BiomedBERT
892
+ output_medical = gr.HTML(label="🧬 Analyse Médicale Avancée")
893
 
894
  gr.Markdown(f"Ensemble de modèles utilisés : {', '.join(models_status) if models_status else 'AUCUN'}")
895
  gr.HTML(value="""
 
905
  quick_btn.click(
906
  fn=quick_predict_ui,
907
  inputs=input_image,
908
+ outputs=[output_label, output_text, output_warning, output_plot, output_status, output_medical]
909
  )
910
 
911
  gradcam_btn.click(