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

相关文章

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

一文解析C#中的StringSplitOptions枚举

《一文解析C#中的StringSplitOptions枚举》StringSplitOptions是C#中的一个枚举类型,用于控制string.Split()方法分割字符串时的行为,核心作用是处理分割后... 目录C#的StringSplitOptions枚举1.StringSplitOptions枚举的常用

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

MyBatis延迟加载与多级缓存全解析

《MyBatis延迟加载与多级缓存全解析》文章介绍MyBatis的延迟加载与多级缓存机制,延迟加载按需加载关联数据提升性能,一级缓存会话级默认开启,二级缓存工厂级支持跨会话共享,增删改操作会清空对应缓... 目录MyBATis延迟加载策略一对多示例一对多示例MyBatis框架的缓存一级缓存二级缓存MyBat

深入理解Mysql OnlineDDL的算法

《深入理解MysqlOnlineDDL的算法》本文主要介绍了讲解MysqlOnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录一、Online DDL 是什么?二、Online DDL 的三种主要算法2.1COPY(复制法)

前端缓存策略的自解方案全解析

《前端缓存策略的自解方案全解析》缓存从来都是前端的一个痛点,很多前端搞不清楚缓存到底是何物,:本文主要介绍前端缓存的自解方案,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、为什么“清缓存”成了技术圈的梗二、先给缓存“把个脉”:浏览器到底缓存了谁?三、设计思路:把“发版”做成“自愈”四、代码

Java集合之Iterator迭代器实现代码解析

《Java集合之Iterator迭代器实现代码解析》迭代器Iterator是Java集合框架中的一个核心接口,位于java.util包下,它定义了一种标准的元素访问机制,为各种集合类型提供了一种统一的... 目录一、什么是Iterator二、Iterator的核心方法三、基本使用示例四、Iterator的工

idea突然报错Malformed \uxxxx encoding问题及解决

《idea突然报错Malformeduxxxxencoding问题及解决》Maven项目在切换Git分支时报错,提示project元素为描述符根元素,解决方法:删除Maven仓库中的resolv... 目www.chinasem.cn录问题解决方式总结问题idea 上的 maven China编程项目突然报错,是