En este post continuaremos trabajando en la predicción de enlaces con el conjunto de datos de Twitch. Nos centraremos en entrenar el modelo ML basado en redes neuronales de grafos (GNN) y optimizar sus hiperparámetros. A estas alturas ya tenemos los datos de grafos procesados y preparados para el entrenamiento del modelo. Los pasos anteriores se describen en la Parte 3: Procesamiento de datos, Parte 2: Exportación de datos desde la BD y Parte 1: Carga de datos en la BD.
Lea la parte 1 aquí ; la parte 2 aquí ; y la parte 3 aquí.
Usaremos redes neuronales convolucionales de grafos tal como lo hicimos en la publicación de predicción de enlaces locales y, aunque Neptune ML usa el mismo marco DGL.ai , el modelo subyacente es un poco diferente. Neptune ML admite tanto grafos de conocimiento (grafos homogéneos con un solo tipo de nodo y un solo tipo de borde) como grafos heterogéneos que tienen múltiples tipos de nodos y bordes. El conjunto de datos con el que estamos trabajando tiene un solo tipo de nodo (usuario) y un solo tipo de borde (amistad). Aunque un modelo de red convolucional de grafos (GCN) o un modelo de muestra y agregación de grafos (GraphSAGE) también funcionaría en este caso, Neptune ML elige automáticamente un modelo de red convolucional de grafos relacionales (R-GCN) para conjuntos de datos con propiedades de nodo que pueden variar de un nodo a otro, como se explica aquí . En general, las R-GCN requieren más cómputo para entrenarse debido a la mayor cantidad de parámetros necesarios para manejar múltiples tipos de nodos y bordes.
Durante la etapa de procesamiento de datos (que describimos en la publicación anterior TODO LINK), Neptune ML creó un archivo llamado model-hpo-configuration.json
. Contiene el tipo de modelo (R-GCN), el tipo de tarea (predicción de enlace), la métrica y frecuencia de evaluación y 4 listas de parámetros: una con parámetros fijos que no se modifican durante el entrenamiento y 3 listas de parámetros que se optimizarán, con rangos y valores predeterminados. Los parámetros se agrupan por importancia. Si se ajustan los parámetros de cada uno de los grupos se decide en función de la cantidad de trabajos de ajuste disponibles: los parámetros de primer nivel siempre se ajustan, los parámetros de segundo nivel se ajustan si la cantidad de trabajos disponibles es > 10 y los parámetros de tercer nivel se ajustan solo si es > 50. Nuestro archivo model-hpo-configuration.json
se ve así:
{ "models": [ { "model": "rgcn", "task_type": "link_predict", "eval_metric": { "metric": "mrr", "global_ranking_metrics": true, "include_retrieval_metrics": false }, "eval_frequency": { "type": "evaluate_every_pct", "value": 0.05 }, "1-tier-param": [ { "param": "num-hidden", "range": [16, 128], "type": "int", "inc_strategy": "power2" }, { "param": "num-epochs", "range": [3, 100], "inc_strategy": "linear", "inc_val": 1, "type": "int", "edge_strategy": "perM" }, { "param": "lr", "range": [0.001, 0.01], "type": "float", "inc_strategy": "log" }, { "param": "num-negs", "range": [4, 32], "type": "int", "inc_strategy": "power2" } ], "2-tier-param": [ { "param": "dropout", "range": [0.0, 0.5], "inc_strategy": "linear", "type": "float", "default": 0.3 }, { "param": "layer-norm", "type": "bool", "default": true }, { "param": "regularization-coef", "range": [0.0001, 0.01], "type": "float", "inc_strategy": "log", "default": 0.001 } ], "3-tier-param": [ { "param": "batch-size", "range": [128, 512], "inc_strategy": "power2", "type": "int", "default": 256 }, { "param": "sparse-lr", "range": [0.001, 0.01], "inc_strategy": "log", "type": "float", "default": 0.001 }, { "param": "fanout", "type": "int", "options": [[10, 30], [15, 30], [15, 30]], "default": [10, 15, 15] }, { "param": "num-layer", "range": [1, 3], "inc_strategy": "linear", "inc_val": 1, "type": "int", "default": 2 }, { "param": "num-bases", "range": [0, 8], "inc_strategy": "linear", "inc_val": 2, "type": "int", "default": 0 } ], "fixed-param": [ { "param": "neg-share", "type": "bool", "default": true }, { "param": "use-self-loop", "type": "bool", "default": true }, { "param": "low-mem", "type": "bool", "default": true }, { "param": "enable-early-stop", "type": "bool", "default": true }, { "param": "window-for-early-stop", "type": "bool", "default": 3 }, { "param": "concat-node-embed", "type": "bool", "default": true }, { "param": "per-feat-name-embed", "type": "bool", "default": true }, { "param": "use-edge-features", "type": "bool", "default": false }, { "param": "edge-num-hidden", "type": "int", "default": 16 }, { "param": "weighted-link-prediction", "type": "bool", "default": false }, { "param": "link-prediction-remove-targets", "type": "bool", "default": false }, { "param": "l2norm", "type": "float", "default": 0 } ] } ] }
Los parámetros del modelo y del tipo de tarea se establecieron durante las etapas de exportación y procesamiento de datos, y no deben modificarse aquí.
La métrica de evaluación también se eligió automáticamente. El rango recíproco medio (MRR) mide el rango promedio del enlace correcto en los resultados previstos; un MRR más alto indica un mejor rendimiento .
La frecuencia de evaluación se establece en el 5 % del progreso del entrenamiento. Por ejemplo, si tenemos 100 épocas, la evaluación se realizará cada 5 épocas.
Repasemos algunos de los hiperparámetros que se ajustarán:
lr : La tasa de aprendizaje es uno de los hiperparámetros más impactantes para el entrenamiento de cualquier modelo. Una tasa de aprendizaje más baja puede generar una convergencia más lenta, pero potencialmente un mejor rendimiento, mientras que una tasa de aprendizaje más alta puede acelerar el entrenamiento, pero podría dejar fuera soluciones óptimas.
num-hidden : el parámetro num-hidden hace referencia a la cantidad de unidades ocultas (neuronas) en cada capa de la red neuronal R-GCN, específicamente en las capas ocultas. Una mayor cantidad de unidades ocultas aumenta la capacidad del modelo para aprender patrones y relaciones complejos a partir de los datos, lo que puede mejorar la precisión de la predicción, pero también puede provocar un sobreajuste si el modelo se vuelve demasiado complejo para el conjunto de datos.
num-epochs : define durante cuánto tiempo se entrena el modelo. Más épocas permiten que el modelo aprenda más de los datos, pero pueden aumentar el riesgo de sobreajuste.
tamaño del lote : el tamaño del lote afecta el uso de la memoria y la estabilidad de la convergencia. Un tamaño de lote más pequeño puede hacer que el modelo sea más sensible a los datos, mientras que un tamaño de lote más grande puede mejorar la velocidad de entrenamiento.
num-negs : el muestreo negativo afecta la manera en que el modelo aprende a distinguir los vínculos verdaderos de los falsos. Una mayor cantidad de muestras negativas puede mejorar la calidad de las predicciones, pero aumenta los costos computacionales.
Dropout : el dropout ayuda a prevenir el sobreajuste al omitir aleatoriamente algunas neuronas durante el entrenamiento. Una tasa de abandono más alta puede reducir el sobreajuste, pero podría dificultar el aprendizaje del modelo.
coeficiente-de-regulación : Regularización que tiene como objetivo evitar que el modelo se sobreajuste.
Puede cambiar los valores predeterminados, el rango y el tamaño del paso para cada uno de estos parámetros. La lista completa de parámetros se puede encontrar aquí .
Después de cambiar los parámetros, simplemente reemplace el archivo original model-hpo-configuration.json
en S3.
Al igual que el procesamiento de datos descrito en la Parte 3 de esta guía, el entrenamiento de modelos requiere dos roles de IAM: un rol de Neptune que proporciona acceso de Neptune a SageMaker y S3, y un rol de ejecución de SageMaker que SageMaker utiliza mientras ejecuta la tarea de procesamiento de datos y le permite acceder a S3. Estos roles deben tener políticas de confianza que permitan que los servicios de Neptune y SageMaker las asuman:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "sagemaker.amazonaws.com" }, "Action": "sts:AssumeRole" }, { "Sid": "", "Effect": "Allow", "Principal": { "Service": "rds.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
Después de crear los roles y actualizar sus políticas de confianza, los agregamos al clúster Neptune (Neptune -> Bases de datos -> YOUR_NEPTUNE_CLUSTER_ID -> Conectividad y seguridad -> Roles de IAM -> Agregar rol).
Ahora estamos listos para comenzar el entrenamiento del modelo. Para ello, debemos enviar una solicitud a la API HTTP del clúster de Neptune desde dentro de la VPC donde se encuentra el clúster. Usaremos curl en una instancia de EC2:
curl -XPOST https://(YOUR_NEPTUNE_ENDPOINT):8182/ml/modeltraining \ -H 'Content-Type: application/json' \ -d '{ "dataProcessingJobId" : "ID_OF_YOUR_DATAPROCESSING_JOB", "trainModelS3Location" : "s3://OUTPUT_BUCKET/model-artifacts/...", "neptuneIamRoleArn": "arn:aws:iam::123456789012:role/NeptuneMLModelTrainingNeptuneRole", "sagemakerIamRoleArn": "arn:aws:iam::123456789012:role/NeptuneMLModelTrainingSagemakerRole" }'
Solo se requieren estos parámetros:
También existe el parámetro maxHPONumberOfTrainingJobs , que establece la cantidad de trabajos de entrenamiento que se ejecutarán con diferentes conjuntos de hiperparámetros. De manera predeterminada, son 2, pero AWS recomienda ejecutar al menos 10 trabajos para obtener un modelo preciso.
También hay muchos parámetros opcionales: por ejemplo, podemos seleccionar manualmente el tipo de instancia EC2 que se usará para el entrenamiento del modelo con trainingInstanceType y establecer el tamaño del volumen de almacenamiento con trainingInstanceVolumeSizeInGB . La lista completa de parámetros se puede encontrar aquí .
El clúster responde con un JSON que contiene el ID del trabajo de procesamiento de datos que acabamos de crear:
{"id":"d584f5bc-d90e-4957-be01-523e07a7562e"}
Podemos usarlo para obtener el estado del trabajo de entrenamiento del modelo con este comando (use el mismo neptuneIamRoleArn que en la solicitud anterior):
curl https://YOUR_NEPTUNE_CLUSTER_ENDPOINT:8182/ml/modeltraining/YOUR_JOB_ID?neptuneIamRoleArn='arn:aws:iam::123456789012:role/NeptuneMLModelTrainingNeptuneRole'
Una vez que responde con algo como esto,
{ "processingJob": { "name": "PROCESSING_JOB_NAME", "arn": "arn:aws:sagemaker:us-east-1:123456789012:processing-job/YOUR_PROCESSING_JOB_NAME", "status": "Completed", "outputLocation": "s3://OUTPUT_BUCKET/model-artifacts/PROCESSING_JOB_NAME/autotrainer-output" }, "hpoJob": { "name": "HPO_JOB_NAME", "arn": "arn:aws:sagemaker:us-east-1:123456789012:hyper-parameter-tuning-job/HPO_JOB_NAME", "status": "Completed" }, "mlModels": [ { "name": "MODEL_NAME-cpu", "arn": "arn:aws:sagemaker:us-east-1:123456789012:model/MODEL_NAME-cpu" } ], "id": "d584f5bc-d90e-4957-be01-523e07a7562e", "status": "Completed" }
Podemos verificar los registros de entrenamiento y los artefactos en el depósito S3 de destino.
El entrenamiento del modelo se ha completado, así que verifiquemos los resultados en la consola de AWS: SageMaker -> Entrenamiento -> Trabajos de entrenamiento.
Para simplificar, no cambiamos la cantidad de trabajos de HPO cuando comenzamos el entrenamiento del modelo y se utilizó el valor predeterminado de 2. Los 2 trabajos se ejecutaron en paralelo. El tipo de instancia se seleccionó automáticamente: ml.g4dn.2xlarge .
El primer trabajo (el que tiene '001' en su nombre) se completó en 15 minutos, y el segundo ('002') se detuvo automáticamente, ya que SageMaker admite la detención anticipada si las métricas de entrenamiento no mejoran durante un tiempo:
Comparemos los hiperparámetros que se utilizaron en estos trabajos:
Solo 3 parámetros tienen valores diferentes: num-hidden, num-negs y lr . El segundo modelo (entrenado con Job 2) tuvo una tasa de aprendizaje más alta, pero con menor capacidad para capturar patrones complejos (porque tenía menos neuronas) y se entrenó con menos muestras negativas. Esto condujo a una precisión significativamente menor, como podemos ver en el rango medio de validación (115 frente a 23) y en HITS@K :
El rango medio (MR) es la posición promedio del enlace correcto entre las predicciones. Los valores de MR más bajos son mejores porque indican que el enlace correcto está, en promedio, clasificado más cerca de la parte superior .
Las métricas HITS@K miden la proporción de veces que aparece el enlace correcto en los K principales resultados previstos.
Cuando se finalizan los trabajos de entrenamiento, se crean artefactos del modelo en el depósito S3 de salida, junto con archivos que contienen estadísticas y métricas de entrenamiento:
Las métricas y los parámetros de estos archivos JSON son los que mencionamos anteriormente. Solo el directorio 001 contiene el subdirectorio 'output' con el archivo model.tar.gz, ya que es el único trabajo de HPO que se completó. Los artefactos para la predicción de enlaces también contienen los datos del gráfico DGL, ya que son necesarios para realizar predicciones reales, como se explica aquí .
Estos archivos se utilizarán para crear un punto final de inferencia y generar predicciones de enlaces reales. Esto se analizará en la próxima y última publicación de esta serie.