Visual Relationship Detection with Deep Structural Ranking(阅读笔记)
Published:
该文章仅对相关论文做出个人解读,并非博客作者原创工作,如果你觉得对你的工作有所帮助,请引用原文信息。如果要转载博客内容,请告知笔者。
论文信息:
@article{liang2018Visual,
title={Visual Relationship Detection with Deep Structural Ranking},
author={Liang, Kongming and Guo, Yuhong and Chang, Hong and Chen, Xilin},
booktitle={AAAI Conference on Artificial Intelligence},
year={2018}
}
GitHub Link: https://github.com/GriffinLiang/vrd-dsr
如有任何相关问题欢迎评论或者邮件讨论wenyuanxue@bjtu.edu.cn
Introduction
视觉关系检测任务的目标是准确定位图像中的一对物体,并对他们之间的关系(predicate,“谓语”)做出判断,如图(1)所示。作为一个中间阶段的学习任务,视觉关系检测的结果可以应用在图像描述(image captioning)和视觉问答(visual question answering)等更高层的视觉理解任务。
视觉检测任务主要有以下两类挑战:
- 如果我们将两个物体间的视觉关系表示为:主语-谓语-宾语(subject-predicate-object),假设有N种不同的物体和K个谓语(即K个关系),那么“主谓宾”这样的组合数大概有$O(N^2K)$。有一类方法就是直接将“主谓宾”这样的关系对作为学习目标(Sadeghi and Farhadi 2011),但是在真实的世界中,物体都不是等概率出现的,有些组合在数据集中可能根本没有对应的样本。因此这类方法在较大的数据集上就会表现不佳。还有一个办法是对物体和谓语分别做检测(Lu et al. 2016),那么不论主语和宾语分别是什么,只要谓语相同,他们的关系都属于一类(e.g. truck-on-street, car-on-street)。但是,在每一类谓语关系中,各类物体的分布也是不均匀的。
- 另一个问题是数据集的关系标注不完整。首先,在一张图像中一般存在多个物体,然而只有部分子集进行了标注。其次,给了一对物体,他们没有被标注任何关系类别,即使是他们之间确实有视觉关系。还有一种情况是一对物体通常只被标注了一种视觉关系,然而他们通常不止只有一种关系(the co-occurrence of the predicates are very common)。一种最直接的解决办法是将未标注的视觉关系看做负样本,并且将视觉关系检测任务看做是多标签分类问题来解决。因为每对物体只都只被标注了一种关系,因此之前的很多工作也将该任务视作多类别分类,但这显然忽略了视觉关系的共存现象。
Deep Structural Ranking
本文的算法流程如上图所示,根据原文,我们分为Network Architecture和Structural Ranking Loss两部分来介绍。首先我们先作一些必要的形式化和说明:
- $P$表示所有被标注的物体对的集合,每对物体$(s,o) \in P$中,$s$表示主语,$o$表示宾语。$P_{(s,o)}$表示物体对$(s,o)$的所有视觉关系集合(谓语集合),那么$R={(s,p,o) \mid (s,o) \in P \bigwedge p \in P_{(s,o)}}$就表示一张图像中的所有视觉关系组合。
- 在训练阶段,物体的位置信息(bounding box)和类别信息(label)都是已知的。在测试阶段,我们首先需要尽心物体检测来获取其位置信息以及其类别。
Network Architecture
本文的网络结果融合了视觉表征、位置特征以及语义特征,下面逐一说明。
Visual Appearance Cue
这一部分主要是指通过卷积神经网络来提取视觉特征,作者共享的代码中,采用了VGG16作为骨干网络,并使用RPN来提取与主语s和宾语o对应的bounding box的区域特征,以及主谓语联合区域的特征表示。
#file: vrd-dsr/lib/nets/Vrd_Model.py line:103-116
103 x_u = self.roi_pool(x, rel_boxes)
104 x = x_u.view(x_u.size()[0], -1)
105 x = self.fc6(x)
106 x = F.dropout(x, training=self.training)
107 x = self.fc7(x)
108 x = F.dropout(x, training=self.training)
109 x = self.fc8(x)#并集区域特征表示
110
111 if(args.use_so):
112 x_s = torch.index_select(x_so, 0, ix1)#主语特征表示
113 x_o = torch.index_select(x_so, 0, ix2)#宾语特征表示
114 x_so = torch.cat((x_s, x_o), 1)
115 x_so = self.fc_so(x_so)
116 x = torch.cat((x, x_so), 1)#三个特征串联在一起
Spatial Location Cue
接下来就是空间位置特征,由于卷积神经网络具有的一些性质,如平移不变性等,这使得其很难学到诸如上、下、左、右等一些空间位置的特征。文中介绍了两种空间位置的表示方法:首先是主语s和宾语o的相对位置特征,由一个4维的向量构成。对于主语s来说,其表示为:
\[l_x = \frac{x_s - x_o}{x_o},l_y = \frac{y_s - y_o}{y_o},l_w = \log{\frac{w_s}{w_o}},l_h = \log{\frac{h_s}{h_o}}\]$(x,y,w,h)$就分别代表bounding box的左上角坐标以及宽和高。这一部分对应的代码是:
file: vrd-dsr/lib/data_layers/vrd_data_layer.py line:273-279
273 def _getRelativeLoc(self, aBB, bBB):
274 sx1, sy1, sx2, sy2 = aBB.astype(np.float32)
275 x1, oy1, ox2, oy2 = bBB.astype(np.float32)
276 sw, sh, ow, oh = sx2-sx1, sy2-sy1, ox2-ox1, oy2-oy1
277 xy = np.array([(sx1-ox1)/ow, (sy1-oy1)/oh, (ox1-sx1)/sw, (oy1-sy1)/sh])
278 wh = np.log(np.array([sw/ow, sh/oh, ow/sw, oh/sh]))
279 return np.hstack((xy, wh))
此外,作者还提供了另外一个选择来表示空间关系,那就是空间模板。一个物体的空间模板首先被初始化为一个与原图同样尺寸的零矩阵,然后物体所在的bounding box区域进行非零填充,最后再缩放到$32 \times 32$。主语s和谓语o的空间模板串联起来构成了第二种类型的空间位置特征。
file: vrd-dsr/lib/data_layers/vrd_data_layer.py line:261-271
261 def _getDualMask(self, ih, iw, bb):
262 rh = 32.0 / ih
263 rw = 32.0 / iw
264 x1 = max(0, int(math.floor(bb[0] * rw)))
265 x2 = min(32, int(math.ceil(bb[2] * rw)))
266 y1 = max(0, int(math.floor(bb[1] * rh)))
267 y2 = min(32, int(math.ceil(bb[3] * rh)))
268 mask = np.zeros((32, 32))
269 mask[y1 : y2, x1 : x2] = 1
270 assert(mask.sum() == (y2 - y1) * (x2 - x1))
271 return mask
Semantic Embedding Cue
然后是语义表示特征,很多情况下,一个谓语可以表示多个主宾之间的关系(e.g. car-near-street, person-near-building),但是这种视觉关系之间的联系可能很难从视觉特征中学习到,特别是在样本不均衡的情况下,所以这里又引入了语义表示特征。具体地,本文通过word-to-vector的方法分别将主语s和谓语o的物体类别表示为一个向量,然后将两个向量连接在一起,经过一层全连接,再与之前的视觉特征混合。表示该部分的具体代码如下:
#file: vrd-dsr/lib/nets/Vrd_Model.py line:127-134
127 if(args.use_obj):
128 emb = self.emb(classes)
129 emb = torch.squeeze(emb, 1)
130 emb_s = torch.index_select(emb, 0, ix1)
131 emb_o = torch.index_select(emb, 0, ix2)
132 emb_so = torch.cat((emb_s, emb_o), 1)
133 emb_so = self.fc_so_emb(emb_so)
134 x = torch.cat((x, emb_so), 1)
Structural Ranking Loss
前文中已经提到,很多物体间不止有一种关系(比如,people-above-bike, people-on-bike),所以本文中采用了多标签损失函数,代码中使用的是MultiLabelMarginLoss,公式如下:
\[loss(x,y) = \sum_{x,y}{\frac{max(0,1-(x[y[j]]-x[i]))}{x.size(0)}}\]这里的$x,y$都是二维的Tensor,对于一个样本,$x$表示的网络输出的各个类别的score,$y$表示的是该样本所属类别的向量。该loss的目标就是使$x$中正确类别($y[j]$)对应的score要大于非正确类别对应的score($y[j] \neq i$)。
在论文中,作者列举了一种该任务中可能出现的情况,那就是检测出来的关系谓语$r^{‘} \in R^{‘}$,但是这个关系谓语并没有出现在标注中$(R^{‘} = {(s^{‘},p^{‘},o^{‘}) \mid (s^{‘},o^{‘}) \in P \bigwedge p^{‘} \notin P_{s^{‘},o^{‘}}})$。如果这个检测结果本应该是正确的,比如该关系组合出现在了其他图像中,但由于不是显著性关系,所以并没有在当前数据中进行标注。作者将该种情况下的损失形式化为:
\[loss(x) = \sum_{r \in R, r^{'} \in R^{''}}{[\Delta(r, r^{'})+\Phi(x,r^{'})-\Phi(x,r)]_{+}}\]去掉$\Delta(r, r^{‘})$不看,剩下的部分和上述的MultiLabelMarginLoss的表示应该是一致的。但是在这种因为不完备标注产生的误差是我们不希望的,这种偏差会导致$(\Phi(x,r^{‘})-\Phi(x,r))$这一项的margin变小,这也会势必会影响到整个算法的优化。因此,本文引入了$\Delta(r, r^{‘})$:
\[\Delta(r, r^{'})=\Delta(\{s,p,o\},\{s^{'},p^{'},o^{'}\}) \\ =1+P(p|c_s,c_o)-P(p^{'}|c_{s^{'}},c_{o^{'}}) \\ =1-(P(p^{'}|c_{s^{'}},c_{o^{'}})-P(p|c_s,c_o))\]$P(p \mid c_s,c_o)$表示的是数据集上统计的有标注的类别p的先验概率,$P(p^{‘} \mid c_{s^{‘}},c_{o^{‘}})$则是标注了关系对中对应的物体,却没有标注其关系的的概率。当后一项的概率比较大时,说明检测到的视觉关系更有可能是一个被漏掉的标注,两概率的差值因此也会对上面提到的减小的margin做出一些补偿。从而使整个训练过程得到优化。
file: vrd-dsr/tools/train.py line: 82
82 args.criterion = nn.MultiLabelMarginLoss().cuda()
file: vrd-dsr/lib/model.py line: 29
29 loss = args.criterion((rel_so_prior+rel_score).view(1, -1), target)
Experiments
作者已经在论文里对实验进行了详尽的说明,这里不多做赘述,只分享一点:Recall@50,Recall@100。这两个指标最早应该是在(Lu et al. 2016)1中提到的,起初看时没有认真地思考,想当然地认为:
[✖]对于一个样本(s,p,o),我们需要对这个组合进行分类,如果一共有K种谓语关系,那么网络输出的结果应该是一个K维的向量,处理成softmax概率分布,取概率最大的前z个,如果这z个里有其对应的真实类别,则我们就认为预测正确。然而这样理解是不正确的。因为,拿这个vrd这个数据集来说,一共只有70个类别,显然Recall@100就没法解释。
后来欧同学在邮件中和我讨论另一篇文章时指出了这个问题,我对比这篇论文与代码,认识到了之前理解的错误,这个问题正确的理解应该是这样的:
[✔]对于一张图像,存在N个物体,那么一共可以组成$N \cdot (N-1)$个关系对,再算上一共有K种关系,那么可能的组合一共是$K \cdot N \cdot (N-1)$,将这些组合的结果按照confidence进行排序。分别统计前50和100个预测中的True Positive与50和100做比值就得到了Recall@50和Recall@100。
如果大家有任何问题,欢迎来信交流(wenyuanxue@bjtu.edu.cn)
C. Lu, R. Krishna, M. Bernstein, and L. Fei-Fei. Visual relationship detection with language priors. In Proc. Eur. Conf. Comp. Vis., pages 852–869. Springer, 2016. ↩