使用Amazon SageMaker在自定义数据集上实现多目标跟踪解决方案

多目标跟踪(MOT)在视频分析中的需求在许多行业中显著增加,例如现场体育、制造业和交通监控。例如,在现场体育比赛中,MOT可以实时跟踪足球运动员,分析实时速度和移动距离等身体表现。

自2021年推出以来,ByteTrack仍然是MOT应用中各种基准数据集上表现最佳的方法之一。在ByteTrack中,作者提出了一种简单、有效和通用的数据关联方法(称为BYTE)进行检测框和轨迹匹配。它不仅保留高分检测框,还保留低分检测框,这可以在发生遮挡、运动模糊或大小变化时帮助恢复未匹配的轨迹。BYTE关联策略也可以用于其他基于Re-ID的跟踪器,如FairMOT。实验表明,与普通跟踪器算法相比,其有所改善。例如,FairMOT在应用BYTE进行数据关联时,在MOTA(多目标跟踪中的主要指标之一)上取得了1.3%的改进(FairMOT:多目标跟踪中检测和重新识别的公平性)。

在博客文章“使用Amazon SageMaker训练和部署FairMOT模型”中,我们演示了如何在MOT挑战数据集上使用Amazon SageMaker训练和部署FairMOT模型。在实际案例中应用MOT解决方案时,您需要在自定义数据集上训练或微调MOT模型。使用Amazon SageMaker Ground Truth,您可以有效地在自己的视频数据集上创建标签。

在上一篇博客文章的基础上,我们增加了以下贡献和修改:

  • 使用Ground Truth为自定义视频数据集生成标签
  • 预处理Ground Truth生成的标签,以与ByteTrack和其他MOT解决方案兼容
  • 使用SageMaker训练作业训练ByteTrack算法(使用扩展预构建容器的选项)
  • 使用各种部署选项部署训练后的模型,包括异步推理

我们还在GitHub上提供了代码示例,该示例使用SageMaker进行标注、构建、训练和推理。

SageMaker是一项完全托管的服务,为每个开发人员和数据科学家提供了快速准备、构建、训练和部署机器学习(ML)模型的能力。SageMaker提供几种内置算法和容器映像,您可以使用它们来加速ML模型的训练和部署。此外,像ByteTrack这样的自定义算法也可以通过自定义构建的Docker容器映像进行支持。有关在容器中决定正确的参与级别的更多信息,请参阅“使用Docker容器进行SageMaker”。

SageMaker提供了许多模型部署选项,例如实时推理、无服务器推理和异步推理。在本文中,我们展示了如何使用不同的部署选项部署跟踪模型,以便您可以选择适合自己用例的合适部署方法。

解决方案概述

我们的解决方案包括以下高级步骤:

  1. 对跟踪数据集进行标注,每个对象(例如行人、汽车等)都有一个边界框。设置ML代码开发和执行的资源。
  2. 在自定义数据集上训练ByteTrack模型并调整超参数。
  3. 使用不同的部署选项部署已训练的ByteTrack模型,具体取决于您的用例:实时处理、异步或批量预测。

以下图表说明了每个步骤中的体系结构。

先决条件

开始之前,请完成以下先决条件:

  1. 创建一个AWS账户或使用现有的AWS账户。
  2. 我们建议在us-east-1区域中运行源代码。
  3. 确保您至少有一个GPU实例(例如单GPU训练的ml.p3.2xlargeml.p3.16xlarge)用于分布式训练作业。还支持其他类型的GPU实例,具有不同的性能差异。
  4. 确保您至少有一个GPU实例(例如ml.p3.2xlarge)用于推理端点。
  5. 确保您至少有一个GPU实例(例如ml.p3.2xlarge)用于运行批量预测处理作业。

如果您是首次在上述实例类型上运行SageMaker服务,则可能需要请求增加所需实例的配额。

设置您的资源

完成所有先决条件后,您就可以部署解决方案了。

  1. 创建一个SageMaker笔记本实例。对于此任务,我们建议使用ml.t3.medium实例类型。在运行代码时,我们使用docker build来扩展SageMaker训练镜像与ByteTrack代码(docker build命令将在笔记本实例环境内本地运行)。因此,我们建议从高级配置选项中将卷大小增加到100 GB(默认卷大小为5 GB)。对于您的AWS身份和访问管理(IAM)角色,请选择现有角色或创建新角色,并将AmazonS3FullAccessAmazonSNSFullAccessAmazonSageMakerFullAccessAmazonElasticContainerRegistryPublicFullAccess策略附加到角色上。
  2. 将GitHub repo克隆到您创建的笔记本实例上的/home/ec2-user/SageMaker文件夹中。
  3. 创建一个新的Amazon简单存储服务(Amazon S3)存储桶或使用现有存储桶。

