Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,96 +1,19 @@
|
|
| 1 |
-
import json
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
#
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
#
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
#
|
| 18 |
-
|
| 19 |
-
|
| 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)
|
|
|
|
| 1 |
+
import json import cv2 import numpy as np import gradio as gr import onnxruntime from PIL import Image from torchvision import transforms import pandas as pd
|
| 2 |
+
# Cargar el modelo ONNX ort_session = onnxruntime.InferenceSession("model_new_new_final.onnx")
|
| 3 |
+
# Abrir archivo JSON with open('dat.json') as f: data = json.load(f)
|
| 4 |
+
keys = list(data)
|
| 5 |
+
# DataFrame de ejemplo simple = pd.DataFrame( { "item": keys, "probability": [0] * len(keys) } )
|
| 6 |
+
def Predict(image): # Preprocesar la imagen img = cv2.resize(image, (100, 100))
|
| 7 |
+
# Convertir el arreglo NumPy de vuelta a una imagen PIL image = Image.fromarray(image) # Preprocesar la imagen img = image.resize((100, 100))
|
| 8 |
+
# Definir transformaciones test_tfms = transforms.Compose([ transforms.Resize((100, 100)), transforms.ToTensor(), transforms.Normalize(mean=[0.7611, 0.5869, 0.5923], std=[0.1266, 0.1487, 0.1619]) ]) # Aplicar transformaciones input_image = test_tfms(img).unsqueeze(0).numpy() # Agregar dimension de lote y convertir a arreglo numpy
|
| 9 |
+
# Preparar tensor de entrada input_name = ort_session.get_inputs()[0].name input_dict = {input_name: input_image}
|
| 10 |
+
# Ejecutar inferencia output = ort_session.run(None, input_dict)
|
| 11 |
+
# Obtener el indice de la clase predicha prediction_idx = np.argmax(output)
|
| 12 |
+
# Recuperar informacion del JSON basada en la clase predicha disease_name = keys[prediction_idx] description = data[disease_name]['description'] symptoms = data[disease_name]['symptoms'] causes = data[disease_name]['causes'] treatment = data[disease_name]['treatment-1']
|
| 13 |
+
# Obtener probabilidades para cada clase y convertirlas a enteros probabilities = output[0] ints_probabilities = probabilities_to_ints(probabilities)
|
| 14 |
+
# Actualizar la probabilidad en el DataFrame simple["probability"] = ints_probabilities[0]
|
| 15 |
+
# Crear grafico de barras para las probabilidades bar_plot = gr.BarPlot( value=simple, x="item", y="probability", y_title="Probabilidad", x_title="Nombre de la Enfermedad", title="Distribucion de Probabilidad", tooltip=["item", "probability"], vertical = False )
|
| 16 |
+
return disease_name, description, symptoms, causes, treatment, bar_plot
|
| 17 |
+
# Funcion para convertir probabilidades a enteros def probabilities_to_ints(probabilities, total_sum=100): # Filtrar los valores negativos positive_values = np.maximum(probabilities, 0) # Encontrar el peso positivo total total_positive_weight = np.sum(positive_values) # Calcular probabilidades escaladas para valores positivos scaled_probabilities = np.zeros_like(probabilities) if total_positive_weight > 0: scaled_probabilities = positive_values / total_positive_weight * total_sum # Redondear las probabilidades escaladas a enteros rounded_probabilities = np.round(scaled_probabilities).astype(int) # Ajustar por errores de redondeo rounding_diff = total_sum - np.sum(rounded_probabilities) if rounding_diff != 0 and np.sum(positive_values) > 0: # Agregar la diferencia de redondeo a la clase con mayor peso positivo max_positive_index = np.argmax(positive_values) flattened_probabilities = rounded_probabilities.flatten() flattened_probabilities[max_positive_index] += rounding_diff rounded_probabilities = np.reshape(flattened_probabilities, rounded_probabilities.shape) return rounded_probabilities
|
| 18 |
+
# Definir la interfaz Gradio demo = gr.Interface(fn=Predict, inputs="image", outputs=[ gr.Textbox(label='Nombre de la Enfermedad', type="text"), gr.Textbox(label='Descripcion', type="text"), gr.Textbox(label='Sintomas', type="text"), gr.Textbox(label='Causas', type="text"), gr.Textbox(label='Tratamiento', type="text"), "bar_plot" ], title="Clasificacion de Enfermedades de la Piel", 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')
|
| 19 |
+
demo.launch(debug=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|