Entrena modelos con moléculas, espectros, señales y episodios de robots
Ajusta rdkit-property, peak-cnn, signal-cnn y episode-model con las respuestas de tu estudio y muestra las predicciones a los anotadores para que las acepten o las corrijan.
Novedad de la v2.14.0
Este tutorial entrena cuatro modelos con anotaciones científicas de un estudio de Potato. rdkit-property responde a una pregunta sobre una molécula, peak-cnn localiza picos en espectros de RMN, IR, Raman, UV-Vis y de masas, signal-cnn clasifica en fases de sueño las épocas o marca intervalos etiquetados en grabaciones de EEG, ECG y sensores, y episode-model marca las fases, el resultado y la curva de recompensa de un episodio de robot. La página está dirigida a equipos que ya anotan moléculas, espectros, señales o episodios de robot en Potato y quieren un modelo que preetiquete los ítems restantes. Para cada entrenador, la página ofrece una configuración que pasa potato validate config.yaml --strict, lo que aprende una ejecución, la puntuación sobre ítems reservados que conviene leer y cómo llegan las predicciones a los anotadores. Entrena tu primer modelo recorre la página Training con un clasificador de texto, y este tutorial parte de ese recorrido.
Los cuatro entrenadores
Cada entrenador aprende de las respuestas de un esquema de anotación y lee la entrada del modelo del display o del archivo al que apunta el esquema:
| Entrenador | Esquema | Entrada | Instalación | Puntuación principal sobre ítems reservados |
|---|---|---|---|---|
rdkit-property | radio, select, likert o slider sobre una molécula | un campo de display molecule, o una respuesta chemical_structure | potato-annotation[chemistry] | macro-F1, o exactitud de posición exacta para un deslizador |
peak-cnn | peak_picking | espectros de JCAMP-DX, mzML, CSV o datos en línea | potato-annotation[train-vision] | F1 de picos dentro de una tolerancia |
signal-cnn | interval_label, en modo epoch o free | señales de EDF, BDF, WFDB, CSV, Parquet o datos en línea | potato-annotation[train-vision], más [signals] para WFDB y Parquet | macro-F1 sobre las épocas, o F1 de intervalos con IoU 0,5 |
episode-model | episode_annotation | episodios de robot de LeRobot, HDF5 o el manifiesto de episodios de Potato | potato-annotation[train-vision] | macro-F1 de fases |
rdkit-property ajusta un modelo de scikit-learn, y los otros tres entrenadores ajustan redes PyTorch pequeñas en el dispositivo que selecciona model_training.device. Cada ejecución entrena con un esquema, puntúa el modelo sobre los ítems reservados val y test de la ejecución y escribe de vuelta las predicciones solo para los esquemas listados en writeback.schemas. Los ítems de la partición train de una ejecución nunca reciben preetiqueta. peak-cnn, signal-cnn y episode-model conservan el punto de control de la época que puntuó mejor sobre val, así que Potato toma de test la puntuación sobre ítems reservados de las tres redes. Un estudio pequeño tiene pocos ítems de test, y la métrica test_n de la ejecución da el recuento que hay detrás de la puntuación.
Las tres redes dan a la predicción de un ítem la confianza de la parte menos segura de la predicción, es decir, el pico, el intervalo, la fase o el resultado más débil. Por tanto, un umbral mínimo de confianza writeback.min_confidence retiene el ítem entero cuando cualquiera de sus partes queda por debajo del umbral. Una predicción de deslizador de rdkit-property no tiene valor de confianza y siempre supera el umbral.
Propiedades moleculares con rdkit-property
rdkit-property aprende las respuestas a una pregunta sobre la molécula que muestra un ítem, y la estructura de la molécula es la entrada del modelo en lugar del texto del ítem. Cada estructura se convierte en una huella de Morgan de radio 2 y 2048 bits seguida de los descriptores 2D de RDKit, por ejemplo el peso molecular y el logP. Con radio 2, la huella de Morgan equivale a ECFP4, la huella de conectividad extendida con un diámetro de 4 enlaces. La regresión logística ajusta por defecto una respuesta radio, select o likert, y la regresión ridge ajusta un slider. Un bosque aleatorio es la alternativa para ambos. Instala RDKit en el servidor que entrena:
pip install "potato-annotation[chemistry]"La siguiente configuración muestra cada compuesto como un dibujo de su estructura y plantea dos preguntas, un deslizador de 1 a 10 sobre lo difícil que sería fabricar el compuesto y una elección de sí o no sobre fabricar el compuesto a continuación:
annotation_task_name: "Compound triage"
task_dir: .
output_annotation_dir: annotation_output
data_files: [data/molecules.jsonl]
item_properties: {id_key: id, text_key: note}
user_config:
allow_all_users: true
instance_display:
fields:
- key: smiles # SMILES, a molfile, or a .mol, .sdf or .smi file
type: molecule
label: "Compound"
annotation_schemes:
- annotation_type: slider
name: synthesis
description: "How hard would this compound be to make? 1 is one step from a catalog reagent, 10 is a research project."
min_value: 1
max_value: 10
starting_value: 5
step: 1
- annotation_type: radio
name: advance
description: "Would you make this compound next?"
labels: ["yes", "no"]
model_training:
enabled: true
writeback:
schemas: [synthesis, advance]
include_unlabeled: true
min_confidence: 0.6Cada línea del archivo de datos contiene un compuesto:
{"id": "cpd_023", "smiles": "CC(=O)Nc1ccc(O)cc1", "note": "Compound 23"}El entrenador toma la estructura del primer campo molecule de instance_display. Un estudio sin un campo molecule puede plantear la pregunta junto a un esquema chemical_structure, y entonces el entrenador aprende de la estructura que dibujaron los anotadores. Cuando los anotadores dibujaron estructuras distintas, el entrenador toma el dibujo más frecuente, y cuando nadie dibujó, toma la estructura con la que empezó el editor (prefill_field). La página Training ofrece rdkit-property para un campo molecule cuando al menos el 80 % de los ítems rellenan el campo. Una estructura que RDKit no puede analizar queda fuera del entrenamiento, no recibe predicción y se cuenta en la métrica n_unparseable de la ejecución. Para una pregunta de elección o de Likert, la página Training ofrece también los entrenadores de texto, porque los ítems siguen teniendo texto.
La predicción de un deslizador se redondea al step del deslizador y se mantiene entre min_value y max_value, de modo que el modelo siempre propone una posición que el deslizador tiene. La puntuación principal de un deslizador es la exactitud de posición exacta, que cuenta como error una predicción de 6 frente a una respuesta de 7. Lee val_mae o test_mae, el error absoluto medio, junto a la exactitud antes de decidir si las predicciones son lo bastante cercanas para mostrarlas. La ejecución necesita al menos 10 moléculas etiquetadas en la partición train. Parámetros como model, class_weight, radius y bits van en el campo Parameters de la página Training o en la solicitud a la API:
curl -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
http://localhost:8000/admin/training/api/runs \
-d '{"trainer": "rdkit-property", "schemas": ["advance"],
"params": {"model": "random_forest", "class_weight": "balanced"}}'El registro de la ejecución indica el número de moléculas, el número de características y el modelo. Un peso de clase equilibrado da más peso a las respuestas poco frecuentes. Usa class_weight: balanced cuando la mayoría de los compuestos reciben la misma respuesta. Cuando la ejecución termina, un anotador que abre un compuesto sin etiquetar encuentra el deslizador en el valor del modelo y la elección del modelo seleccionada, ambos editables.
Picos en espectros con peak-cnn
peak-cnn aprende a localizar picos a partir de las respuestas peak_picking que dieron los anotadores. El entrenador lee el espectro que muestra el viewer_field del esquema, con los mismos lectores que usa el display de espectros. El objetivo de entrenamiento es cada pico que el anotador conservó, tanto las sugerencias aceptadas como los picos añadidos. Una sugerencia que el anotador rechazó marca un lugar sin pico. El modelo predice solo las posiciones de los picos, y los anotadores siguen dando a cada pico una asignación, una etiqueta o una multiplicidad. Instala PyTorch en la máquina que entrena:
pip install "potato-annotation[train-vision]"La siguiente configuración pide a los anotadores que revisen los picos sugeridos en espectros de RMN de 1H:
annotation_task_name: "1H NMR peak picking"
task_dir: .
media_directory: media
output_annotation_dir: annotation_output
data_files: [data/spectra.jsonl]
item_properties: {id_key: id, text_key: note}
user_config:
allow_all_users: true
instance_display:
fields:
- key: spectrum
type: spectrum
label: "1H NMR"
display_options:
prepick:
method: auto # item peaks, then model, then file peak table, then detector
prominence: 0.05
max_peaks: 30
annotation_schemes:
- annotation_type: peak_picking
name: peaks
description: "Accept or reject each suggested peak, and add any the suggestions missed"
viewer_field: spectrum
peak_fields:
- name: assignment
placeholder: "e.g. OCH2"
require_review: true
label_requirement: {required: true}
model_training:
enabled: true
trainer_params:
peak-cnn:
tolerance: 0.02 # ppm
writeback:
schemas: [peaks]
include_unlabeled: trueLos picos del modelo llegan a los anotadores solo mediante el ajuste prepick del display, y sin prepick el display no muestra ninguna sugerencia. Con method: auto, el display ofrece primero los peaks propios del ítem, después los picos del modelo, luego la tabla de picos del archivo y por último los picos que encuentra el detector. Antes de la primera ejecución, los anotadores revisan las sugerencias del detector, y después de una ejecución los mismos ítems muestran los picos del modelo sin reiniciar. Con method: model, el display muestra solo los picos del modelo. Usa method: model para medir con qué frecuencia aceptan los anotadores los picos del modelo sin las sugerencias del detector mezcladas. Cada pico del modelo aparece en la lista con «· model», el display conserva los max_peaks de mayor confianza, y un pico del modelo aceptado se almacena con source: model.
El parámetro tolerance fija cuánto, en unidades de x, puede distar un pico predicho de un pico anotado y seguir contando como encontrado. Sin tolerance, la ejecución usa el 0,5 % del rango x del espectro, y el 0,5 % de una ventana de 12 ppm de 1H son 0,06 ppm. A 400 MHz, un acoplamiento de 7 Hz separa las líneas de un multiplete en 0,0175 ppm. La tolerancia predeterminada es más ancha que esa separación, y la configuración fija 0,02 ppm en su lugar. La ejecución puntúa la precisión, la exhaustividad y la F1 sobre los picos emparejados uno a uno, empezando por el más cercano, y notifica el desplazamiento medio de los picos emparejados. Un pico predicho en un espectro que el anotador indicó que no tiene picos cuenta como falsa alarma. La ejecución necesita al menos 5 espectros anotados en la partición train.
Cada espectro se remuestrea a length puntos, 4096 por defecto, antes de que la red lo vea. Aumenta length cuando los picos son más estrechos que 1/length del rango x, por ejemplo en un espectro de masas de alta resolución. Leer archivos mzML necesita además el extra spectra, como describe la página del display de espectros.
Fases de sueño e intervalos de señal con signal-cnn
signal-cnn aprende de las respuestas interval_label sobre grabaciones fisiológicas y de sensores, como EEG, ECG, EMG y datos de acelerómetro. La red es un modelo InceptionTime pequeño, una pila de convoluciones paralelas de tres anchuras. El entrenador lee cada grabación con los lectores del display de series temporales, toma los canales que nombra el display, remuestrea cada canal a rate (100 Hz por defecto) y estandariza cada canal. Instala PyTorch, y el extra signals para las grabaciones WFDB y Parquet:
pip install "potato-annotation[train-vision,signals]"La siguiente configuración puntúa el sueño en épocas de 30 segundos sobre polisomnografía de toda la noche, como un evaluador humano que etiqueta cada época como vigilia, N1, N2, N3 o REM:
annotation_task_name: "Sleep staging"
task_dir: .
media_directory: media
output_annotation_dir: annotation_output
data_files: [data/psg.jsonl]
item_properties: {id_key: id, text_key: note}
user_config:
allow_all_users: true
instance_display:
fields:
- key: signal
type: time_series
label: "PSG"
display_options:
window: 30
channels: ["EEG Fpz-Cz", "EOG", "EMG chin"] # also the channels signal-cnn reads
annotation_schemes:
- annotation_type: interval_label
name: stage
description: "Sleep stage of each 30-second epoch"
signal_field: signal
mode: epoch
epoch_length: 30
require_all_epochs: true
label_requirement: {required: true}
labels:
- {name: W, key_value: "1"}
- {name: N1, key_value: "2"}
- {name: N2, key_value: "3"}
- {name: N3, key_value: "4"}
- {name: REM, key_value: "5"}
model_training:
enabled: true
writeback:
schemas: [stage]
include_unlabeled: trueEl mode del esquema fija la tarea. En modo epoch, cada época anotada es un ejemplo de entrenamiento, y el modelo etiqueta cada época de una grabación nueva. Una última época con menos de la mitad de la duración de la época grabada no recibe etiqueta. La puntuación principal sobre ítems reservados es la macro-F1 sobre las épocas anotadas. La macro-F1 da a una fase poco frecuente como N1 el mismo peso que a N2. Por defecto, la pérdida de entrenamiento pondera cada fase por la inversa de la frecuencia de la etiqueta (balanced: true), y entonces una época N1 cuenta más que una época N2. Cada grabación se lee con los canales de la primera grabación de entrenamiento, en ese orden, y una grabación que carece de uno de los canales de entrenamiento recibe una línea plana en lugar del canal que falta. Un display que no nombra canales da al entrenador todos los canales, hasta max_channels (16).
El modo free entrena con tramos marcados en su lugar. Añade un segundo esquema interval_label con mode: free al mismo signal_field para marcar artefactos o microdespertares:
- annotation_type: interval_label
name: artifacts
description: "Mark artifacts"
signal_field: signal
mode: free
labels:
- {name: artifact, key_value: "a"}
- {name: spike, key_value: "s", kind: event}En modo free, la red entrena con recortes aleatorios de 30 segundos (window_s), etiqueta cada fotograma de 1 segundo (frame_s), fusiona los fotogramas consecutivos con una misma etiqueta en un intervalo y descarta los intervalos más cortos que min_duration. La puntuación principal es la F1 de intervalos, que empareja un intervalo predicho con uno anotado de la misma etiqueta con IoU 0,5. Los eventos puntuales como la etiqueta spike de arriba no se entrenan ni se predicen. La ejecución necesita al menos 3 grabaciones anotadas en la partición train, y el modo epoch necesita además al menos dos etiquetas distintas en los datos.
Los intervalos del modelo aparecen en la grabación como preanotaciones discontinuas, listadas con «· from the model», y se guardan cuando el anotador hace un primer cambio o pulsa «Keep these». Las anotaciones propias de una grabación tienen prioridad. Un archivo EDF+ que contiene un hipnograma muestra el hipnograma y no los intervalos del modelo, y lo mismo vale para un ítem con intervalos de preannotation_field. Fijar pre_annotations: false en el esquema desactiva ambos tipos.
Episodios de robot con episode-model
episode-model aprende las tres capas de una respuesta episode_annotation, es decir, las fases, el resultado y la curva de recompensa de progreso. La entrada del modelo es cada serie numérica que registra el episodio, como las posiciones de las articulaciones y el estado de la pinza, con una fila por fotograma. La entrada incluye las series que series_shown deja fuera de la pantalla y excluye el vídeo. El modelo no puede encontrar una fase que solo se aprecia en la cámara y deja sin cambios las mediciones del robot. Instala PyTorch, más pyarrow para los conjuntos de datos LeRobot o h5py para las demostraciones HDF5:
pip install "potato-annotation[train-vision]"La siguiente configuración recoge las tres capas en demostraciones de coger y colocar, como describe la página de episodios de robot:
annotation_task_name: "Robot episode review"
task_dir: .
media_directory: media
output_annotation_dir: annotation_output
data_files: [data/episodes.jsonl]
item_properties: {id_key: id, text_key: note}
user_config:
allow_all_users: true
annotation_schemes:
- annotation_type: episode_annotation
name: episode_review
description: "Mark the phases, judge the outcome, and draw the progress."
source_field: episode
layers: [phases, outcome, reward]
phases:
- {name: reach, key_value: "1"}
- {name: grasp, key_value: "2"}
- {name: transport, key_value: "3"}
- {name: place, key_value: "4"}
- {name: retract, key_value: "5"}
outcomes: [success, partial, failure]
failure_causes: [missed grasp, object slipped, collision]
reward_range: [0.0, 1.0]
series_shown: [gripper, wrist_force, shoulder_lift, elbow]
model_training:
enabled: true
writeback:
schemas: [episode_review]
include_unlabeled: trueLa red aplica una convolución sobre las series que alimenta una GRU bidireccional con tres cabezas, una para la fase de cada fotograma, otra para el resultado del episodio y otra para la recompensa en cada fotograma. Una capa que una respuesta deja vacía queda fuera de la pérdida de ese episodio, así que un episodio marcado solo con un resultado sigue entrenando la cabeza del resultado. La cabeza del resultado se entrena cuando los episodios de entrenamiento incluyen al menos dos resultados distintos. La cabeza de la recompensa se entrena solo con el tramo en que el anotador dibujó la curva, porque fuera de ese tramo el anotador no dio ninguna respuesta. Los episodios de más de max_frames (2000) se entrenan con recortes aleatorios.
La predicción tiene la forma de una respuesta almacenada, con fases de la lista del esquema, uno de los resultados del esquema y una curva de recompensa de 50 puntos dentro de reward_range, para las capas que muestra el esquema. La predicción rellena de antemano la línea de tiempo y se almacena cuando el anotador edita la línea de tiempo. La causa del fallo y la instrucción quedan para el anotador. La puntuación principal sobre ítems reservados es la macro-F1 de fases sobre una cuadrícula de 0,1 segundos. La ejecución notifica también la F1 de segmentos de fase con IoU 0,5, la exactitud del resultado y la r de Pearson de la curva de recompensa donde se dibujó una curva. Un esquema sin fases toma como puntuación principal la exactitud del resultado y, después, la correlación de la recompensa. La ejecución necesita al menos 5 episodios anotados en la partición train. Potato no tiene un entrenador para rollout_evaluation, porque una preferencia entre despliegues compara vídeos y episode-model no lee vídeo.
Iniciar una ejecución y comprobar el resultado
Reinicia el servidor después de añadir model_training:
potato start config.yaml -p 8000Abre /admin/training, elige el esquema y el entrenador y pulsa Train now. La página ofrece solo los entrenadores que encajan con cada esquema, y un entrenador que no está instalado aparece como «not installed», con el comando de instalación. Cuando la ejecución termina, Potato lista la puntuación sobre ítems reservados en la tabla de ejecuciones, con la partición y la métrica en una información emergente. La página de la ejecución lista todas las métricas y la partición de cada ítem. El informe de escritura de vuelta de GET /admin/training/api/status cuenta las predicciones publicadas y las que retuvo cada comprobación, por ejemplo n_skipped_low_confidence.
Las preetiquetas condicionan a los anotadores hacia la respuesta del modelo, así que activa include_unlabeled en un estudio nuevo solo cuando la puntuación sobre ítems reservados justifique mostrar las respuestas del modelo. Revisa las preetiquetas del modelo en el bucle cubre cómo servir primero las preetiquetas de menor confianza y reentrenar con las correcciones, y Configuración lista todas las claves, los backends y las comprobaciones de la escritura de vuelta.
Más información
- Resumen del entrenamiento de modelos
- Todos los entrenadores
- Estructuras químicas, espectros y series temporales
- Anotación de episodios de robot y la guía de episodios de robot
- Potato para química, fisiología y robótica
- Etiquetado asistido por modelos
- Referencia upstream de
rdkit-property,peak-cnn,signal-cnnyepisode-model
Referencias
- Ismail Fawaz, H., Lucas, B., Forestier, G., Pelletier, C., Schmidt, D. F., Weber, J., Webb, G. I., Idoumghar, L., Muller, P.-A., and Petitjean, F. (2020). InceptionTime: Finding AlexNet for Time Series Classification. Data Mining and Knowledge Discovery, 34(6), 1936-1962. https://doi.org/10.1007/s10618-020-00710-y
- Rogers, D., and Hahn, M. (2010). Extended-Connectivity Fingerprints. Journal of Chemical Information and Modeling, 50(5), 742-754. https://doi.org/10.1021/ci100050t