Ir al contenido

Entrena tu primer modelo con tus anotaciones

Ejecuta el estudio de reseñas de muestra de Potato en un portátil sin GPU, etiqueta 120 reseñas con el simulador, entrena sklearn-text y observa las preetiquetas del modelo.

Novedad de la v2.14.0

Este tutorial entrena un clasificador de sentimiento con las etiquetas de un estudio de muestra y muestra las respuestas del clasificador al siguiente anotador como preetiquetas. El tutorial está escrito para quien dirige un estudio y prueba por primera vez el entrenamiento de modelos de Potato, y todos los pasos se ejecutan en un portátil sin GPU y sin más instalación que la del propio Potato. Inicias el proyecto de reseñas de muestra de Potato, haces que el simulador de usuarios etiquete 120 de las 160 reseñas del proyecto, entrenas sklearn-text desde la página Training del administrador, lees la puntuación sobre ítems reservados de la ejecución e inicias sesión como anotador nuevo para ver las respuestas del modelo. Para saber qué hace cada parte del ciclo en general, consulta la visión general del entrenamiento de modelos.

Instalar Potato y el proyecto de ejemplo

El tutorial usa sklearn-text, un entrenador que convierte cada reseña en características TF-IDF y ajusta un clasificador de regresión logística. sklearn-text no necesita ninguna instalación adicional, porque scikit-learn es una de las dependencias básicas de Potato. El proyecto de muestra está en el repositorio de GitHub de Potato y no en el paquete de pip, así que instala Potato y clona el repositorio:

bash
pip install --upgrade potato-annotation
git clone https://github.com/davidjurgens/potato.git
cd potato

Todos los comandos siguientes se ejecutan desde la raíz del repositorio. La carpeta del proyecto examples/ai-assisted/model-training/ contiene tres archivos:

  • config.yaml es la configuración del estudio, con los comandos de este tutorial en sus comentarios.
  • data/reviews.json contiene 160 reseñas sintéticas de productos, un objeto JSON por línea con un id y un text.
  • data/gold.json da la etiqueta correcta de cada reseña. El simulador responde a partir de este archivo.

La configuración de ejemplo

La configuración define un esquema radio llamado sentiment con las etiquetas positive y negative, y activa el entrenamiento de modelos. El bloque siguiente es el archivo incluido con los comentarios eliminados, y el archivo pasa python -m potato.validate_cli --strict sin cambios:

yaml
annotation_task_name: "Review Sentiment (model training demo)"
 
data_files:
  - "data/reviews.json"
 
item_properties:
  id_key: "id"
  text_key: "text"
 
task_dir: "."
output_annotation_dir: "annotation_output"
 
require_password: false
admin_api_key: "demo-admin-key"
 
num_annotators_per_item: 1
 
annotation_schemes:
  - annotation_type: "radio"
    name: "sentiment"
    description: "Is this review positive or negative?"
    labels:
      - "positive"
      - "negative"
    sequential_key_binding: true
 
model_training:
  enabled: true
  writeback:
    schemas: ["sentiment"]
    include_unlabeled: true
    min_confidence: 0.6

Cuatro ajustes dan forma al tutorial:

  • num_annotators_per_item: 1 da una etiqueta a cada reseña. Tres anotadores simulados con 40 reseñas cada uno cubren entonces 120 reseñas distintas y dejan 40 sin etiquetar para el modelo.
  • require_password: false permite que un anotador nuevo inicie sesión solo con un nombre de usuario. El último paso inicia sesión de ese modo.
  • admin_api_key: "demo-admin-key" abre las páginas de administración. Sustituye la clave en cualquier servidor al que puedan acceder otras personas.
  • model_training registra las rutas /admin/training. El bloque writeback muestra a los anotadores las predicciones del esquema sentiment, y la sección sobre la escritura de vuelta, más abajo, explica cada clave.

Iniciar el servidor en el puerto 8000

Inicia Potato con la configuración de ejemplo:

