admin管理员组

文章数量:1122969

Single

昨天在arxiv上发现的一篇非常有意思的论文,特来记录一下,惯例发链接

自己实现的github

为什么文章叫Single-Stage,首先,针对多人pose这方面,主流的方法分为两类:

  1. Top-Down solution。先用一个detector检测出来图像上的所有行人,然后针对每一个检测的出来的human box,做单人pose预测,总共需要2步
  2. Bottom-Up solution。先用一个cnn检测出来图像上所有人的所有关键点,再通过一个聚类算法(或者其它方法)对这些点进行区分,将同一个人的点划分到一起,最后得到所有人的关键点,总共需要2步

以上的方法都是需要经过两个步骤才可以得到最终的multi-person pose,那么有没有一种方法可以一步到位?这就是论文提出的方法,一步到位,一次就可以得到多个人的pose点,所以叫做Single-Stage,具体看下图:

思路和之前anchor-free的Objects as Points很像,具体如下:

  1. 定义一个中心点,这个中心点就是这个人的box的中心位置,论文里把它叫作root joint

  2. root joint回归出来模型需要检测的某一个人的所有pose点的offset(相对root joint)而言,这样网络只需要最后输出一个 root joint heatmap, 然后heatmap上的每一个位置再回归得到N个offset,就可以得到一个人的所有pose点坐标

  3. 上面2步其实就是Objects as Points里提到的关于检测pose点的方法,这篇文章对这个更进一步,因为如果直接回归一个人的所有点离root joint的offset,对于离root joint比较远的点,回归起来比较困难(称之为long range displacements),所以,论文对一个人的所有关节点做了分层,共分成4个层次:

    • root joint 为第一层
    • 脖子点、两个肩膀点、两个臀部点为第二层
    • 头部点、手肘点、膝盖点为第三层
    • 手腕点、脚踝点为第四层
  4. 分层之后,每个root joint同样还是回归N个点的offset,但这offset不再是直接针对root joint的offset,而是root joint直接回归第二层点的offset,然后第三层点的坐标是通过相对于第二层的点的offset得到,第四层点的坐标是通过相对于第三层点的offset得到,这样,root joint得到的N个offset都是short-range的,有利于网络去学习。形象化如下图所示:

  5. 图c是直接通过root joint回归出来N个坐标的形象化,图d是论文改进的一个回归方式,可以看出每个offset都变得很短,这样有助于网络去学习这些offset。

论文的做法在不同的数据集上都达到了速度与精度的高度平衡,非常棒,具体图表可以参照论文。但仍然有些不是很清楚的地方:

  • 模型的label怎么打?回归得到的N个offset有什么固定顺序吗?是不是右肘只负责回归右手腕的offset?
  • 论文说heatmap用l2 loss, 回归的offset用smooth l1 loss,但我尝试过用centernet的做法回归得到17个pose点,效果并不好,里面是不是还有其它trick?
  • 期待作者的开源

update 09.09

  1. label的标签格式。对于root joint来讲,和centernet里的一样,把这个instance的box中心点当作root joint,并以这个点为中心打个高斯核,并在训练的时候,对root joint使用L2 loss计算。

  2. 对于人体的其它关节点来说,首先是根据事先划分的4个层级的顺序,第i层的点负责计算第i+1层的点的偏移,并且是负责离其语义信息最接近的那个点(举例来说,右肩点和右肘点分属第2和第3层级,那么右肘点的偏移就是从右肩点出发得到的offset。虽然右肩和左肩同属第2层级,但很自然的,左肩负责左肘的偏移而不负责右肘的偏移)这样整个人体的关节点偏移指向就和上图2(d)中表示的一样:

     1). root joint -> right shoulder -> right elbow -> right wrist2). root joint -> left shoulder -> left elbow -> left wrist3). root joint -> neck -> head4). root joint -> right hip -> right knee -> right ankle5). root joint -> left hip -> left knee -> left ankle
    
  3. 具体的label形式就是最终是一个[ h, w, 1 + N * 2]大小的featuremap输出,N表示有多少个关节点需要计算。第1层的channel是表示的root joint,后面的对应的N*2层channel就是N个点的offset,只不过和centernet不一样的是,是先根据root joint计算得到第2层的关节点的位置(如 right shoulder, left shoulder),再根据第2层计算出来的位置加上对应的offset得到第3层的关节点的位置(如 right elbow, left elbow),这样直到把N个关节点都给找出来

update 09.18

  1. loss计算的时候,root joint使用的是MSE loss, body joint regression使用的是smooth l1 loss,只不过在计算body joint regression的时候,需要额外加入个mask,标明哪些channel位置处是有label的,只计算有label的位置,其余位置忽略掉。

update 20200310

  1. 自己在做测试的时候,使用的ai-challenger的数据集,根据我的理解计算出来的offset,如果按照论文所说的还要出上个h*w做归一化的话,我发现offset loss都特别小,而且,center点到第一个层级的offset最大,第一层级到第二层级,以及第二层级到第三层级都相对来说比较小。训练几个epoch进行测试后,发现网络将所有的offset都倾向于学习为0,center点没有问题可以学到,但offset很差。
  2. 原来offset loss和center loss的比重为1:0.01,学习centernet,全部设为1:1,看看情况

本文标签: Single