Spaces:
Sleeping
Sleeping
Upload 5 files
Browse files- Dockerfile +22 -15
- app.py +85 -45
- modelo_cnn_tbc_mejorado.h5 +3 -0
- modelo_cnn_tbc_mejorado.json +0 -0
- requirements.txt +7 -6
Dockerfile
CHANGED
|
@@ -1,16 +1,23 @@
|
|
| 1 |
-
#
|
| 2 |
-
|
| 3 |
-
#
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
#
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
RUN
|
| 14 |
-
|
| 15 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
|
|
|
|
| 1 |
+
# Dockerfile
|
| 2 |
+
|
| 3 |
+
# Usar una imagen base oficial de Python.
|
| 4 |
+
FROM python:3.9-slim
|
| 5 |
+
|
| 6 |
+
# Establecer el directorio de trabajo dentro del contenedor
|
| 7 |
+
WORKDIR /app
|
| 8 |
+
|
| 9 |
+
# Copiar el archivo de requerimientos primero para aprovechar el cache de Docker.
|
| 10 |
+
COPY requirements.txt .
|
| 11 |
+
|
| 12 |
+
# Instalar las dependencias de Python
|
| 13 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
| 14 |
+
|
| 15 |
+
# Copiar el resto de los archivos de la aplicaci贸n al directorio de trabajo.
|
| 16 |
+
# Esto incluye app.py y tu modelo .h5
|
| 17 |
+
COPY . .
|
| 18 |
+
|
| 19 |
+
# Exponer el puerto en el que se ejecutar谩 la aplicaci贸n (7860 para Hugging Face).
|
| 20 |
+
EXPOSE 7860
|
| 21 |
+
|
| 22 |
+
# El comando para iniciar la aplicaci贸n cuando el contenedor se ejecute.
|
| 23 |
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
|
app.py
CHANGED
|
@@ -1,45 +1,85 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
import
|
| 4 |
-
|
| 5 |
-
from
|
| 6 |
-
from
|
| 7 |
-
from
|
| 8 |
-
from
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# app.py
|
| 2 |
+
|
| 3 |
+
import io
|
| 4 |
+
import numpy as np
|
| 5 |
+
from PIL import Image
|
| 6 |
+
from fastapi import FastAPI, File, UploadFile
|
| 7 |
+
from fastapi.responses import JSONResponse
|
| 8 |
+
from tensorflow.keras.models import load_model
|
| 9 |
+
|
| 10 |
+
# Inicializar la aplicaci贸n FastAPI
|
| 11 |
+
app = FastAPI(
|
| 12 |
+
title="API de Clasificaci贸n de TBC (Mejorado)",
|
| 13 |
+
description="Una API para clasificar radiograf铆as de t贸rax como 'normal' o 'tbc' usando un modelo CNN con Transfer Learning (MobileNetV2).",
|
| 14 |
+
version="2.0"
|
| 15 |
+
)
|
| 16 |
+
|
| 17 |
+
# --- Carga del Modelo ---
|
| 18 |
+
# Cargar el modelo .h5 mejorado al iniciar la aplicaci贸n.
|
| 19 |
+
try:
|
| 20 |
+
# Aseg煤rate de que el nombre del archivo coincida con el que guardaste
|
| 21 |
+
model = load_model('modelo_cnn_tbc_mejorado.h5')
|
| 22 |
+
print("Modelo mejorado cargado exitosamente.")
|
| 23 |
+
except Exception as e:
|
| 24 |
+
print(f"Error al cargar el modelo: {e}")
|
| 25 |
+
model = None
|
| 26 |
+
|
| 27 |
+
# Definir las constantes del nuevo modelo
|
| 28 |
+
IMG_HEIGHT = 224 # <-- 隆CAMBIO IMPORTANTE!
|
| 29 |
+
IMG_WIDTH = 224 # <-- 隆CAMBIO IMPORTANTE!
|
| 30 |
+
CLASS_NAMES = ["normal", "tbc"]
|
| 31 |
+
|
| 32 |
+
# --- Endpoints de la API ---
|
| 33 |
+
|
| 34 |
+
@app.get("/")
|
| 35 |
+
def read_root():
|
| 36 |
+
"""Endpoint ra铆z para verificar que la API est谩 funcionando."""
|
| 37 |
+
return {"message": "Bienvenido a la API de Clasificaci贸n de TBC v2.0. Usa el endpoint /predict/."}
|
| 38 |
+
|
| 39 |
+
@app.post("/predict/")
|
| 40 |
+
async def predict(file: UploadFile = File(...)):
|
| 41 |
+
"""
|
| 42 |
+
Endpoint para predecir si una radiograf铆a es 'normal' o 'tbc'.
|
| 43 |
+
- Acepta un archivo de imagen (JPG, PNG, etc.).
|
| 44 |
+
- Devuelve la clase predicha y la confianza de la predicci贸n.
|
| 45 |
+
"""
|
| 46 |
+
if not model:
|
| 47 |
+
return JSONResponse(status_code=500, content={"error": "El modelo no est谩 cargado. Revisa los logs del servidor."})
|
| 48 |
+
|
| 49 |
+
# 1. Leer el contenido del archivo subido en memoria
|
| 50 |
+
contents = await file.read()
|
| 51 |
+
|
| 52 |
+
# 2. Convertir los bytes en una imagen PIL
|
| 53 |
+
try:
|
| 54 |
+
image = Image.open(io.BytesIO(contents)).convert('RGB')
|
| 55 |
+
except Exception as e:
|
| 56 |
+
return JSONResponse(status_code=400, content={"error": f"Archivo inv谩lido. No se pudo procesar la imagen: {e}"})
|
| 57 |
+
|
| 58 |
+
# 3. Preprocesar la imagen para que coincida con la entrada del modelo
|
| 59 |
+
# Redimensionar la imagen al tama帽o esperado por MobileNetV2
|
| 60 |
+
image = image.resize((IMG_WIDTH, IMG_HEIGHT))
|
| 61 |
+
# Convertir la imagen a un array de numpy
|
| 62 |
+
img_array = np.array(image)
|
| 63 |
+
# Normalizar los valores de los p铆xeles (de 0-255 a 0-1)
|
| 64 |
+
img_array = img_array / 255.0
|
| 65 |
+
# A帽adir una dimensi贸n de batch (el modelo espera una forma de [1, 224, 224, 3])
|
| 66 |
+
image_batch = np.expand_dims(img_array, axis=0)
|
| 67 |
+
|
| 68 |
+
# 4. Realizar la predicci贸n
|
| 69 |
+
prediction = model.predict(image_batch)
|
| 70 |
+
score = prediction[0][0]
|
| 71 |
+
|
| 72 |
+
# 5. Interpretar el resultado
|
| 73 |
+
if score > 0.5:
|
| 74 |
+
predicted_class = CLASS_NAMES[1] # 'tbc'
|
| 75 |
+
confidence = score
|
| 76 |
+
else:
|
| 77 |
+
predicted_class = CLASS_NAMES[0] # 'normal'
|
| 78 |
+
confidence = 1 - score
|
| 79 |
+
|
| 80 |
+
# 6. Devolver el resultado en formato JSON
|
| 81 |
+
return {
|
| 82 |
+
"filename": file.filename,
|
| 83 |
+
"prediction": predicted_class,
|
| 84 |
+
"confidence": float(confidence)
|
| 85 |
+
}
|
modelo_cnn_tbc_mejorado.h5
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2f22b5f0b0e236b20584eb2156368d5e8a29276ab2221a025887fae55f0f0c59
|
| 3 |
+
size 11540560
|
modelo_cnn_tbc_mejorado.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
requirements.txt
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
|
|
|
|
|
| 1 |
+
# requirements.txt
|
| 2 |
+
fastapi
|
| 3 |
+
uvicorn
|
| 4 |
+
tensorflow-cpu
|
| 5 |
+
numpy
|
| 6 |
+
pillow
|
| 7 |
+
python-multipart
|