bash
potato start examples/ai-assisted/model-training/config.yaml -p 8000

El servidor carga las 160 reseñas y sirve la página de anotación en http://localhost:8000. Si el puerto 8000 está ocupado en tu máquina, pasa otro puerto a -p y úsalo en todas las URL siguientes.

Etiquetar 120 reseñas con el simulador

El modelo necesita etiquetas humanas de las que aprender. El simulador de usuarios sustituye a tres anotadores. Cada anotador simulado responde a partir del archivo gold y acierta la mayoría de las respuestas. Ejecuta el simulador en una segunda terminal, desde la raíz del repositorio:

bash
python -m potato.simulator --server http://localhost:8000 --users 3 \
  --strategy gold_standard --competence good=1.0 --max-annotations 40 \
  --gold-file examples/ai-assisted/model-training/data/gold.json \
  --sequential --fast-mode --no-export

--strategy gold_standard hace que cada anotador simulado responda a partir de gold.json, y --competence good=1.0 asigna a los tres anotadores el perfil good del simulador. Un anotador good obtiene una exactitud entre 0,80 y 0,90 y acierta cada reseña con esa probabilidad. Por eso las etiquetas contienen errores, como las de un equipo real. --sequential ejecuta los tres anotadores uno tras otro, --fast-mode elimina las pausas entre respuestas y --no-export omite la escritura de los archivos de resultados del propio simulador. El simulador termina en unos dos segundos y acaba con un resumen. Comprueba que el resumen indica Total annotations: 120 antes de continuar. También puedes etiquetar reseñas a mano en http://localhost:8000. sklearn-text se niega a ajustar el modelo con menos de 10 ítems etiquetados en la partición train.

Abrir la página Training con la clave de administrador

La página Training necesita una sesión de administrador. Abre http://localhost:8000/admin, introduce demo-admin-key cuando la página pida la clave de la API y abre después http://localhost:8000/admin/training.

La página Training de Potato con sklearn-text, el esquema sentiment y el backend local seleccionados, sobre una tabla de ejecuciones con dos ejecuciones terminadas y puntuaciones sobre ítems reservados de 0.847 y 0.840La página Training tras dos ejecuciones de sklearn-text en el proyecto de muestra

El panel Start a run de la parte superior contiene toda la configuración. Schema lista el único esquema del proyecto, sentiment (radio). Trainer lista los 38 entrenadores, y un entrenador que el proyecto no puede ejecutar lleva el motivo junto a su nombre, como «not installed». La página selecciona sklearn-text siempre que sklearn-text encaja con el esquema. Runs on muestra el único backend del proyecto, local (this machine).

Entrenar sklearn-text

Deja Parameters vacío para usar los valores predeterminados del entrenador y haz clic en Train now. La ejecución resuelve las anotaciones en una etiqueta por reseña, divide las 120 reseñas etiquetadas en particiones train, val y test, y ajusta el modelo en un proceso aparte. Nuestra ejecución tardó 1,5 segundos, y el panel mostró «Run finished.» cuando la ejecución terminó.

sklearn-text usa de forma predeterminada el TfidfVectorizer de scikit-learn para las características y LogisticRegression para el clasificador. Con 50 o más ítems en la partición train, sklearn-text también calibra las confianzas del clasificador. La calibración usa el escalado de Platt por debajo de 1000 ítems de entrenamiento y la regresión isotónica a partir de 1000 ítems. El modelo calibrado se conserva solo si la calibración cuesta como máximo 0,05 de exactitud de entrenamiento. La calibración importa aquí porque el paso de escritura de vuelta compara cada confianza con min_confidence.

Para iniciar la misma ejecución desde un script, envía la clave de administrador en la cabecera X-API-Key:

bash
curl -X POST -H "X-API-Key: demo-admin-key" -H "Content-Type: application/json" \
  http://localhost:8000/admin/training/api/runs \
  -d '{"trainer": "sklearn-text", "schemas": ["sentiment"]}'

