如何处理用于Tensorflow服务批处理转换的.csv输入?

如何处理用于Tensorflow服务批处理转换的.csv输入?,csv,amazon-s3,tensorflow-serving,amazon-sagemaker,Csv,Amazon S3,Tensorflow Serving,Amazon Sagemaker,信息: 我正在从一个S3 bucket加载一个现有的训练有素的model.tar.gz,并希望使用包含输入数据的.csv执行批处理转换。data.csv的结构是这样的,将其读入pandas数据框可以为我提供一行完整的预测输入 笔记: 这是使用Python SDK在Amazon Sagemaker上完成的 BATCH_TRANSFORM_输入是指向data.csv的路径 我能够加载model.tar.gz中的内容,并使用tensorflow在本地机器上进行推理,日志显示2020-08-04 13

信息: 我正在从一个S3 bucket加载一个现有的训练有素的model.tar.gz,并希望使用包含输入数据的.csv执行批处理转换。data.csv的结构是这样的,将其读入pandas数据框可以为我提供一行完整的预测输入

笔记:
  • 这是使用Python SDK在Amazon Sagemaker上完成的
  • BATCH_TRANSFORM_输入是指向data.csv的路径
  • 我能够加载model.tar.gz中的内容,并使用tensorflow在本地机器上进行推理,日志显示
    2020-08-04 13:35:01.123557:I tensorflow_serving/core/loader_harness.cc:87]成功加载了可服务版本{name:model version:1}
    因此,该模型似乎已经过适当的培训和保存
  • data.csv与培训数据的格式完全相同,这意味着每“预测”一行,其中该行中的所有列表示不同的特征
  • 将参数策略更改为“MultiRecord”会产生相同的错误
  • [path in s3]是真实路径的替代品,因为我不想透露任何bucket信息
  • TensorFlow模型服务器:2.0.0+dev.sha.ab786af
  • TensorFlow库:2.0.2
其中1-5是功能,文件data.csv如下所示:

+------+-------------------------+---------+----------+---------+----------+----------+
| UNIT | TS                      | 1       | 2        | 3       | 4        | 5        |
+------+-------------------------+---------+----------+---------+----------+----------+
| 110  | 2018-01-01 00:01:00.000 | 1.81766 | 0.178043 | 1.33607 | 25.42162 | 12.85445 |
+------+-------------------------+---------+----------+---------+----------+----------+
| 110  | 2018-01-01 00:02:00.000 | 1.81673 | 0.178168 | 1.30159 | 25.48204 | 12.87305 |
+------+-------------------------+---------+----------+---------+----------+----------+
| 110  | 2018-01-01 00:03:00.000 | 1.8155  | 0.176242 | 1.38399 | 25.35309 | 12.47222 |
+------+-------------------------+---------+----------+---------+----------+----------+
| 110  | 2018-01-01 00:04:00.000 | 1.81530 | 0.176398 | 1.39781 | 25.18216 | 12.16837 |
+------+-------------------------+---------+----------+---------+----------+----------+
| 110  | 2018-01-01 00:05:00.000 | 1.81505 | 0.151682 | 1.38451 | 25.22351 | 12.41623 |
+------+-------------------------+---------+----------+---------+----------+----------+
def input_handler(data, context):
    import pandas as pd
    if context.request_content_type == 'text/csv':
        payload = pd.read_csv(data)
        instance = [{"dataset": payload}]
        return json.dumps({"instances": instance})
    else:
        _return_error(416, 'Unsupported content type "{}"'.format(context.request_content_type or 'Unknown'))
inference.py当前看起来像:

