Anchor-Free Person Search(AlignPS)
代码
https://github.com/daodaofr/AlignPS
网络结构
-
Scale Alignment:作者说FCOS中的FPN结构输出的多个特征图来检测不同的scale的目标的方案在person中是不合理的,作者认为如果从不同特征图上获取的re-id features,那么会导致获取到的re-id features是不一致的。所以作者只使用了最后一个特征层,即上图中的P3。
-
Region Alignment:作者认为上图中的Feature Aggregation Block模块可以很好地融合各层特征。
-
Task Alignment:提出了Triplet-Aided Online Instance Matching Loss,作者说这个loss可以更加关注reid feature。
【我觉得他在放pi,不过我需要先去搞懂一下FPN到底是个啥?】
TOIM loss
OIM loss(参考:链接):
- 查找表 (LUT) 中存储所有标记身份的特征中心,查找表用V表示,\(V \in R^{D\times L}=\{v_1, ...,v_L\}\),L个D维的向量。
- 循环队列用来储存在最近mini-batch种检测到的无标记身份,Circular Queue用U表示,\(U \in R^{D\times Q}=\{u_1, ...,u_L\}\)。
在每次迭代中,给定一个标签为 i 的输入特征 x,OIM 分别通过 \(V^Tx\) 和 \(Q^Tx\) 计算 LUT 和循环队列中所有特征之间的相似度。x 属于身份 i 的概率计算如下:
OIM 的目标是最小化如下负对数似然:
OIM loss中,距离仅在输入特征和存储在查找表和循环队列中的特征之间计算,而输入特征之间没有进行比较。其次,对数似然损失项没有在特征对之间给出明确的距离度量。下面公式解决了此问题:
M应该只是一个参数,\(D_{pos}\)表示同一个人的特征向量之间的距离,\(D_{neg}\)表示不同人的特征向量之间的距离。
最终得到Triplet-aided OIM (TOIM) loss:
问题
【问题】re-id Embeddings是个什么东西?图像中的每个人物对应re-id Embeddings中的一个向量吗?re-id Embeddings可以输入到detection head中是否就是说明re-id Embeddings中的每个向量都包含“每个框中的人物长什么样和框的位置信息”?那么将re-id Embeddings直接输入到Loss Funtions中是否会导致信息冗余?re-id Embeddings前面再增加一个卷积模块进行特征提取会不会更好?re-id Embeddings应该是包含了位置信息和人物的细节信息,所以不应该叫re-id Embeddings吧,re-id Embeddings应该是只包含了人物的细节信息。
deformable convolution?
ROI-AlignPS
我猜测实现的过程如下:
图a通过RPN生成区域建议框,然后使用框中内容生成reid feature、bbox、cls
图b中的底部AlignPS分支生成bbox,然后bbox所框到的特征图通过图b中的上半部分网络得到各个reid feature。图b中丢弃了RPN,直接使用下层AlignPS分支生成的框。
这样就实现了在推理阶段不使用anchor,在训练阶段使用anchor。
上半部分称为ROI-Align分支,下半部分称为AlignPS分支。
其他
"Gallery" 在人物搜索中通常是指一个图片集合,其中包含了可能的目标人物的照片。
re-id Embeddings:就是人像经过特征提取以后得到的特征向量。
reid和detect:以前我认为在person search中“re-id更关注是人长什么样,detect更关注哪个是人”,但是现在我认为不是这样的:只有在two stage模型中,才是“re-id更关注是人长什么样,detect更关注哪个是人”,在one stage中更关注的应该是“query与图像中人物的匹配”。
代码阅读
【问题】从AlignPS/configs/fcos/prw_base_focal_labelnorm_sub_ldcn_fg15_wd1-3.py中可以看出,test集和val集是一样的,这样不行吧?
代码运行过程中缺少什么模型就去下载什么模型,很多模型从这里可以找到
loss计算:
- 计算正负样本:
if center_sampling==False
,如果特征图上点对应于原图中的区域的中心点落在了gt中,则认为此区域为有标记。
if center_sampling==True
,首先以gt中心为中心画出一个长宽为(h,w)的框A,(h,w)为特征图对应原图中区域的大小。然后计算A与gt的交集区域B,如果特征图上点对应于原图中的区域的中心点落在了B中,则认为此区域为有标记。
loss定义在AlignPS/mmdet/models/dense_heads/fcos_reid_head_focal_sub_triqueue.py
解释一下下面函数:loss_oim = F.nll_loss(focal_p_i, pid_labels, reduction='none', ignore_index=-1)
,其中focal_p_i的shape为[9, 10532],pid_labels的shape为[9]
数据集
数据集包装成coco的标注文件的格式,接下来对其进行介绍:
读取json的代码如下:
import json
json_path = "train_pid_new.json"
json_labels = json.load(open(json_path, "r"))
for i in range(3):
print(json_labels["annotations"][i])
train_pid_new.json文件中三种信息,分别为images、annotations和categories,虽然categories中只有person类,但是还是写出来了,我猜测这是由于mmdetection对数据格式的要求
1.标注框的格式(json_labels["annotations"]):
{'area': 4144, 'bbox': [391, 243, 37, 112], 'category_id': 1, 'id': 0, 'image_id': 0, 'iscrowd': 0, 'person_id': 2212, 'segmentation': []}
{'area': 4956, 'bbox': [426, 249, 42, 118], 'category_id': 1, 'id': 1, 'image_id': 0, 'iscrowd': 0, 'person_id': 2543, 'segmentation': []}
{'area': 20999, 'bbox': [297, 303, 83, 253], 'category_id': 1, 'id': 2, 'image_id': 1, 'iscrowd': 0, 'person_id': 4430, 'segmentation': []}
有用的字段有三个,分别为'bbox'、'image_id'和'person_id','image_id'用于找到对应的图片
{'file_name': 's1.jpg', 'id': 0, 'width': 600, 'height': 800}
{'file_name': 's10.jpg', 'id': 1, 'width': 600, 'height': 800}
{'file_name': 's100.jpg', 'id': 2, 'width': 600, 'height': 800}
这里的id应该与annotations中的image_id是对应的。
coco中的目标边界框信息为[x,y,width,height]