La respuesta incluye el nuevo run_id y "started": true.

La página de la ejecución y la puntuación sobre ítems reservados

La ejecución terminada aparece en la tabla de ejecuciones con los tamaños de train y val y su Held-out score. Haz clic en el ID de la ejecución para abrir la página de la ejecución en /admin/training/runs/<run_id>. La página de la ejecución lista el estado, el entrenador, el backend, los tamaños de las particiones, la semilla de la partición, la puntuación sobre ítems reservados y los parámetros de la ejecución, y a continuación una tabla con todas las métricas y el registro de la ejecución.

De forma predeterminada, una ejecución reserva el 15 % de los ítems etiquetados para val y otro 15 % para test, y split_seed decide qué ítems van a cada partición. La partición se mantiene igual de una ejecución a otra mientras split_seed conserve su valor, así que dos ejecuciones con las mismas etiquetas se puntúan sobre los mismos ítems. La puntuación sobre ítems reservados de una ejecución de sklearn-text es el macro-F1 sobre val. El macro-F1 promedia la puntuación F1 de cada etiqueta, aquí positive y negative. La ejecución también registra la exactitud y el macro-F1 sobre test. La exactitud sobre la partición train se registra como train_accuracy y nunca se usa como puntuación. En nuestra ejecución, el registro decía:

text
[info] Read 76 labelled rows from the train split
[info] Applied sigmoid calibration over 5 folds
[info] Held-out val macro_f1: 0.725

La documentación de Potato informa de una ejecución sobre el mismo proyecto, y la tabla pone esa ejecución junto a la nuestra:

Documentación de PotatoNuestra ejecución
Reseñas etiquetadas120120
Ítems de train, val y testno se indica76, 19 y 25
Puntuación sobre ítems reservados (macro-F1 de val)0,840,725
Macro-F1 de testno se indica0,826
Preetiquetas publicadas8073
Predicciones por debajo de min_confidence411

Tus números diferirán de ambas columnas, porque cada anotador simulado obtiene una exactitud al azar y comete errores distintos. En nuestra ejecución, las etiquetas simuladas coincidieron con gold.json en 97 de las 120 reseñas y en 15 de las 19 reseñas de val. La puntuación sobre ítems reservados mide la coincidencia con las etiquetas de tus anotadores y no con ninguna clave de respuestas, así que los errores de los anotadores en val bajan la puntuación. Las 73 preetiquetas que publicó nuestra ejecución coincidían con gold.json. En un estudio real sin archivo gold, interpreta una puntuación baja sobre ítems reservados como un motivo para revisar el acuerdo entre anotadores antes de culpar al modelo.

Activar la escritura de vuelta para el esquema

Las predicciones de una ejecución llegan a los anotadores solo mediante la escritura de vuelta. La configuración de ejemplo ya activa la escritura de vuelta para el esquema sentiment. En tu propio proyecto, añade este bloque bajo model_training en la configuración y reinicia el servidor:

yaml
model_training:
  enabled: true
  writeback:
    schemas: ["sentiment"]
    include_unlabeled: true
    min_confidence: 0.6

writeback.schemas nombra los esquemas cuyas predicciones ven los anotadores. La lista está vacía de forma predeterminada, así que activar el entrenamiento no cambia nada en la página de anotación hasta que nombres un esquema. include_unlabeled: true hace que cada ejecución prediga también sobre las reseñas que nadie ha etiquetado, además de sobre las de val y test. Sin include_unlabeled, una ejecución predice solo sobre las reseñas de val y test, y esas reseñas ya tienen una etiqueta humana. min_confidence: 0.6 mantiene una predicción fuera de la página de anotación cuando la confianza del modelo cae por debajo de 0,6. Potato sigue almacenando la predicción.