标记数据集

在数据准备.ipynb笔记本中,我们下载了一个MOT16测试视频文件,并将视频文件拆分成有200帧的小视频文件。然后,我们将这些视频文件上传到S3存储桶作为标记的数据源。

要为MOT任务标记数据集,请参阅开始。当标记作业完成后,我们可以在S3存储桶中的作业输出位置访问以下注释目录。

如果我们完成了所有文件的标记,则manifests目录应包含一个output文件夹。我们可以在output文件夹中看到文件output.manifest。此清单文件包含有关视频和视频跟踪标签的信息,您可以稍后用它们来训练和测试模型。

在自定义数据集上训练ByteTrack模型并调整超参数

要训练您的ByteTrack模型,我们使用bytetrack-training.ipynb笔记本。笔记本包括以下步骤:

  1. 初始化SageMaker设置。
  2. 执行数据预处理。
  3. 构建并推送容器镜像。
  4. 定义训练作业。
  5. 启动训练作业。
  6. 调整超参数。

特别是在数据预处理中,我们需要将具有Ground Truth输出格式的标记数据集转换为MOT17格式数据集,并将MOT17格式数据集转换为MSCOCO格式数据集(如下图所示),以便我们可以在自定义数据集上训练YOLOX模型。因为我们保留了MOT格式数据集和MSCOCO格式数据集,所以您可以在MOT格式数据集上训练其他MOT算法,而无需将检测和跟踪分开。您可以轻松更改检测器以使用其他算法,例如YOLO7,以使用现有的对象检测算法。

部署训练的ByteTrack模型

在训练YOLOX模型后,我们将训练的模型部署用于推理。SageMaker提供了多种模型部署选项,例如实时推理,异步推理,无服务器推理和批量推理。在我们的文章中,我们使用了实时推理、异步推理和批量推理的示例代码。您可以根据自己的业务需求从这些选项中选择适合的代码。

因为SageMaker批量转换需要将数据分区并存储在Amazon S3上作为输入,同时将调用并发地发送到推理端点,它不满足目标跟踪任务中需要以顺序方式发送目标的要求。因此,我们不使用SageMaker批量转换作业来运行批量推理。在这个例子中,我们使用SageMaker处理作业来进行批量推理。

下表总结了我们推理作业的配置。

推理类型 负载 处理时间 自动扩展
实时 高达6 MB 高达1分钟 最小实例计数为1或更高
异步 高达1 GB 高达15分钟 最小实例计数可以为零
批处理(带处理作业) 无限制 无限制 不支持

部署实时推理端点

要部署实时推理端点,我们可以运行bytetrack-inference-yolox.ipynb笔记本。我们将ByteTrack推理分为目标检测和跟踪。在推理端点中,我们仅运行目标检测的YOLOX模型。在笔记本中,我们创建一个跟踪对象,接收来自推理端点的目标检测结果,并更新跟踪器。

我们使用SageMaker PyTorchModel SDK创建和部署ByteTrack模型,如下所示:

from sagemaker.pytorch.model import PyTorchModel
 
pytorch_model = PyTorchModel(
    model_data=s3_model_uri,
    role=role,
    source_dir="sagemaker-serving/code",
    entry_point="inference.py",
    framework_version="1.7.1",
    py_version="py3",
)
 
endpoint_name =<endpint name>
pytorch_model.deploy(
    initial_instance_count=1,
    instance_type="ml.p3.2xlarge",
    endpoint_name=endpoint_name
)

成功部署模型到端点后,我们可以使用以下代码片段调用推理端点:

with open(f"datasets/frame_{frame_id}.png", "rb") as f:
    payload = f.read()

response = sm_runtime.invoke_endpoint(
    EndpointName=endpoint_name, ContentType="application/x-image", Body=payload
)
outputs = json.loads(response["Body"].read().decode())

我们在接受来自端点的检测结果后在客户端上运行跟踪任务(请参见以下代码)。通过在每个帧中绘制跟踪结果并保存为跟踪视频,您可以确认跟踪结果。

