Calamar49 commited on
Commit
7578b2b
·
1 Parent(s): 1b3e54a
Files changed (3) hide show
  1. Dockerfile +7 -0
  2. README.md +3 -5
  3. app.py +21 -15
Dockerfile ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ FROM huggingface/transformers-pytorch-gpu
2
+ WORKDIR /code
3
+ COPY ./requirements.txt /code/requirements.txt
4
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
5
+ COPY . /code
6
+ EXPOSE 7860
7
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,9 +1,7 @@
1
  ---
2
  title: Orchid Classifier
3
  emoji: 🌸
4
- colorFrom: green
5
- colorTo: purple
6
- sdk: gradio
7
- sdk_version: 4.31.0 # Usar una versión reciente de Gradio
8
- license: mit
9
  ---
 
1
  ---
2
  title: Orchid Classifier
3
  emoji: 🌸
4
+ sdk: docker
5
+ app_file: app.py
6
+ app_port: 7860
 
 
7
  ---
app.py CHANGED
@@ -1,64 +1,70 @@
1
- # app.py (Versión Corregida para Cargar el Modelo Ensamblado)
2
 
3
  import torch
4
  import torchvision.transforms as transforms
5
  from PIL import Image
6
  import json
 
7
  import gradio as gr
 
8
 
9
- # --- ¡CAMBIO 1: Importar la clase de nuestro modelo! ---
10
- from VisionEnsembleModel import VisionEnsembleModel
11
 
12
- # --- 1. Carga del Modelo y Componentes ---
13
  device = torch.device("cpu")
14
-
15
- # --- ¡VERIFICACIÓN! Apuntar al archivo de modelo correcto ---
16
- MODEL_PATH = "model/best_vision_ensemble_model.pth"
17
  LABELS_PATH = "model/species_labels_map.json"
18
  NUM_CLASSES = 156
19
 
20
- # Cargar mapa de etiquetas
21
  with open(LABELS_PATH) as f:
22
  labels_map = json.load(f)
23
 
24
- # --- ¡CAMBIO 2: Instanciar nuestro modelo personalizado! ---
25
- model = VisionEnsembleModel(num_classes=NUM_CLASSES)
26
  model.load_state_dict(torch.load(MODEL_PATH, map_location=device))
27
  model.to(device)
28
  model.eval()
29
 
30
- print("Modelo VisionEnsembleModel cargado y listo.")
31
 
32
- # --- 2. Definir la Función de Predicción para Gradio (SIN CAMBIOS) ---
33
  transforms_val = transforms.Compose([
34
  transforms.Resize((224, 224)),
35
  transforms.ToTensor(),
36
  transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
37
  ])
38
 
 
 
39
  def predict(image):
40
  pil_image = Image.fromarray(image.astype('uint8'), 'RGB')
41
  input_tensor = transforms_val(pil_image).unsqueeze(0).to(device)
 
42
  with torch.no_grad():
43
  output = model(input_tensor)
44
  probabilities = torch.nn.functional.softmax(output[0], dim=0)
45
 
46
  top5_prob, top5_catid = torch.topk(probabilities, 5)
 
47
  confidences = {}
48
  for i in range(top5_prob.size(0)):
49
  species_id = top5_catid[i].item()
50
  prob = top5_prob[i].item()
51
  species_name = labels_map.get(str(species_id), "Desconocido")
52
  confidences[species_name] = prob
 
53
  return confidences
54
 
55
- # --- 3. Crear y Lanzar la Interfaz de Gradio (SIN CAMBIOS) ---
 
56
  iface = gr.Interface(
57
  fn=predict,
58
  inputs=gr.Image(type="numpy", label="Sube una imagen de tu orquídea"),
59
  outputs=gr.Label(num_top_classes=5, label="Predicciones"),
60
- title="Clasificador de Orquídeas (Modelo Ensamblado)",
61
  description="Sube una foto de una orquídea y la IA intentará identificar la especie.",
62
  )
63
 
64
- iface.launch(server_name="0.0.0.0", server_port=7860)
 
 
 
 
 
 
1
+ # app.py (versión final combinando Gradio y FastAPI)
2
 
3
  import torch
4
  import torchvision.transforms as transforms
5
  from PIL import Image
6
  import json
7
+ import timm
8
  import gradio as gr
9
+ from fastapi import FastAPI
10
 
11
+ # --- 1. Carga del Modelo y Componentes (Sin cambios) ---
 
12
 
 
13
  device = torch.device("cpu")
14
+ MODEL_PATH = "model/best_mobilenet_model.pth"
 
 
15
  LABELS_PATH = "model/species_labels_map.json"
16
  NUM_CLASSES = 156
17
 
 
18
  with open(LABELS_PATH) as f:
19
  labels_map = json.load(f)
20
 
21
+ model = timm.create_model('mobilenetv2_100', pretrained=False, num_classes=NUM_CLASSES)
 
22
  model.load_state_dict(torch.load(MODEL_PATH, map_location=device))
23
  model.to(device)
24
  model.eval()
25
 
26
+ print("Modelo MobileNetV2 cargado y listo.")
27
 
 
28
  transforms_val = transforms.Compose([
29
  transforms.Resize((224, 224)),
30
  transforms.ToTensor(),
31
  transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
32
  ])
33
 
34
+ # --- 2. Función de Predicción (Sin cambios) ---
35
+
36
  def predict(image):
37
  pil_image = Image.fromarray(image.astype('uint8'), 'RGB')
38
  input_tensor = transforms_val(pil_image).unsqueeze(0).to(device)
39
+
40
  with torch.no_grad():
41
  output = model(input_tensor)
42
  probabilities = torch.nn.functional.softmax(output[0], dim=0)
43
 
44
  top5_prob, top5_catid = torch.topk(probabilities, 5)
45
+
46
  confidences = {}
47
  for i in range(top5_prob.size(0)):
48
  species_id = top5_catid[i].item()
49
  prob = top5_prob[i].item()
50
  species_name = labels_map.get(str(species_id), "Desconocido")
51
  confidences[species_name] = prob
52
+
53
  return confidences
54
 
55
+ # --- 3. Crear la Interfaz de Gradio (Sin 'launch()') ---
56
+
57
  iface = gr.Interface(
58
  fn=predict,
59
  inputs=gr.Image(type="numpy", label="Sube una imagen de tu orquídea"),
60
  outputs=gr.Label(num_top_classes=5, label="Predicciones"),
61
+ title="Clasificador de Orquídeas",
62
  description="Sube una foto de una orquídea y la IA intentará identificar la especie.",
63
  )
64
 
65
+ # --- 4. Crear la App FastAPI y Montar Gradio en ella ---
66
+
67
+ app = FastAPI()
68
+
69
+ # Montamos la interfaz de Gradio en la ruta raíz ("/") de nuestra aplicación FastAPI
70
+ app = gr.mount_gradio_app(app, iface, path="/")