摘要:
针对分布式摄像头系统进行对象查询任务的一个系统 Gecko ,于边上实时运行
主要特点:
(i) 能提取特征并选择对应的模型分配给边缘设备
(ii) 运行时能够动态调整帧查询间隔,并且支持在边缘设备上进行模型的合并和分支
(iii) 改变视频分辨率来调整查找准确性(流转移和模型连续学习)
背景介绍:
为了能够实时进行物体查询,大部分模型都是减少了DNN的复杂性来换取实时性,从而降低了模型识别的准确性
SurveilEdge,Video-zilla之类的方法尝试通过云边协同来实现实时处理,但他们(以及其他类似的工作)都没有注意到以下几点来增加资源利用率:
- 多摄像头间的模型共享:类似SurveilEdge这样的方法只关注了单视频流查询的优化,而在多视频流查询中我们很容易可以将相同对象视频流查询的工作使用相同的模型处理,也就是共享模型以实现资源利用率的提高
- 实时查询资源消耗大,为了保证高精度和低延迟需要有对应的分配策略
- 查询应当适应视频的内容:(1)因为即便是针对某种物体进行检测,各种轻量级模型之间的性能波动还是会比较大,所以需要选择表现最好的模型来检测。(2)且应该根据视频内容来配置视频帧查询间隔(视频流在分析时只会按照一定间隔进行抽取然后分析)(3)并且还应当考虑到模型的特化(比如专门针对夜晚)来分配模型。
系统输入:
查询物体,查询的摄像头
系统输出:带有查询物体的视频帧
系统工作流:
-
用户出现在线视频查询任务,输入查询物体和查询的摄像头
-
Gecko对要查询的视频流提取帧$X$的内容特征(Content Features),包括:
-
名称 维度 时间花费 定义 基本特征 5 0.42ms 帧长宽,物体数量 颜色直方图 768 17.23ms 3通道的颜色直方图256*3 梯度方向直方图 5400 30.15ms Oriented Gradients MobileNetV2 1280 179.89ms 取全连接层之前的特征图
再额外进行一次平均池化
-
Gecko根据提取到的特征,调用模型选择函数(serverless)从云端共享模型库中选择合适的模型。
- 模型选择函数A(model,feature)是一个6层的神经网络,每个隐藏层都有256个节点,由于特征维度差距很大,所以对每个特征在第一层都会用全连接层进行特征映射融合,映射到256维,最后输出层节点个数就是模型个数,对应每个模型的准确率分数,每次添加新的模型的时候输出层新建节点并且只训练新节点的连接权重(这个serverless函数是怎么训练的?)
-
调度器(Scheduler)调度模型到合适的边缘设备*(模型的大小不是好几个GB吗)*,并将一个或多个视频流给到对应的模型上开始查询
- 调度策略:每个模型都有绑定的元数据记录着模型占用GPU资源大小以及对每个额外视频流所需要的处理资源,Gecko的Scheduler只考虑空间资源大小问题,将等待执行的model按照资源需求从小到大排序,然后依次分配给最空闲的设备。
-
在查询进行时采用 跳帧控制器 和 模型合并分支重分配 来对资源进行重新配置:
-
跳帧控制器(Frame skipping controller)会动态地调整视频流的帧查询间隔,对于慢速移动的物体就可以适当增加帧查询间隔(反之同理)。具体地说,跳帧控制器输入第$k$帧图像的预测类别和$k-1$帧的预测类别就能输出两帧之间的误差值,如果误差较大就说明场景变化较大,从而适当减少帧查询间隔(间隔帧数量减半),较小则说明场景变化较小,从而适当增加帧查询间隔(间隔帧+1),像这种线性增加,指数减少的算法就是AIMD(Additive Increase/Multiplicative Decrease)算法。
-
**模型的合并和分支(Fork and Join)也会自适应地重新分配边缘设备的计算资源。**分支(Fork)具体是将模型从一个边缘设备拷贝到另一个边缘设备上,以确保:
- 该模型能够实时处理所有的到达帧
- 边缘设备接收的视频流保持在最大支持数以下(为什么要这么做?)
相应的,如果查询完成导致视频流数量下降,亦或者视频基本静止或者变化缓慢,则需要用到合并(Join)操作,在保证处理速度和最大流支持数的前提下尽可能减少使用的边缘设备,释放冗余模型。
在Join操作或后续的数据飘移机制中会涉及到模型A即将释放,需将自己的流1转到模型B上。为了确保无缝衔接,模型B首先接入流1,在正常工作后向模型A发送一个完成信号,接到信号后模型A断开流1并释放。
-
-
针对数据漂移(Data Drift),还引入了 细粒度的流传输 与 连续学习 机制:
-
细粒度的流传输:当视频流场景发生明显变化后,会重新提取特征,迁移到另一个更适应的模型上。具体来说,对每个运行时的视频流,都会每隔30秒进行一次验证,截取帧$Y$和最初做模型选择的帧$X$的内容特征,使用如下公式来计算Hellinger距离
$$
d_H(X,Y)=\frac{1}{|F|}\sum_{f∈F}\sqrt{\sum_{i=1}^{k_f}{(\sqrt{\frac{X_{fi}}{\sum_{j=1}^{k_f}X_{fj}}}-\sqrt{\frac{Y_{fi}}{\sum_{j=1}^{k_f}Y_{fj}}})^2}}
$$
$F$是所有特征的集合,$k_f$是$f$的维度。如果连续多次计算得到的Hellinger距离都大于阈值的话则会触发迁移决策。 -
连续学习:困难样本挖掘器(Hard Example Miner)会挖掘困难样本帧,触发serverless模型的再训练。具体来说,模型对于每个预测的物体都有一个置信概率$bbox.score$,给定$(\theta_L, \theta_M, \theta_H)$三个阈值和一个图像阈值$\lambda$,如果有预测物体的$bbox.score$处于$(\theta_L, \theta_M)$之间,则直接将该帧认定为困难样本帧。如果没有物体的$bbox.score$处于$(\theta_L, \theta_M)$区间中,则统计所有$bbox.score$处于$(\theta_M,\theta_H)$之间的物体的数量$m$,若共有$n$个检测物体,则判断$\frac{m}{n}\ge(1-\lambda)$,如果为真则说明有大量物体的检测还是不太准确,因此仍然认定此帧为困难样本帧。$(\theta_L, \theta_M, \theta_H, \lambda)$这四个参数都是根据经验选择的。
-
当困难样本帧积攒的数量超过阈值时,会使用一个非常厉害的黄金模型来标定这些困难样本帧,随后给对应的模型当训练集进行训练,训练集的一小部分还会被替换成之前的历史训练数据以防遗忘。如果新模型准确率高于之前的模型,则将其在边缘设备上进行替换,并且加入到模型集合中,更新模型精度预测器。
评估
实验设置
特征提取器,跳帧控制器,困难样本挖掘器都是使用pyTorch来实现的神经网络模型。边缘端实现使用了DeepStream SDK来实现运行时视频流的附着和分离,非边缘端实现基于阿里云的serverless计算平台。
实验使用了三种不同的工作负载,分别是单个/多个/所有摄像头上进行查询某类对象的场景。实验设备分别是NVIDIA Jetson TX2,NVIDIA Jetson AGX Xavier,NVIDIA Jetson AGX Orin。
实验数据和模型
YouTube收集的62个监控视频作为相机流,视频长度从几分钟到一小时不等,总共25小时,包含不同的城市,场景,天气情况,时间。且任何边缘设备上都不会出现重复播放的视频。
轻量级的检测模型(云端模型库中的模型)使用的是YOLOX-Nano,黄金模型(用于困难样本帧标定)使用的是YOLOX-X
衡量指标
平均GPU使用量,检测准确率(使用F-1 score),响应时间
Baseline
One-to-one:在边缘设备上运行的一个Docker,可以查询摄像头中的某一个对象
RECL:适用于多任务的一个类似的系统,但是不具备合并和分支的策略
SurveilEdge:类似的云边协作系统,可以使用特定模型进行摄像头查询
Scalable SurveilEdge:SurveilEdge的改进版本,因为有多个工作负载环境,所以额外实现了单模型跨摄像机查询某类对象的功能
结果
Gecko基本全方位优于其他方法
总结
作者提出的Gecko可以在边缘端实现对视频流高效且准确的对象查询。主要结构包括:
- 根据 视频帧内容特征 输出 模型准确率 的一个 深度预测模型
- 根据 GPU占用资源大小 将模型分配到边缘设备 的一个调度器
- 运行时缓解资源竞争 的 动态跳帧控制器 (输出两帧间的误差值)
- 运行时缓解资源竞争 的 FORK 和 JOIN 机制(监控运行时资源来重分配流和模型)
- 针对数据漂移 的 细粒度流迁移机制(定时检测场景变化并决定是否切换模型)
- 针对数据漂移 的 连续学习机制(收集综合置信概率低的视频帧定量进行重复训练)
感想
论文针对视频流对象查询系统提出了多种机制和方法来优化效率和准确度,单看每个机制感觉并不难,而堆砌在一起作为整个系统的优化则较为完整。在自己未来的方法中也可以使用类似的做法,加入轻量型的模型在基本不影响效率的情况下通过简单的机制来进行一定程度的优化。