Re-ranking Person Re-identification with k-reciprocal Encoding 重排序算法解析

本文主要是介绍Re-ranking Person Re-identification with k-reciprocal Encoding 重排序算法解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

论文:

Re-ranking Person Re-identification with k-reciprocal Encoding

代码:

https://github.com/layumi/Person_reID_baseline_pytorch/blob/master/re_ranking.py

 

 

3.提出的方法

3.1 问题定义

给定probe person 和gallery set,可以度量它们的马氏距离:

这里是特征向量,M是半正定矩阵。我们可以根据这个距离对p和G排序,距离从小到大排列:

我们的目标是对这个初始排序列表重新排序,使得更多的正样本出现在列表的前段。

 

3.2 K-reciprocal Nearest Neighbors

首先,定义k-nearest neighbors(k-nn),即排序列表的前k个样本:

接着,定义k-reciprocal nearest neighbors(k-rnn),简单地说就是满足“都在对方的k-nn列表里”这一条件的的集合:

 

然而,由于光照、姿态、视角等一系列变化,正样本可能会被排除到k-nn列表外,因此我们定义了一个更鲁棒的k-rnn集合:

上式的意思是,对于原本的集合R(p,k)中的每一个样本q,找到它们的k-rnn集合R(q,k/2),对于重合样本数达到一定条件的,则将其并入R(p,k).通过这种方式,将原本不在R(p,k)集合中的正样本重新带回来。文中给了一个例子来说明这一过程,如下图所示:

 

3.3 Jaccard距离

作者认为,假如两张图片相似,那么它们的k-rnn集合会重叠,即会有重复的样本。重复的样本越多,这两张图片就越相似。那么很自然地就想到用Jaccard Distance度量它们k-rnn集合的相似度:

然而,上面的距离度量有三个缺点:

1.取交集和并集的操作非常耗时间,尤其是在需要计算所有图像对的情况下。一个可选方式是将近邻集编码为一个等价的但是更简单的向量,以减少计算复杂度。

2.这种距离计算方法将所有的近邻样本都认为是同等重要的,而实际上,距离更接近于probe的更可能是正样本。因此,根据原始的距离将大的权值分配给较近的样本这一做法是合理的。

3.单纯考虑上下文信息会在试图测量两个人之间的相似性时造成相当大的障碍。因为,不可避免的变化会使得区分上下文信息变得困难。因此,为了得到鲁棒的距离度量,结合原始距离和Jaccard距离是有必要的。

为了克服上述缺点,我们开始改造Jaccard距离。首先,将k-rnn集合编码为N维的二值向量=,其中每个元素由以下指示函数定义:

接着,为了给每一个元素根据原始距离来重新分配权值,我们采用了高斯核。于是将向量改写为:

 

于是,计算Jaccard距离时用到的交集和并集的基数就改写为:

最后,我们终于得到了改造过的Jaccard距离:

这个改造过程,实际上是将集合比较问题转化为纯粹的向量计算,实践起来更简单。

 

3.4 Local Query Expansion

基于来自同一类的图像可能共享相似特征的想法,我们使用probe的k-nn集合来实现local query expansion,

特别要说明的是,这个query expansion被同时用到了probe 和galleries 上。(这里我的理解是对每个向量定义为其k-nn集合向量的平均,通过这种方法来提升性能。根据我的测试,去掉这一步仍然有不错的效果,但mAP会有少许的下降。)因为k-nn集合可能会混有噪声,因此我们将k值设置得比较小。为了与前面的k做区分,我们定义前面用到的为,而这里用到的为,k1>k2.

 

3.5 最终距离

在这里有参数,最终计算距离如下:

 

3.6 复杂度分析

参考原文内容。

 

整个重排序的流程图如下所示:

 

 

 

这篇关于Re-ranking Person Re-identification with k-reciprocal Encoding 重排序算法解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/306149

相关文章

C++快速排序超详细讲解

《C++快速排序超详细讲解》快速排序是一种高效的排序算法,通过分治法将数组划分为两部分,递归排序,直到整个数组有序,通过代码解析和示例,详细解释了快速排序的工作原理和实现过程,需要的朋友可以参考下... 目录一、快速排序原理二、快速排序标准代码三、代码解析四、使用while循环的快速排序1.代码代码1.由快

使用EasyExcel实现简单的Excel表格解析操作

《使用EasyExcel实现简单的Excel表格解析操作》:本文主要介绍如何使用EasyExcel完成简单的表格解析操作,同时实现了大量数据情况下数据的分次批量入库,并记录每条数据入库的状态,感兴... 目录前言固定模板及表数据格式的解析实现Excel模板内容对应的实体类实现AnalysisEventLis

Java的volatile和sychronized底层实现原理解析

《Java的volatile和sychronized底层实现原理解析》文章详细介绍了Java中的synchronized和volatile关键字的底层实现原理,包括字节码层面、JVM层面的实现细节,以... 目录1. 概览2. Synchronized2.1 字节码层面2.2 JVM层面2.2.1 ente

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR

IDEA与JDK、Maven安装配置完整步骤解析

《IDEA与JDK、Maven安装配置完整步骤解析》:本文主要介绍如何安装和配置IDE(IntelliJIDEA),包括IDE的安装步骤、JDK的下载与配置、Maven的安装与配置,以及如何在I... 目录1. IDE安装步骤2.配置操作步骤3. JDK配置下载JDK配置JDK环境变量4. Maven配置下

Python中配置文件的全面解析与使用

《Python中配置文件的全面解析与使用》在Python开发中,配置文件扮演着举足轻重的角色,它们允许开发者在不修改代码的情况下调整应用程序的行为,下面我们就来看看常见Python配置文件格式的使用吧... 目录一、INI配置文件二、YAML配置文件三、jsON配置文件四、TOML配置文件五、XML配置文件

Spring中@Lazy注解的使用技巧与实例解析

《Spring中@Lazy注解的使用技巧与实例解析》@Lazy注解在Spring框架中用于延迟Bean的初始化,优化应用启动性能,它不仅适用于@Bean和@Component,还可以用于注入点,通过将... 目录一、@Lazy注解的作用(一)延迟Bean的初始化(二)与@Autowired结合使用二、实例解

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1