Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import torch
|
3 |
+
from torchvision import transforms, models
|
4 |
+
from PIL import Image
|
5 |
+
import torch.nn.functional as F
|
6 |
+
import pandas as pd
|
7 |
+
import pathlib
|
8 |
+
import matplotlib.pyplot as plt
|
9 |
+
|
10 |
+
from torchvision import models
|
11 |
+
import torch.nn as nn
|
12 |
+
|
13 |
+
me = ['Acceuil','Prediction']
|
14 |
+
p = st.sidebar.selectbox('Menu', me)
|
15 |
+
|
16 |
+
# style
|
17 |
+
def load_css(file_path):
|
18 |
+
with open(file=file_path) as f:
|
19 |
+
st.html(f"<style>{f.read()}</style>")
|
20 |
+
|
21 |
+
css_path = pathlib.Path("css_file.css")
|
22 |
+
load_css(css_path)
|
23 |
+
|
24 |
+
@st.cache_resource
|
25 |
+
def charger_modele():
|
26 |
+
try:
|
27 |
+
model = torch.load('Brain_tumor_effmodel.pth', map_location=torch.device('cpu'), weights_only=False) # Charge sur CPU par défaut
|
28 |
+
model.eval() # Mettre le modèle en mode évaluation
|
29 |
+
return model
|
30 |
+
except Exception as e: # Gestion des erreurs
|
31 |
+
st.error(f"Erreur lors du chargement du modèle : {e}") # Affichage de l'erreur dans Streamlit
|
32 |
+
return None # Ou gérer l'erreur comme vous le souhaitez
|
33 |
+
with st.spinner('Chargement du model pytorch..'):
|
34 |
+
modele_charge = charger_modele()
|
35 |
+
|
36 |
+
# L'image doit être comme celles utilisées de l'entraînement du model
|
37 |
+
transform = transforms.Compose([
|
38 |
+
transforms.Resize((224, 224)),
|
39 |
+
transforms.ToTensor(),
|
40 |
+
transforms.Normalize((0.5),0.5)])
|
41 |
+
|
42 |
+
if p == 'Acceuil':
|
43 |
+
st.title('SN DE TRANSFERT LEARNING')
|
44 |
+
st.subheader("Nom & Prenom: Nchourupouo Mohamed")
|
45 |
+
st.subheader("Application de prediction de tumeur cerebrale")
|
46 |
+
c1, c2 = st.columns(2)
|
47 |
+
with c1:
|
48 |
+
st.write("Bienvenue sur cette plateforme innovante qui utilise l'intelligence artificielle pour fournir des prédictions éclairées sur les tumeurs de cerveau.Elle offre une évaluation rapide et précise du risque de malignité. Alors vous souhaitez essayer notre Application ? cliquer sur le bouton prediction dans le sidebar.")
|
49 |
+
|
50 |
+
with c2:
|
51 |
+
st.write("Près pour un test ? Deroulez le menu `Acceuil` ➤ `Prediction` ➤ `Browse files` et Uploader un fichier image comme celui presente ci-dessous")
|
52 |
+
st.image("mri_healthy (1).jpeg", caption="Image chargée", use_container_width=True)
|
53 |
+
|
54 |
+
elif p=='Prediction':
|
55 |
+
st.title('TRANSFERT LEARNING')
|
56 |
+
st.write("Pour pouvoir faire une prediction, veuillez uploader une image en upuyant le bouton `Browse files`.")
|
57 |
+
upload_file = st.sidebar.file_uploader('Choisissez une image',type=['jpg','jpeg','png'])
|
58 |
+
|
59 |
+
if upload_file:
|
60 |
+
image = Image.open(upload_file).convert("RGB")
|
61 |
+
st.image(image, caption="Image chargée", use_container_width=True)
|
62 |
+
st.write("Cliquez sur le bouton `Resultat` pour voir vos resultats, puis sur `probabilites` pour voir quelle probabilite donne le model a la classe predicte.")
|
63 |
+
# Prétraitement de l'image
|
64 |
+
img_tensor = transform(image).unsqueeze(0)
|
65 |
+
|
66 |
+
classes_p = {'HEALTHY': 0, "Brain Tumor":1}
|
67 |
+
|
68 |
+
def output_proba():
|
69 |
+
output = modele_charge(img_tensor)
|
70 |
+
probabilities = F.softmax(output, dim=1)
|
71 |
+
return output, probabilities
|
72 |
+
|
73 |
+
if st.sidebar.checkbox("Resultat"):
|
74 |
+
# Prédiction
|
75 |
+
with torch.no_grad():
|
76 |
+
output,_ =output_proba()
|
77 |
+
predicted_class = torch.argmax(output, dim=1).item()
|
78 |
+
|
79 |
+
for key, value in classes_p.items():
|
80 |
+
if value == predicted_class:
|
81 |
+
if key == "HEALTHY":
|
82 |
+
st.write(f"Je suis heureux de vous annoncer que les résultats sont très encourageants. Il n'y a aucune indication de cancer du cerveau. La prédiction du modèle est la suivante ➤ <strong>{key}</strong>", unsafe_allow_html=True)
|
83 |
+
st.balloons()
|
84 |
+
else:
|
85 |
+
st.write(f"Je suis profondément désolé de devoir vous annoncer que les résultats ne sont pas ceux que nous espérions. la prediction du model est la suivante ➤ <strong>{key}</strong>", unsafe_allow_html=True)
|
86 |
+
|
87 |
+
_,probabilities = output_proba()
|
88 |
+
df = pd.DataFrame({"Classe": classes_p.keys(),"Probabilité": probabilities.tolist()[0]})
|
89 |
+
|
90 |
+
couleurs = ['skyblue', 'lightcoral']
|
91 |
+
|
92 |
+
fig, ax = plt.subplots(figsize=(8, 6)) # Créer une figure et un axe
|
93 |
+
ax.bar(df['Classe'], df['Probabilité'], color=couleurs)
|
94 |
+
|
95 |
+
# Ajouter des étiquettes et un titre
|
96 |
+
ax.set_xlabel('Classe')
|
97 |
+
ax.set_ylabel('Probabilité')
|
98 |
+
ax.set_title('Probabilites de prediction')
|
99 |
+
|
100 |
+
# Personnaliser l'apparence du graphique (facultatif)
|
101 |
+
ax.grid(axis='y', linestyle='--', alpha=0.7) # Ajouter une grille en arrière-plan
|
102 |
+
ax.tick_params(axis='x', rotation=45) # Faire pivoter les étiquettes de l'axe x si elles sont trop longues
|
103 |
+
|
104 |
+
# Afficher le graphique dans Streamlit
|
105 |
+
st.pyplot(fig)
|
106 |
+
print(df.columns)
|
107 |
+
|