aspect_ratio_thresh = 1.6
min_box_area = 10
tracker = BYTETracker(
        frame_rate=30,
        track_thresh=0.5,
        track_buffer=30,
        mot20=False,
        match_thresh=0.8
    )

online_targets = tracker.update(torch.as_tensor(outputs[0]), [height, width], (800, 1440))
online_tlwhs = []
online_ids = []
online_scores = []
for t in online_targets:
    tlwh = t.tlwh
    tid = t.track_id
    vertical = tlwh[2] / tlwh[3] > aspect_ratio_thresh
    if tlwh[2] * tlwh[3] > min_box_area and not vertical:
        online_tlwhs.append(tlwh)
        online_ids.append(tid)
        online_scores.append(t.score)
        results.append(
            f"{frame_id},{tid},{tlwh[0]:.2f},{tlwh[1]:.2f},{tlwh[2]:.2f},{tlwh[3]:.2f},{t.score:.2f},-1,-1,-1\n"
        )
online_im = plot_tracking(
    frame, online_tlwhs, online_ids, frame_id=frame_id + 1, fps=1. / timer.average_time
)

部署异步推断端点

SageMaker异步推断是处理请求大小大(高达1 GB)、处理时间长(高达1小时)和近实时延迟要求的理想选择。对于MOT任务,通常视频文件超过6 MB,这是实时端点的负载限制。因此,我们部署异步推断端点。请参阅异步推断以获取有关如何部署异步端点的更多详细信息。我们可以重用为实时端点创建的模型;对于本文,我们将跟踪过程放入推断脚本中,以便我们可以直接获得输入视频的最终跟踪结果。

为了在端点上使用与ByteTrack相关的脚本,我们需要将跟踪脚本和模型放入同一文件夹中,并将该文件夹压缩为 model.tar.gz 文件,然后上传到用于模型创建的S3存储桶中。下图显示了 model.tar.gz 的结构。

我们需要显式设置请求大小、响应大小和响应超时作为环境变量,如下面的代码所示。环境变量的名称因框架而异。有关更多详细信息,请参阅创建异步推断端点。

pytorch_model = PyTorchModel(
    model_data=s3_model_uri,
    role=role,
    entry_point="inference.py",
    framework_version="1.7.1",
    sagemaker_session=sm_session,
    py_version="py3",
    env={
        'TS_MAX_REQUEST_SIZE': '1000000000', #default max request size is 6 Mb for torchserve, need to update it to support the 1GB input payload
        'TS_MAX_RESPONSE_SIZE': '1000000000',
        'TS_DEFAULT_RESPONSE_TIMEOUT': '900' # max timeout is 15mins (900 seconds)
    }
)

pytorch_model.create(
    instance_type="ml.p3.2xlarge",
)

当调用异步端点时,我们不是在请求中发送负载,而是发送输入视频的Amazon S3 URL。当模型推断完成处理视频后,结果将保存在S3输出路径上。我们可以配置Amazon Simple Notification Service (Amazon SNS)主题,以便在结果准备好时,我们可以收到作为通知的SNS消息。

使用SageMaker处理进行批处理推断

对于大于1 GB的视频文件,我们使用SageMaker处理作业进行批处理推断。我们定义了自定义的Docker容器来运行SageMaker处理作业(请参见下面的代码)。我们在输入视频上绘制跟踪结果。您可以在由 s3_output 定义的S3存储桶中找到结果视频。

from sagemaker.processing import ProcessingInput, ProcessingOutput
script_processor.run(
    code='./container-batch-inference/predict.py',
    inputs=[
        ProcessingInput(source=s3_input, destination="/opt/ml/processing/input"),
        ProcessingInput(source=s3_model_uri, destination="/opt/ml/processing/model"),
    ], 
    outputs=[
        ProcessingOutput(source='/opt/ml/processing/output', destination=s3_output),
    ]
)

清理

为避免不必要的费用,删除您创建的作为此解决方案一部分的资源,包括推断端点。

结论

本文演示了如何使用SageMaker上的最先进算法在自定义数据集上实现多目标跟踪解决方案。我们还演示了三种SageMaker部署选项,以便您可以选择最佳选项适用于自己的业务场景。如果用例需要低延迟并需要将模型部署在边缘设备上,则可以使用AWS Panorama在边缘部署MOT解决方案。

有关更多信息,请参阅使用YOLOX + BYTE-TRACK进行多目标跟踪和数据分析。