La escritura de vuelta se ejecuta tras cada ejecución correcta y omite todo ítem de la partición train de la ejecución. En nuestra ejecución, el modelo predijo sobre 84 reseñas (19 de val, 25 de test y las 40 sin etiquetar), 11 predicciones quedaron por debajo de 0,6 y la ejecución publicó las otras 73. El campo writeback de GET /admin/training/api/status da los mismos recuentos, con el resumen «Published 73 prediction(s) as prelabels.». Las predicciones almacenadas se escriben de vuelta de nuevo cuando arranca el servidor, así que las preetiquetas sobreviven a un reinicio. Para quitar de los ítems las preetiquetas de una ejecución, envía DELETE /admin/training/api/runs/<run_id>/predictions.

Una preetiqueta vista por un anotador nuevo

Abre http://localhost:8000 en una ventana privada del navegador e inicia sesión con un nombre de usuario que nadie haya usado, como newannotator. Cada reseña etiquetada ya tiene su única etiqueta, así que al anotador nuevo se le asignan las 40 reseñas sin etiquetar, y el contador de progreso de nuestra ejecución indicaba 0/40. Nuestra primera reseña era «The toaster: Disappointed, it stopped working within a week. Much smaller than the photos suggest.» con Negative ya seleccionado con una confianza de 0,68.

Una página de anotación de Potato con una reseña de una tostadora, con la opción Positive ya seleccionada por el modelo y el ítem todavía marcado como Not labeledUna reseña que se abre con la respuesta del modelo seleccionada, antes de que el anotador haya guardado nada

La preetiqueta no se guarda mientras el anotador solo mira la reseña, y el indicador de estado dice «Not labeled» hasta que el anotador guarda una respuesta. La respuesta del modelo pasa a ser la del anotador cuando este cambia la selección o hace clic en Next. En nuestra ejecución, las 5 reseñas sin etiquetar cuya predicción quedó por debajo de min_confidence se abrieron sin nada seleccionado. Un anotador excluido de la ayuda automática con ai_support.holdout no ve ninguna preetiqueta. Las preetiquetas inclinan a los anotadores hacia la respuesta del modelo, así que activa la escritura de vuelta cuando la puntuación sobre ítems reservados sea lo bastante alta como para fiarse de ella, y vigila a los anotadores que aceptan todas las preetiquetas con las comprobaciones de detectar preetiquetas aceptadas sin revisar.

Próximos pasos

El mismo proyecto admite algunos experimentos más antes de pasar a tus propios datos:

  • Cambia un parámetro. Escribe {"vectorizer_kwargs": {"ngram_range": [1, 2]}} en Parameters y entrena de nuevo para añadir pares de palabras a las características. Nuestra segunda ejecución con pares de palabras obtuvo 0,774 de macro-F1 en val sobre la misma partición y publicó 74 preetiquetas. Un nombre de parámetro que sklearn-text no admite se rechaza con la lista de los nombres que sí admite el entrenador.
  • Prueba un transformer. hf-text-classification (pip install "potato-annotation[train-text]") y setfit (pip install "potato-annotation[embeddings]") aprenden el mismo esquema, y la página de entrenadores da los parámetros de cada entrenador.
  • Cierra el ciclo. El modelo en el ciclo añade la cola de revisión, el reentrenamiento a medida que llegan anotaciones con auto_retrain y el guardado de la partición de una ejecución como versión de un conjunto de datos.
  • Pasa el entrenamiento a una GPU. Entrenar en un servidor con GPU, un clúster SLURM o una máquina tras NAT envía las mismas ejecuciones a otra máquina.
  • Entrena otros tipos de modelo. Los tutoriales sobre ajuste fino de LLM, modelos de visión, modelos de audio y modelos científicos siguen los mismos pasos con otros entrenadores y esquemas.

Todas las claves usadas aquí figuran en la referencia de configuración del entrenamiento de modelos. Inicia la primera ejecución de tu propio proyecto copiando en tu configuración el bloque model_training de arriba y nombrando tu esquema en writeback.schemas.

Más información