在这篇文章中,我们将继续使用 Twitch 数据集进行链接预测。我们将重点关注基于图神经网络 (GNN) 训练 ML 模型并优化其超参数。到目前为止,我们已经处理了图数据并准备好进行模型训练。前面的步骤在第 3 部分 - 数据处理、第 2 部分 - 从数据库导出数据和第 1 部分 - 将数据加载到数据库中进行了描述。
点击此处阅读第 1 部分;点击此处阅读第 2 部分;点击此处阅读第 3 部分。
我们将使用图卷积神经网络,就像我们在本地链接预测帖子中所做的那样,尽管 Neptune ML 使用相同的DGL.ai框架,但底层模型略有不同。Neptune ML 同时支持知识图谱(具有单一节点类型和单一边缘类型的同构图)和具有多种节点和边缘类型的异构图。我们正在处理的数据集具有单一节点类型(用户)和单一边缘类型(友谊)。虽然图卷积网络 (GCN) 或图样本和聚合 (GraphSAGE) 模型在这种情况下也可以工作,但 Neptune ML 会自动为节点属性可能因节点而异的数据集选择关系图卷积网络 (R-GCN) 模型, 如下所述。通常,由于处理多种节点和边缘类型所需的参数数量增加,因此 R-GCN 需要更多的计算来训练。
在数据处理阶段(我们在上一篇文章 TODO LINK 中描述过),Neptune ML 创建了一个名为model-hpo-configuration.json
文件。它包含模型类型(R-GCN)、任务类型(链接预测)、评估指标和频率以及 4 个参数列表:一个列表包含训练期间不会修改的固定参数,3 个列表包含要优化的参数,包括范围和默认值。参数按重要性分组。是否调整每个组中的参数取决于可用的调整作业数量:始终调整第 1 层参数,如果可用作业数量 > 10,则调整第 2 层参数,只有当作业数量 > 50 时,才调整第 3 层参数。我们的model-hpo-configuration.json
文件如下所示:
{ "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 } ] } ] }
模型和任务类型参数是在数据导出和处理阶段设置的,不应在此处更改。
评估指标也是自动选择的。平均倒数排名 (MRR)衡量预测结果中正确链接的平均排名, MRR 越高,表示性能越好。
评估频率设置为训练进度的 5%。例如,如果我们有 100 个 epoch,则每 5 个 epoch 进行一次评估。
让我们回顾一下一些需要调整的超参数:
lr :学习率是任何模型训练中影响最大的超参数之一。较低的学习率可能导致收敛速度较慢但可能带来更好的性能,而较高的学习率可以加快训练速度但可能会错过最佳解决方案。
num-hidden :num-hidden 参数是指 R-GCN 神经网络每层(具体指隐藏层)的隐藏单元(神经元)数量。隐藏单元数量越多,模型从数据中学习复杂模式和关系的能力就越强,这可以提高预测准确性,但如果模型对于数据集来说过于复杂,也可能导致过度拟合。
num-epochs :这定义了模型的训练时间。更多的 epochs 允许模型从数据中学习更多,但可能会增加过度拟合的风险。
batch-size :batch 大小会影响内存使用量和收敛稳定性。较小的 batch 大小可能会使模型对数据更敏感,而较大的 batch 大小可能会提高训练速度。
num-negs :负采样会影响模型如何学习区分真实链接和虚假链接。负样本数量越多可能会提高预测质量,但会增加计算成本。
dropout :Dropout 通过在训练期间随机跳过一些神经元来帮助防止过度拟合。较高的 dropout 率可能会减少过度拟合,但可能会使模型的学习更加困难。
正则化系数:正则化旨在防止模型过度拟合。
您可以更改每个参数的默认值、范围和步长。完整的参数列表可在此处找到。
更改参数后只需替换S3中原来的model-hpo-configuration.json
文件即可。
与本指南第 3 部分中描述的数据处理一样,模型训练需要 2 个 IAM 角色:一个 Neptune 角色,为 Neptune 提供对 SageMaker 和 S3 的访问权限;一个 Sagemaker 执行角色,供 SageMaker 在运行数据处理任务时使用并允许其访问 S3。这些角色必须具有允许 Neptune 和 SageMaker 服务代入它们的信任策略:
{ "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" } ] }
创建角色并更新其信任策略后,我们将它们添加到 Neptune 集群(Neptune -> 数据库 -> YOUR_NEPTUNE_CLUSTER_ID -> 连接和安全 -> IAM 角色 -> 添加角色)。
现在我们准备开始模型训练。为此,我们需要从集群所在的 VPC 内部向 Neptune 集群的 HTTP API 发送请求。我们将在 EC2 实例上使用 curl:
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" }'
仅需要以下参数:
还有maxHPONumberOfTrainingJobs参数,用于设置使用不同超参数集运行的训练作业数量。默认情况下,它是 2,但AWS 建议至少运行 10 个作业以获得准确的模型。
还有许多可选参数:例如,我们可以使用trainingInstanceType手动选择用于模型训练的 EC2 实例类型,并使用trainingInstanceVolumeSizeInGB设置其存储卷大小。完整的参数列表可在此处找到。
集群以 JSON 进行响应,其中包含我们刚刚创建的数据处理作业的 ID:
{"id":"d584f5bc-d90e-4957-be01-523e07a7562e"}
我们可以使用它通过这个命令获取模型训练作业的状态(使用与上一个请求相同的neptuneIamRoleArn ):
curl https://YOUR_NEPTUNE_CLUSTER_ENDPOINT:8182/ml/modeltraining/YOUR_JOB_ID?neptuneIamRoleArn='arn:aws:iam::123456789012:role/NeptuneMLModelTrainingNeptuneRole'
一旦它回应了类似这样的内容,
{ "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" }
我们可以检查目标 S3 存储桶中的训练日志和工件。
模型训练已经完成,让我们在 AWS 控制台中检查结果:SageMaker -> 训练 -> 训练作业。
为简单起见,我们在开始模型训练时没有更改 HPO 作业的数量,而是使用默认值 2。这 2 个作业并行运行。实例类型是自动选择的: ml.g4dn.2xlarge 。
第一项作业(名称中带有“001”的作业)在 15 分钟内完成,第二项作业(“002”)自动停止,因为如果训练指标在一段时间内没有改善,SageMaker 支持提前停止:
让我们比较一下这些作业中使用的超参数:
只有 3 个参数具有不同的值: num-hidden、num-negs 和 lr 。第二个模型(使用作业 2 训练)具有更高的学习率,但捕捉复杂模式的能力较弱(因为它的神经元较少),并且是在较少的负样本上进行训练的。从验证平均等级(115 vs 23)和 HITS@K可以看出,这导致准确率明显降低:
平均排名 (MR)是正确链接在预测中的平均排名位置。MR值越低越好,因为它们表示正确链接的平均排名越接近顶部。
HITS@K 指标衡量正确链接在前 K 个预测结果中出现的次数比例。
训练作业完成后,将在输出 S3 存储桶中创建模型工件,以及包含训练统计数据和指标的文件:
这些 JSON 文件中的指标和参数是我们之前提到的。只有 001 目录包含带有 model.tar.gz 文件的“output”子目录,因为它是唯一完成的 HPO 作业。链接预测的工件还包含 DGL 图形数据,因为它是进行实际预测所必需的,如此处所述。
这些文件将用于创建推理端点并生成实际的链接预测。这将在本系列的下一篇也是最后一篇文章中讨论。