File size: 19,004 Bytes
ef3d61f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f7a5626
ef3d61f
f7a5626
40342cb
ef3d61f
 
 
 
 
 
 
 
 
 
 
 
f7a5626
 
c1e40ac
f7a5626
 
c1e40ac
f7a5626
40342cb
f7a5626
 
 
ef3d61f
 
 
f7a5626
ef3d61f
 
 
 
 
 
 
 
f7a5626
 
 
ef3d61f
 
 
 
f7a5626
ef3d61f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4d6f113
 
ef3d61f
4d6f113
ef3d61f
 
 
 
f7a5626
 
ef3d61f
f7a5626
ef3d61f
f7a5626
 
 
 
ef3d61f
 
f7a5626
 
 
 
 
ef3d61f
 
 
 
 
 
 
 
 
 
 
f7a5626
 
 
ef3d61f
 
 
 
 
40342cb
 
 
 
 
 
 
 
 
 
 
 
ef3d61f
 
 
 
f7a5626
 
ef3d61f
 
 
 
 
 
 
f7a5626
ef3d61f
 
f7a5626
ef3d61f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40342cb
 
 
 
ef3d61f
 
 
ff110e2
1
2
3
4
5
6
7
8
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
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>FitoAsistente · Universidad San Sebastián</title>
<style>
  :root{
    --navy:#052A4A; --navy2:#0C3A5E; --blue:#297FD5; --teal:#00949D;
    --steel:#435D74; --gold:#C0A264; --gray:#606163; --bg:#F7F9FC;
    --card:#FFFFFF; --line:#DCE7F3;
  }
  *{box-sizing:border-box}
  body{
    margin:0; background:var(--bg); color:var(--gray);
    font-family:Calibri,"Segoe UI",system-ui,-apple-system,sans-serif;
    line-height:1.6; font-size:16px;
  }
  a{color:var(--blue); text-decoration:none}
  a:hover{text-decoration:underline}
  .wrap{max-width:960px; margin:0 auto; padding:0 24px}

  header{background:var(--navy); color:#fff; padding:48px 0 40px}
  header .eyebrow{
    font-size:12px; letter-spacing:.14em; text-transform:uppercase;
    color:#8FB4CE; font-weight:700; margin-bottom:18px;
  }
  header h1{margin:0 0 6px; font-size:46px; font-weight:700; letter-spacing:-.5px}
  header .sub{font-size:19px; color:#C9DCEA; margin:0 0 26px; max-width:620px}
  header .rule{height:3px; width:88px; background:var(--gold); margin-bottom:24px}
  header .meta{font-size:14px; color:#A9C4D6}

  .cta{
    display:inline-block; background:var(--gold); color:var(--navy);
    font-weight:700; padding:13px 26px; border-radius:6px; margin:6px 10px 6px 0;
    font-size:16px;
  }
  .cta:hover{background:#D0B478; text-decoration:none}
  .cta.ghost{background:transparent; color:#C9DCEA; border:1px solid #3C6484}
  .cta.ghost:hover{background:#0C3A5E}

  section{padding:44px 0; border-bottom:1px solid var(--line)}
  section:last-of-type{border-bottom:none}
  h2{color:var(--navy); font-size:27px; margin:0 0 6px; font-weight:700}
  h2 + .lead{color:var(--steel); font-style:italic; margin:0 0 22px}
  h3{color:var(--teal); font-size:18px; margin:26px 0 8px; font-weight:700}

  .aviso{
    background:#FFF8E8; border:1px solid #E8D9AE; border-left:4px solid var(--gold);
    border-radius:6px; padding:18px 22px; margin:26px 0;
  }
  .aviso strong{color:var(--navy)}

  .cards{display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:16px; margin-top:20px}
  .card{background:var(--card); border:1px solid var(--line); border-radius:8px; padding:20px 22px}
  .card h4{margin:0 0 4px; color:var(--navy); font-size:17px}
  .card .tag{
    display:inline-block; font-size:11px; letter-spacing:.09em; text-transform:uppercase;
    color:var(--teal); font-weight:700; margin-bottom:8px;
  }
  .card p{margin:0; font-size:14.5px}
  .card .big{font-size:30px; font-weight:700; color:var(--teal); line-height:1.2}

  table{width:100%; border-collapse:collapse; margin:18px 0 6px; background:var(--card); font-size:14.5px}
  th{background:var(--navy); color:#fff; text-align:left; padding:11px 13px; font-weight:700}
  th:not(:first-child), td:not(:first-child){text-align:center}
  td{padding:10px 13px; border-bottom:1px solid var(--line)}
  tr:nth-child(even) td{background:#F3F8FD}
  .win{color:var(--gold); font-weight:700}
  caption{caption-side:bottom; text-align:left; font-size:13px; font-style:italic; color:var(--steel); padding-top:8px}

  figure{margin:22px 0}
  figure img{width:100%; border:1px solid var(--line); border-radius:6px; background:#fff}
  figcaption{font-size:13px; font-style:italic; color:var(--steel); margin-top:7px}
  .figpair{display:grid; grid-template-columns:1fr 1fr; gap:16px}
  @media(max-width:700px){.figpair{grid-template-columns:1fr} header h1{font-size:34px}}

  ul{padding-left:20px} li{margin-bottom:7px}
  code{background:#EDF3FA; padding:2px 6px; border-radius:4px; font-size:13.5px; color:var(--navy)}

  footer{background:var(--navy); color:#A9C4D6; padding:32px 0; font-size:14px}
  footer a{color:#C9DCEA}
  .gold-bar{height:4px; background:var(--gold)}
</style>
</head>
<body>

<header>
  <div class="wrap">
    <div class="eyebrow">Universidad San Sebastián · Facultad de Ingeniería · Magíster en Data Science</div>
    <h1>FitoAsistente</h1>
    <p class="sub">Asistente para el diagnóstico fitosanitario de cultivos, con dos capacidades distintas de modelos fundacionales de Hugging Face.</p>
    <div class="rule"></div>
    <a class="cta" href="#demo">Ver la demostración</a>
    <a class="cta ghost" href="#ejecutar">Ejecutar la aplicación</a>
    <a class="cta ghost" href="https://huggingface.co/JohnSupertramp2026/vit-base-plantvillage" target="_blank" rel="noopener">Modelo ViT</a>
    <a class="cta ghost" href="https://huggingface.co/JohnSupertramp2026/convnext-tiny-plantvillage" target="_blank" rel="noopener">Modelo ConvNeXt</a>
    <p class="meta" style="margin-top:26px">
      Jonathan Núñez Moya · Francisco Rietta González<br>
      Inteligencia Artificial — Prof. Manuel Alejandro Goyo · Agosto de 2026
    </p>
  </div>
</header>
<div class="gold-bar"></div>

<div class="wrap">

<section id="demo">
  <h2>La aplicación funcionando</h2>
  <p class="lead">Recorrido real de 20 segundos, grabado sobre la aplicación en ejecución</p>
  <video src="FitoAsistente_demo.mp4" controls muted playsinline loop preload="metadata"
         style="width:100%;border-radius:10px;border:1px solid #D6DEE6;background:#F7F9FB"></video>
  <p style="margin-top:14px">Se arrastra la fotografía de una hoja al recuadro, el clasificador la identifica como <strong>Peach · Bacterial spot</strong> con 99,7 % de confianza, el asistente responde una consulta sobre la enfermedad con ese diagnóstico ya en contexto, y una consulta ajena al dominio queda rechazada por el filtro sin llegar al modelo de lenguaje.</p>
  <div class="aviso" style="margin-top:16px">
    <p style="margin:0"><strong>Por qué publicamos un video y no un enlace.</strong> La dirección pública que genera Gradio existe únicamente mientras el cuaderno está en ejecución, así que cualquier enlace que dejáramos aquí quedaría muerto a los pocos días. El video resuelve eso: dispone el funcionamiento completo de forma permanente y verificable. Y si prefieres ejecutarla tú, el cuaderno está en la entrega y levanta en unos cuatro minutos — las instrucciones están más abajo.</p>
  </div>
</section>

<section>
  <h2>Qué hace</h2>
  <p class="lead">Dos capacidades distintas de modelos fundacionales, en una sola aplicación</p>
  <p>Subes la foto de una hoja y el sistema hace dos cosas que no son la misma. La <strong>clasifica</strong> entre 38 categorías fitopatológicas, y después <strong>conversa</strong> contigo sobre qué hacer con ese diagnóstico. El sistema tiene dos capacidades y tres modelos: ViT y ConvNeXt resuelven la misma tarea y están los dos porque son el objeto de la comparación experimental.</p>

  <div class="cards">
    <div class="card">
      <span class="tag">Capacidad 1 · image-classification</span>
      <h4>ViT-Base/16 y ConvNeXt-Tiny</h4>
      <p>Ajustados sobre PlantVillage. Devuelven una etiqueta entre 38 clases con su probabilidad. Se pueden ejecutar por separado o comparar lado a lado.</p>
    </div>
    <div class="card">
      <span class="tag">Capacidad 2 · text-generation</span>
      <h4>Qwen2.5-1.5B-Instruct</h4>
      <p>Sin ajustar. Recibe como texto la clase que decidió el clasificador y conversa sobre tratamiento y manejo. No procesa la imagen.</p>
    </div>
  </div>

  <h3>Por qué se necesitan las dos</h3>
  <p>El clasificador es preciso pero cerrado: ante una especie que nunca vio devuelve igual una de sus 38 etiquetas, con alta confianza y sin manera de decir «no sé». El modelo de lenguaje no decide nada: recibe la clase ya resuelta y se encarga de traducirla a manejo agronómico, que es la pregunta que un usuario tiene de verdad frente a una hoja enferma.</p>
</section>

<section>
  <h2>Resultados</h2>
  <p class="lead">Comparación controlada sobre el conjunto de prueba, usado una sola vez</p>

  <table>
    <caption>Todas las condiciones idénticas salvo la arquitectura: 20 % estratificado de PlantVillage, partición 80/10/10, semilla 42, 3 épocas, lote 32, learning rate 5e-5, GPU T4.</caption>
    <thead>
      <tr><th>Modelo</th><th>Preentr.</th><th>Parámetros</th><th>Exactitud</th><th>Macro F1</th><th>Weighted F1</th><th>Latencia CPU</th></tr>
    </thead>
    <tbody>
      <tr><td>CNN desde cero <span style="color:#8A93A0">(referencia)</span></td><td>No</td><td>8,49 M</td><td>59,60 %</td><td>0,354</td><td>0,544</td><td></td></tr>
      <tr><td><strong>ViT-Base/16</strong></td><td>IN-21k</td><td>85,83 M</td><td class="win">99,08 %</td><td class="win">0,988</td><td class="win">0,991</td><td>395,0 ms</td></tr>
      <tr><td><strong>ConvNeXt-Tiny</strong></td><td>IN-1k</td><td>27,85 M</td><td>96,41 %</td><td>0,919</td><td>0,960</td><td class="win">119,6 ms</td></tr>
    </tbody>
  </table>

  <div class="cards">
    <div class="card"><div class="big">+63,4 pp</div><p>de macro F1 sobre la red entrenada desde cero, contra +39,5 pp de exactitud</p></div>
    <div class="card"><div class="big">+6,9 pp</div><p>de macro F1 de ViT sobre ConvNeXt, con solo 2,7 pp de diferencia en exactitud</p></div>
    <div class="card"><div class="big">3,3×</div><p>más rápido ConvNeXt en CPU, con un tercio de los parámetros</p></div>
  </div>

  <h3>Por qué la brecha es tan distinta según la métrica</h3>
  <p>ConvNeXt obtuvo un F1 de <strong>0,000</strong> en <code>Potato___healthy</code>, una clase con solo tres ejemplos en prueba, y <strong>0,182</strong> en <code>Corn___Cercospora_leaf_spot</code>. ViT resolvió las dos por encima de 0,900. Abandonar las clases pequeñas es exactamente el mismo patrón que había mostrado la red entrenada desde cero, y por eso elegimos ViT como modelo por defecto aunque sea más lento.</p>
  <p>Las dos arquitecturas coinciden en tres de sus cinco peores clases. Cuando los dos modelos fallan en lo mismo, la dificultad viene del problema y no del modelo.</p>

  <div class="figpair">
    <figure><img src="matriz_confusion_vit-base.png" alt="Matriz de confusión de ViT-Base"><figcaption>Matriz de confusión normalizada — ViT-Base/16</figcaption></figure>
    <figure><img src="matriz_confusion_convnext-tiny.png" alt="Matriz de confusión de ConvNeXt-Tiny"><figcaption>Matriz de confusión normalizada — ConvNeXt-Tiny</figcaption></figure>
  </div>
  <figure><img src="curvas_entrenamiento.png" alt="Curvas de entrenamiento"><figcaption>Pérdida y macro F1 de validación. ViT llegó a 0,981 de macro F1 en la primera época; ConvNeXt partió en 0,646 y necesitó las tres para llegar a 0,936.</figcaption></figure>
</section>

<section>
  <h2>Lo que aprendimos del modelo de lenguaje</h2>
  <p class="lead">Medimos la segunda capacidad y dos cosas que creíamos resultaron falsas</p>
  <p>Sometimos el asistente a diez consultas sobre una misma hoja de duraznero clasificada como <em>Peach · Bacterial spot</em>: ocho del dominio agronómico y dos deliberadamente ajenas. Cada respuesta se clasificó en correcta, vaga o incorrecta.</p>
  <table>
    <thead><tr><th>Resultado sobre 10 consultas</th><th>Qwen2.5-0,5B</th><th>Qwen2.5-1,5B</th></tr></thead>
    <tbody>
      <tr><td style="text-align:left">Correctas (de 8 en dominio)</td><td>0</td><td class="win">1</td></tr>
      <tr><td style="text-align:left">Vagas (de 8 en dominio)</td><td>1</td><td>3</td></tr>
      <tr><td style="text-align:left">Incorrectas (de 8 en dominio)</td><td>7</td><td>4</td></tr>
      <tr><td style="text-align:left">Fuera de dominio bloqueadas</td><td>0 de 2</td><td class="win">2 de 2</td></tr>
    </tbody>
  </table>
  <h3>El resultado más informativo</h3>
  <p>Ante la pregunta por la dosis de cobre, el modelo de 0,5 B inventó una cifra —<em>«0,001 gramos por litro»</em>— y un instrumento que no existe. El de 1,5 B respondió que no tenía información específica y derivó a un agrónomo. <strong>Se abstuvo.</strong> Un modelo mayor no solo acierta más: reconoce mejor los límites de lo que sabe, y en un asistente que sugiere tratamientos eso importa más que la exactitud media.</p>
  <h3>El guardarraíl por instrucción no funcionaba</h3>
  <p>Habíamos escrito en la instrucción de sistema que el asistente solo respondiera sobre botánica y agricultura. Al medirlo, dejó pasar las dos consultas ajenas al dominio: a una pregunta de salud humana llegó a sugerir analgésicos. Lo reemplazamos por un <strong>filtro léxico determinista</strong> que decide antes de invocar al modelo, y que acertó <strong>21 de 21</strong> casos etiquetados. La lección se resume en una línea: lo que debe cumplirse siempre no se le pide al modelo, se le impone al sistema.</p>
  <p>Es una mitigación, no una solución: el filtro decide por vocabulario, así que una consulta ajena redactada con palabras agrícolas pasaría.</p>
</section>

<section>
  <h2>Limitaciones</h2>
  <p class="lead">Lo que este trabajo no demuestra</p>
  <ul>
    <li><strong>El 99,08 % está inflado.</strong> PlantVillage contiene varias fotografías de la misma hoja física. La versión original trae particiones que preservan ese agrupamiento; nosotros repartimos al azar, así que es probable que fotos de una misma hoja hayan quedado en entrenamiento y en prueba. Infla las tres filas por igual, de modo que la comparación entre modelos sigue siendo válida, pero la cifra no estima el desempeño sobre hojas nuevas.</li>
    <li><strong>Laboratorio, no campo.</strong> Mohanty et al. (2016) documentaron que la exactitud cae al 31 % en fotografías de terreno.</li>
    <li><strong>Tres épocas es poco.</strong> ConvNeXt todavía venía subiendo en la tercera, así que su cifra final subestima su techo.</li>
    <li><strong>Muestras pequeñas.</strong> Varias clases tienen menos de diez ejemplos en prueba y sus F1 individuales son inestables.</li>
    <li><strong>Conjunto cerrado.</strong> El clasificador no tiene mecanismo de rechazo.</li>
    <li><strong>El asistente no es confiable.</strong> De ocho consultas en dominio, Qwen2.5-1.5B acertó una. Explica y sugiere; no valida un tratamiento.</li>
    <li><strong>El filtro de dominio es léxico y se puede burlar.</strong> Decide por vocabulario: una consulta ajena redactada con palabras agrícolas pasaría.</li>
    <li><strong>El asistente arrastra sus propios errores.</strong> Como el historial viaja en cada consulta, una alucinación del primer turno se propaga a los siguientes.</li>
    <li>La aplicación prioriza la atención de un profesional. No lo reemplaza.</li>
  </ul>
  <p>En lo metodológico, los dos hallazgos que más cambiaron nuestra lectura de los resultados —el buffer de barajado del experimento de referencia y el agrupamiento por hoja de PlantVillage— no tienen nada que ver con la arquitectura de los modelos.</p>
</section>

<section id="ejecutar">
  <h2>Ejecutar la aplicación</h2>
  <p class="lead">Cuatro minutos, sin instalar nada en tu equipo</p>
  <ol>
    <li>Abre <code>4_Codigo_Aplicacion_Gradio.ipynb</code> —incluido en la entrega— en <a href="https://colab.research.google.com" target="_blank" rel="noopener">Google Colab</a>.</li>
    <li>Menú <em>Entorno de ejecución → Cambiar tipo de entorno → GPU T4</em>. Sin GPU también funciona, pero el asistente tarda entre 15 y 30 segundos por respuesta.</li>
    <li>Ejecuta todas las celdas (<code>Ctrl+F9</code>). La descarga de los tres modelos desde el Hub toma unos minutos la primera vez.</li>
    <li>La última celda imprime una dirección terminada en <code>.gradio.live</code>. Esa es la aplicación, y funciona desde cualquier navegador mientras el cuaderno siga abierto.</li>
  </ol>
  <p>Los tres modelos se descargan solos desde el Hub, así que no hay que entrenar nada ni configurar credenciales. El cuaderno de entrenamiento se entrega por separado y con todas sus salidas ejecutadas, por si interesa revisar el proceso completo.</p>
</section>

<section>
  <h2>Sobre este despliegue</h2>
  <div class="aviso">
    <p style="margin:0 0 10px"><strong>Por qué la aplicación no corre dentro de este Space.</strong></p>
    <p style="margin:0 0 10px">En julio de 2026 Hugging Face modificó su política: los Spaces de tipo <strong>Gradio</strong> y <strong>Docker</strong> pasaron a requerir plan PRO, mientras que los de tipo <strong>Static</strong> siguen siendo gratuitos. Está documentado en el <a href="https://discuss.huggingface.co/t/gradio-sdk-now-marked-as-paid-when-creating-a-new-space/177619" target="_blank" rel="noopener">foro oficial de Hugging Face</a>.</p>
    <p style="margin:0 0 10px">La documentación menciona una excepción: una cuenta gratuita «in good standing» podría alojar hasta dos Spaces Gradio sobre <strong>ZeroGPU</strong>. La verificamos en la cuenta del proyecto el 11 de agosto de 2026 y no estuvo disponible: el formulario de creación ofrece Gradio y Docker marcados como «Paid», sin opción de hardware ZeroGPU.</p>
    <p style="margin:0">La aplicación es exactamente la misma que habíamos preparado. Lo único que cambia es dónde se ejecuta el proceso: en vez del contenedor de Hugging Face, corre en un cuaderno de Google Colab y Gradio publica la dirección con <code>share=True</code>. Los dos modelos ajustados siguen publicados en el Hub, y esta portada está desplegada como Space Static.</p>
  </div>

  <h3>Componentes del proyecto</h3>
  <ul>
    <li><a href="https://huggingface.co/JohnSupertramp2026/vit-base-plantvillage" target="_blank" rel="noopener">ViT-Base/16 ajustado sobre PlantVillage</a> — 38 clases, publicado en el Hub</li>
    <li><a href="https://huggingface.co/JohnSupertramp2026/convnext-tiny-plantvillage" target="_blank" rel="noopener">ConvNeXt-Tiny ajustado sobre PlantVillage</a> — 38 clases, publicado en el Hub</li>
    <li><a href="https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct" target="_blank" rel="noopener">Qwen2.5-1.5B-Instruct</a> — usado sin modificar</li>
    <li><a href="https://huggingface.co/datasets/BrandonFors/Plant-Diseases-PlantVillage-Dataset" target="_blank" rel="noopener">Dataset PlantVillage</a> — 54.305 imágenes, 38 clases</li>
    <li>Esta portada, desplegada como Space Static en Hugging Face</li>
    <li>El video de demostración, disponible de forma permanente en esta misma página</li>
  </ul>
</section>

</div>

<div class="gold-bar"></div>
<footer>
  <div class="wrap">
    <strong style="color:#fff">Universidad San Sebastián</strong> · Facultad de Ingeniería · Magíster en Data Science<br>
    Proyecto Final de Inteligencia Artificial · Prof. Manuel Alejandro Goyo · Agosto de 2026<br>
    Jonathan Núñez Moya · Francisco Rietta González
  </div>
</footer>

<script>
  // La aplicación corre desde un cuaderno de Colab y su dirección .gradio.live
  // cambia en cada ejecución, así que no se publica ningún enlace aquí: el video
  // de esta página cubre la demostración y la sección «Ejecutar la aplicación»
  // explica cómo levantarla. Decisión deliberada, no un enlace pendiente.
</script>

</body>
</html>