Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
| 1 |
import json
|
| 2 |
-
import cv2
|
| 3 |
import numpy as np
|
| 4 |
import gradio as gr
|
| 5 |
import onnxruntime
|
|
@@ -7,120 +6,91 @@ from PIL import Image
|
|
| 7 |
from torchvision import transforms
|
| 8 |
import pandas as pd
|
| 9 |
|
| 10 |
-
#
|
| 11 |
-
ort_session = onnxruntime.InferenceSession("model_new_new_final.onnx")
|
| 12 |
|
| 13 |
-
#
|
| 14 |
-
with open(
|
| 15 |
data = json.load(f)
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
)
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
x="item",
|
| 75 |
y="probability",
|
| 76 |
y_title="Probabilidad",
|
| 77 |
x_title="Nombre de la Enfermedad",
|
| 78 |
title="Distribucion de Probabilidad",
|
| 79 |
tooltip=["item", "probability"],
|
| 80 |
-
vertical
|
|
|
|
| 81 |
)
|
|
|
|
|
|
|
| 82 |
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
# Funcion para convertir probabilidades a enteros
|
| 86 |
-
def probabilities_to_ints(probabilities, total_sum=100):
|
| 87 |
-
# Filtrar los valores negativos
|
| 88 |
-
positive_values = np.maximum(probabilities, 0)
|
| 89 |
-
|
| 90 |
-
# Encontrar el peso positivo total
|
| 91 |
-
total_positive_weight = np.sum(positive_values)
|
| 92 |
-
|
| 93 |
-
# Calcular probabilidades escaladas para valores positivos
|
| 94 |
-
scaled_probabilities = np.zeros_like(probabilities)
|
| 95 |
-
if total_positive_weight > 0:
|
| 96 |
-
scaled_probabilities = positive_values / total_positive_weight * total_sum
|
| 97 |
-
|
| 98 |
-
# Redondear las probabilidades escaladas a enteros
|
| 99 |
-
rounded_probabilities = np.round(scaled_probabilities).astype(int)
|
| 100 |
-
|
| 101 |
-
# Ajustar por errores de redondeo
|
| 102 |
-
rounding_diff = total_sum - np.sum(rounded_probabilities)
|
| 103 |
-
if rounding_diff != 0 and np.sum(positive_values) > 0:
|
| 104 |
-
# Agregar la diferencia de redondeo a la clase con mayor peso positivo
|
| 105 |
-
max_positive_index = np.argmax(positive_values)
|
| 106 |
-
flattened_probabilities = rounded_probabilities.flatten()
|
| 107 |
-
flattened_probabilities[max_positive_index] += rounding_diff
|
| 108 |
-
rounded_probabilities = np.reshape(flattened_probabilities, rounded_probabilities.shape)
|
| 109 |
-
|
| 110 |
-
return rounded_probabilities
|
| 111 |
-
|
| 112 |
-
# Definir la interfaz Gradio
|
| 113 |
-
demo = gr.Interface(fn=Predict,
|
| 114 |
-
inputs="image",
|
| 115 |
-
outputs=[
|
| 116 |
-
gr.Textbox(label='Nombre de la Enfermedad', type="text"),
|
| 117 |
-
gr.Textbox(label='Descripcion', type="text"),
|
| 118 |
-
gr.Textbox(label='Sintomas', type="text"),
|
| 119 |
-
gr.Textbox(label='Causas', type="text"),
|
| 120 |
-
gr.Textbox(label='Tratamiento', type="text"),
|
| 121 |
-
"bar_plot"
|
| 122 |
-
],
|
| 123 |
-
title="Clasificacion de Enfermedades de la Piel",
|
| 124 |
-
description = 'Este espacio se ha desarrollado como parte de una tesis para la Universidad Central de Venezuela con el proposito de realizar diagnosticos precisos sobre una variedad de lesiones cutaneas. Su objetivo es ayudar en la identificacion temprana y precisa de condiciones dermatologicas, incluyendo:\n\n1)Queratosis Actinica \n\n2)Carcinoma Basocelular \n\n3)Dermatofibroma \n\n4)Melanoma \n\n5)Nevus \n\n6)Queratosis Pigmentada Benigna \n\n7)Queratosis Seborreica \n\n8)Carcinoma de Celulas Escamosas \n\n9)Lesion Vascular \n\n')
|
| 125 |
-
|
| 126 |
-
demo.launch(debug=True)
|
|
|
|
| 1 |
import json
|
|
|
|
| 2 |
import numpy as np
|
| 3 |
import gradio as gr
|
| 4 |
import onnxruntime
|
|
|
|
| 6 |
from torchvision import transforms
|
| 7 |
import pandas as pd
|
| 8 |
|
| 9 |
+
# Load model
|
| 10 |
+
ort_session = onnxruntime.InferenceSession("model_new_new_final.onnx", providers=["CPUExecutionProvider"])
|
| 11 |
|
| 12 |
+
# Load classes + metadata
|
| 13 |
+
with open("dat.json", "r", encoding="utf-8") as f:
|
| 14 |
data = json.load(f)
|
| 15 |
+
keys = list(data.keys())
|
| 16 |
+
|
| 17 |
+
# Preprocessing
|
| 18 |
+
test_tfms = transforms.Compose([
|
| 19 |
+
transforms.Resize((100, 100)),
|
| 20 |
+
transforms.ToTensor(),
|
| 21 |
+
transforms.Normalize(mean=[0.7611, 0.5869, 0.5923], std=[0.1266, 0.1487, 0.1619]),
|
| 22 |
+
])
|
| 23 |
+
|
| 24 |
+
def softmax(x: np.ndarray) -> np.ndarray:
|
| 25 |
+
x = x - np.max(x)
|
| 26 |
+
e = np.exp(x)
|
| 27 |
+
return e / e.sum()
|
| 28 |
+
|
| 29 |
+
def probabilities_to_ints(probabilities: np.ndarray, total_sum: int = 100) -> np.ndarray:
|
| 30 |
+
probs = np.asarray(probabilities, dtype=np.float64)
|
| 31 |
+
if probs.ndim == 2 and probs.shape[0] == 1:
|
| 32 |
+
probs = probs
|
| 33 |
+
elif probs.ndim != 1:
|
| 34 |
+
raise ValueError(f"Unexpected probabilities shape: {probs.shape}")
|
| 35 |
+
positive = np.maximum(probs, 0)
|
| 36 |
+
s = positive.sum()
|
| 37 |
+
if s == 0:
|
| 38 |
+
return np.zeros_like(positive, dtype=int)
|
| 39 |
+
scaled = positive / s * total_sum
|
| 40 |
+
rounded = np.rint(scaled).astype(int)
|
| 41 |
+
diff = total_sum - int(rounded.sum())
|
| 42 |
+
if diff != 0:
|
| 43 |
+
order = np.argsort(-positive)
|
| 44 |
+
for i in range(abs(diff)):
|
| 45 |
+
idx = order[i % len(order)]
|
| 46 |
+
rounded[idx] += 1 if diff > 0 else -1
|
| 47 |
+
return rounded
|
| 48 |
+
|
| 49 |
+
def Predict(image: Image.Image):
|
| 50 |
+
if not isinstance(image, Image.Image):
|
| 51 |
+
image = Image.fromarray(image)
|
| 52 |
+
tensor = test_tfms(image).unsqueeze(0).numpy().astype(np.float32)
|
| 53 |
+
input_name = ort_session.get_inputs().name
|
| 54 |
+
out = ort_session.run(None, {input_name: tensor})
|
| 55 |
+
logits = out
|
| 56 |
+
if logits.ndim == 2 and logits.shape == 1:
|
| 57 |
+
logits = logits
|
| 58 |
+
elif logits.ndim != 1:
|
| 59 |
+
raise ValueError(f"Unexpected model output shape: {logits.shape}")
|
| 60 |
+
pred_idx = int(np.argmax(logits))
|
| 61 |
+
probs = softmax(logits)
|
| 62 |
+
ints = probabilities_to_ints(probs).astype(int)
|
| 63 |
+
df = pd.DataFrame({"item": [str(k) for k in keys], "probability": [int(x) for x in ints.tolist()]})
|
| 64 |
+
disease_name = keys[pred_idx]
|
| 65 |
+
meta = data.get(disease_name, {})
|
| 66 |
+
description = meta.get("description", "N/A")
|
| 67 |
+
symptoms = meta.get("symptoms", "N/A")
|
| 68 |
+
causes = meta.get("causes", "N/A")
|
| 69 |
+
treatment = meta.get("treatment-1", meta.get("treatment", "N/A"))
|
| 70 |
+
return disease_name, description, symptoms, causes, treatment, df
|
| 71 |
+
|
| 72 |
+
with gr.Blocks(title="Clasificacion de Enfermedades de la Piel") as demo:
|
| 73 |
+
gr.Markdown(
|
| 74 |
+
"Este espacio se ha desarrollado..."
|
| 75 |
+
)
|
| 76 |
+
inp = gr.Image(type="pil", label="Imagen de la piel")
|
| 77 |
+
out_name = gr.Textbox(label="Nombre de la Enfermedad")
|
| 78 |
+
out_desc = gr.Textbox(label="Descripcion")
|
| 79 |
+
out_symp = gr.Textbox(label="Sintomas")
|
| 80 |
+
out_causes = gr.Textbox(label="Causas")
|
| 81 |
+
out_treat = gr.Textbox(label="Tratamiento")
|
| 82 |
+
bar = gr.BarPlot(
|
| 83 |
x="item",
|
| 84 |
y="probability",
|
| 85 |
y_title="Probabilidad",
|
| 86 |
x_title="Nombre de la Enfermedad",
|
| 87 |
title="Distribucion de Probabilidad",
|
| 88 |
tooltip=["item", "probability"],
|
| 89 |
+
vertical=False,
|
| 90 |
+
label="Probabilidades"
|
| 91 |
)
|
| 92 |
+
btn = gr.Button("Predecir")
|
| 93 |
+
btn.click(Predict, inputs=inp, outputs=[out_name, out_desc, out_symp, out_causes, out_treat, bar])
|
| 94 |
|
| 95 |
+
if __name__ == "__main__":
|
| 96 |
+
demo.launch(debug=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|