为何无法在SageMaker Pipeline中访问TensorFlow Estimator训练指标?
问题
我创建了一个自定义TensorFlow 2模型,为在SageMaker Pipeline中训练该模型,我创建了一个Estimator并定义了训练模型的验证二分类准确率指标:
estimator = TensorFlow(entry_point=code_entry, source_dir=code_dir, role=sagemaker_role, instance_type='local', instance_count=1, model_dir='s3://some-bucket/model/', hyperparameters=hyperparameters, output_path='s3://some-bucket/results/', framework_version='2.8', py_version='py39', metric_definitions=[ { "Name": "binary_accuracy", "Regex": "val_binary_accuracy=(\\d+\\.\\d+)?", } ], script_mode=True)
根据SageMaker Estimator文档说明,设置指标定义后,SageMaker会通过正则表达式从训练日志中提取指标:
metric_definitions (list[dict[str, str] or list[dict[str, PipelineVariable]]) – 用于评估训练作业的指标定义字典列表。每个字典包含两个键:‘Name’为指标名称,‘Regex’为从日志中提取指标的正则表达式。
训练后的模型指标会存储在训练作业属性的FinalMetricDataList对象中。
我在训练日志中可以看到匹配Estimator指标定义正则的日志:
2wn9x0rkaf-algo-1-43gci | INFO:root:val_binary_accuracy=0.5
但尝试通过以下代码访问该指标时:
step_training.properties.FinalMetricDataList['binary_accuracy'].Value
在检查指标是否高于阈值的条件步骤中出现错误:
Pipeline step 'CheckAccuracyEvaluation' FAILED. Failure message is: {"Get": "Steps.TrainingStep.FinalMetricDataList['binary_accuracy'].Value"} is undefined.
请问我哪里操作有误?如何在脚本模式下通过SageMaker Estimator获取训练模型的指标?
解决方案
错误核心
FinalMetricDataList是列表类型,不是字典,无法直接通过指标名称(如'binary_accuracy')作为键来访问。它的结构是包含多个字典元素的列表,每个元素包含MetricName、Value等字段。
正确访问方式
推荐方式:使用JsonGet工具
SageMaker Pipeline提供的JsonGet支持通过JSONPath语法从嵌套结构中精准提取指标值,无需依赖列表顺序:
from sagemaker.workflow.functions import JsonGet # 提取MetricName为binary_accuracy的指标值 accuracy_metric = JsonGet( step_name="TrainingStep", # 替换为你的训练步骤名称 property_name="FinalMetricDataList", json_path="[?(@.MetricName=='binary_accuracy')].Value" ) # 在条件判断中直接使用该变量 accuracy_condition = accuracy_metric > 0.6 # 替换为你的阈值
备选方式:列表索引访问(不推荐)
如果能确定binary_accuracy是FinalMetricDataList中的第一个指标,可以直接用索引访问,但这种方式依赖指标顺序,后续指标定义调整后会出错:
step_training.properties.FinalMetricDataList[0].Value
额外验证点
- 确认训练日志的指标输出完全匹配
metric_definitions中的正则表达式:你的正则val_binary_accuracy=(\\d+\\.\\d+)?可以正确匹配val_binary_accuracy=0.5,这部分无问题。 - 确保训练作业成功完成:只有成功的训练作业才会生成有效的
FinalMetricDataList。
内容的提问来源于stack exchange,提问作者theeDude