+------+-------------------------+---------+----------+---------+----------+----------+
| UNIT | TS                      | 1       | 2        | 3       | 4        | 5        |
+------+-------------------------+---------+----------+---------+----------+----------+
| 110  | 2018-01-01 00:01:00.000 | 1.81766 | 0.178043 | 1.33607 | 25.42162 | 12.85445 |
+------+-------------------------+---------+----------+---------+----------+----------+
| 110  | 2018-01-01 00:02:00.000 | 1.81673 | 0.178168 | 1.30159 | 25.48204 | 12.87305 |
+------+-------------------------+---------+----------+---------+----------+----------+
| 110  | 2018-01-01 00:03:00.000 | 1.8155  | 0.176242 | 1.38399 | 25.35309 | 12.47222 |
+------+-------------------------+---------+----------+---------+----------+----------+
| 110  | 2018-01-01 00:04:00.000 | 1.81530 | 0.176398 | 1.39781 | 25.18216 | 12.16837 |
+------+-------------------------+---------+----------+---------+----------+----------+
| 110  | 2018-01-01 00:05:00.000 | 1.81505 | 0.151682 | 1.38451 | 25.22351 | 12.41623 |
+------+-------------------------+---------+----------+---------+----------+----------+
def input_handler(data, context):
    import pandas as pd
    if context.request_content_type == 'text/csv':
        payload = pd.read_csv(data)
        instance = [{"dataset": payload}]
        return json.dumps({"instances": instance})
    else:
        _return_error(416, 'Unsupported content type "{}"'.format(context.request_content_type or 'Unknown'))
问题是: 当以下代码在我的jupyter笔记本中运行时:

sagemaker_model = Model(model_data = '[path in s3]/savedmodel/model.tar.gz'),  
                        sagemaker_session=sagemaker_session,
                        role = role,
                        framework_version='2.0',
                        entry_point = os.path.join('training', 'inference.py')
                        )

tf_serving_transformer = sagemaker_model.transformer(instance_count=1,
                                                     instance_type='ml.p2.xlarge',
                                                     max_payload=1,
                                                     output_path=BATCH_TRANSFORM_OUTPUT_DIR,
                                                     strategy='SingleRecord')


tf_serving_transformer.transform(data=BATCH_TRANSFORM_INPUT, data_type='S3Prefix', content_type='text/csv')
tf_serving_transformer.wait()
该模型似乎已加载,但最终出现以下错误:
2020-08-04T09:54:27.415:[sagemaker日志]:MaxConcurrentTransforms=1,MaxPayloadInMB=1,BatchStrategy=SINGLE_RECORD 2020-08-04T09:54:27.503:[sagemaker日志]:[s3中的路径]/data.csv:2020-08-04T09:54:27:27.503:[sagemaker日志]:[s3中的路径]/data.csv:Message:2020-08-04T09:54:27.503:[sagemaker日志]:[s3中的路径]/data.csv:{“错误”:“未能处理元素:0个‘实例’列表。错误:无效参数:JSON值:\“\”类型:字符串不是预期的类型:float”}

错误更清楚:

客户错误:400 消息:{“错误”:“未能处理“实例”列表的元素:0。错误:无效参数:JSON值:”“类型:字符串不是预期的类型:float”}

如果我正确理解了这个错误,那么我的数据结构就有问题,因此sagemaker无法将输入数据传递到TFS模型。我想我的inference.py中缺少一些“输入处理”。也许csv数据必须以某种方式转换为兼容的JSON,TFS才能使用它?在input_handler()中到底需要做什么


我感谢所有的帮助,并为这个令人困惑的案件感到抱歉。如果需要任何其他信息,请询问,我很乐意提供我所能提供的。

解决方案:通过使用参数header=False、index=False将数据帧保存为.csv解决了问题。这使得保存的csv不包括数据帧索引标签。TFS接受一个只有浮点值(没有标签)的干净的.csv。我假设错误消息参数无效:JSON值:“”类型:字符串不是预期的类型:float指csv中的第一个单元格,如果csv与标签一起导出,则该单元格仅为空单元格。当它得到一个空字符串而不是一个浮点值时,它会感到困惑。

您的模型在训练之前是否执行了任何预处理?如果是这样,则需要相应地转换数据。AWS有一个名为
推理管道
的系统,您可以将预处理模型和学习模型结合在一起。在将数据帧导出为.csv之前,我们在熊猫数据帧中进行了一些预处理。通过使用参数header=False、index=False将数据帧保存为.csv,问题刚刚得到解决。TFS被输入数据结构搞糊涂了。感谢您的关注,这很有意义<代码>sagemaker要求csv输入不带标题