前言
最近发现face++开源了一个图像检索和行人重识别的基于深度学习的软件包,最近一段时间也一直在接触图像检索相关的东西。故借此机会,对里面涉及的一些常用的方法模块进行一个简单的介绍总结,便于日后回顾。
PyRetri是什么?
PyRetri是由旷视开源的第一个基于深度学习的无监督图像检索库,它是基于PyTorch进行开发的python库。
paper: https://128.84.21.199/abs/2005.02154
GitHub: https://github.com/PyRetri/PyRetri
PyRetri将基于深度学习的无监督CBIR分为了三个重要的部分:特征提取(feature extraction)、索引(indexing)和评估(evaluation)。其主要的整体框架图如下:
图像检索常用公开数据集
图像检索并不是一个新兴的研究方向,现阶段针对不同场景以及需求的图像检索都或多或少有数据集公开。强烈推荐一个总结了常用的计算机视觉数据集列表的网站:Yet Another Computer Vision Index To Datasets (YACVID)
下面简单介绍一些常见的图像检索数据集概况,针对实例检索,往往很多场景也都会使用大规模的分类数据集。
- Oxford5K 2007 牛津大学建筑
收集方式: 通过关键字在Flickr上查询下载图片 每一个query对应good、OK、junk list文件,作为ground truth
规模: total :5062 query: 55 (11*5)
特点: 除提供.jpg格式图片外,还提供sift描述符的压缩二进制文件等
paper: Object retrieval with large vocabularies and fast spatial matching(CVPR 2007)
- Paris6k 2008 巴黎地标
收集方式: 与Oxford5K相同(查询关键字不同)
规模: total :6412 query: 55(11*5)
特点: 仅提供.jpg格式图片
paper: Lost in Quantization: Improving Particular Object Retrieval in Large Scale Image Databases(CVPR 2008)
- Revisiting Oxford 2018 牛津大学建筑
收集方式: 基于Oxford5K
规模: query 50->70
特点: 修复原来数据标注问题 增加数据 标签细化
paper: Revisiting Oxford and Paris: Large-Scale Image Retrieval Benchmarking(CVPR 2018)
- Revisiting Paris 2018 巴黎地标
收集方式: 基于Paris6K
规模: query 50->70
特点: 修复原来数据标注问题 增加数据 标签细化
paper: Revisiting Oxford and Paris: Large-Scale Image Retrieval Benchmarking(CVPR 2018)
- Google landmarks 2017 街景地标建筑
规模: total :200万张图片 3万个独特地标
特点: kaggle 比赛
paper: Large-Scale Image Retrieval with Attentive Deep Local Features( ICCV 2017)
- Google landmarks-v2 2019 街景地标数据
收集方式: 摄影社区众包进行实例标注
规模: total:超过500万张图像 超过20万个不同的地标
特点: kaggle 比赛
paper: Detect-to-Retrieve: Efficient Regional Aggregation for Image Search (CVPR 2019)
- Landmark 3D 2012 地标数据
收集方式: web 图片和3D模型(点云)
规模: total :45180
特点: 25个地标 ;45,180个数据库图像(每个地标1.4K-2K);10,000个正面query用于评估(每个标志400个);3D模型中约270万个3D点(每个地标29K-223K); 约有5800万个SIFT
paper: 3D Visual Phrases for Landmark Recognition". in Proc. of the 25th IEEE Conference on Computer Vision and Pattern Recognition (CVPR 2012)
- Paris500k 2013 地标建筑
收集方式: 数据集是从Flickr和Panoramio收集的地标图像。图像具有“自然”分布,数据集非常具有挑战性,因为存在重复和近似重复,以及大量不相关的图像,例如派对,宠物等的照片
规模: total :501,356
特点: 提供79个地标建筑的94303张图片clustering ground truth
paper: Discovering Details and Scene Structure with Hierarchical Iconoid Shift(ICCV 2013)
收集方式: ZuBuD+ 是对ZuBuD的扩展,主要是增加了测试图片 评估方式:TOP5
规模: total :1005 training data/1005 test_balance data
特点: 每个图像有201个建筑物,每个视图有五个视图,提供训练数据、相同数量的测试数据、ground truth file 和 用于评估的python程序
paper: A location-aware embedding technique for accurate landmark recognition(2017)
- CUB-200-2011 鸟类图片
收集方式:是 CUB-200数据集 的扩展
规模:total : 11788, 200类别
特点:每个图片都有注释 15 Part Locations, 312 Binary Attributes, 1 Bounding Box 图片与ImageNet重叠 常用于细粒度分类、检索等
paper: Wah C., Branson S., Welinder P., Perona P., Belongie S. “The Caltech-UCSD Birds-200-2011 Dataset.” Computation & Neural Systems Technical Report, CNS-TR-2011-001.
- Indoor 室内场景
规模:total :15620 67个室内场景 train set :67*80 test set :67*20
特点:图片有annotation (实例分割) LabelMe格式
paper: A. Quattoni, and A.Torralba. Recognizing Indoor Scenes. IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 2009.
- Caltech101 通用
规模:101个类别,每类40-80张
特点:通用的分类的数据集(有annotation),注:往往分类数据集也会用来实例检索
paper: Learning generative visual models from few training examples: an incremental Bayesian approach tested on 101 object categories. CVPR 2004
行人重识别常用数据集
行人重识别(person re-id)是图像检索的子领域,近几年从各大计算机视觉会议的论文收录情况也可以看出,行人重识别已经成为了计算机视觉领域的研究热点。无论是从社会意义还是从商业角度上来看,行人重识别都具有一定的研究意义。因为PyRetri提到了其也适用于行人重识别任务,那么我们也简单的介绍一下行人重识别常用的数据集。
针对行人重识别数据集,推荐网站: awesome-reid-dataset
-
Market-1501 数据集最早是 2015 年 公布的, 是至今使用广泛的大规模行人重识别数据集之一。该数据集使用 6 个摄像头(5 个高分辨率,一个低分辨率)在清华大学超市前收集的。为了保证跨摄像头搜索,不同摄像头之间存在重叠,并且保证每一个被标注的行人至少来自两个摄像头。更具体地,数据集包括 1501 个行人共 32668 张图片。网上所提供的公开数据集已将 32668张图片分为了训练集和测试集,其中测试集文件夹中包含 19732 张图片,训练集文件夹中包含 12936 张图片。另外将每个摄像头随机选出的一张 ID 行人共3368 张图片(750 个 ID,每个 ID 至多 6 张)作为待选集单独分开。
paper: Scalable Person Re-identification: A Benchmark (ICCV 2016) -
CUHK01 数据集由香港中文大学研究团队公开, 相关信息首次发表于2012 年的亚洲计算机视觉会议上。该数据集采自一对不相交的相机(即具有两个摄像视角)在大学校园收集的。一个视角主要捕获行人的正面和背面,另一个视角主要捕获行人的侧面。该数据集共收集了 971 个行人的 3884 张图片,每个行人包含来自两个视角的共4 张图片。由于采集环境和设备的关系以及采用手工裁剪标注的形式致使CUHK01 数据集行人图片的质量相对较好。
paper: Human re-identification with transferred metric learning (ACCV 2012) -
2014 年起深度学习进入行人重识别领域,为解决之前数据集太小无法满足深度学习训练的问题,香港中文大学的 Li 等人建立了较大规模的行人重识别数据集,名为 CUHK03,此前,他们已经建立了 CUHK01 和 CUHK02 数据集。CUHK03数据集由 5对不同的监控视角拍摄,包含 1360个行人的 13164张图片。此外, CUHK03 数据集还具有以下几个特点: 1) CUHK03 除了手工裁剪的图片以外,还有使用检测算法进行检测裁剪的图片。这使得 CUHK03 的数据集更接近于真实的环境,错位、遮挡、部位缺失都是常见的情况。 2) CUHK03 的样本是通过复杂的交叉视图混合变换采集的。 3)由于数据集中的图像获取是经过了几个月的时间,导致不同图片间存在着光照的不同。这些都使得 CUHK03 数据集上的行人重识别任务更具有挑战性。
paper: DeepReID: Deep Filter Pairing Neural Network for Person Re-identification (CVPR 2014) -
DukeMTMC数据集是一个大规模的多目标多摄像机行人跟踪数据集。数据集包含了 85 分钟的高分辨率视频,收集了来自8 个不同的摄像头, 超过 2700 个不同行人数据信息。基于该原始数据集,两个行人重识别扩展数据集 DukeMTMC-reID 和 DukeMTMC4ReID 分别被创建。其主要区别在于行人边界框的生成方式,前者采用的是直接手工标注,后者则采用 Doppia 作为检测器进行目标检测标注。DukeMTMC-reID作为DukeMTMC 数据集的行人重识别子集,共有36,411 张图像(原始视频中每 120 帧采样一张)。数据集中共包括 1812 个行人,其中 1404 个行人在至少两个摄像头以上出现,余下的 408 个行人只出现在单一 摄像头下。故在将该数据集按照 Market-1501 数据集格式组织时,随机采样 702个行人图片作为训练集,另外 702 个行人图片作为测试集。 查询集(query) 中为 1404 个行人 ID 每个摄像头下的一张图片,剩下的所有图片作为搜索库(gallery),其中也包括 408 个行人的图片作为干扰信息项。最终 DukeMTMC-reID 的数据构成训练集 16522 张、查询集 2228 张图片、 以及搜素库 17661 张图片。其命名规则与 Market-1501 数据集图片命名规则相同。
paper: Performance Measures and a Data Set for Multi-target,Multi-camera Tracking (ECCV 2016)
特征提取 feature extraction
图片预处理方法
无论是图像检索还是其他计算机视觉相关的任务都会多多少少涉及到图片预处理相关的方法,同样的图片预处理对于图像相关任务也有这重要的作用,往往简单的进行图片增强就可以提高网络的performance。因为由PyRetri而起,这边也主要介绍一下,PyRetri提供的预处理方法以及探索一下其在代码实现上有什么可以借鉴的亮点之处。
-
缩放
1)DirectResize:
功能:按指定大小resize
参数:目标size(w,h)\ 插值方式
2)PadResize:
功能:指定长边的长度,短边通过填充到相同大小resize
参数:长边长度\padding的像素值\插值方式
3)ShorterResize
功能:指定短边的长度,并保持原来图像宽高比进行resize
参数:短边长度\插值方式
-
裁剪
1)CenterCrop:
功能:从图片中心按指定大小进行裁剪
参数:指定的图片大小
2)TenCrop:
功能:按指定大小将原图进行上下左右中心裁剪,并进行翻转(默认水平)得到10张图片
参数:指定的图片大小
-
翻转
TwoFlip:
功能:返回原图和水平翻转后的图片
参数:图片
-
其他
1)ToTensor:
功能:将图片转为Tensor
注:PIL的图片size是(w,h) 转为的tensor是(c,h,w)
2)ToCaffeTensor:
功能:将图片转为适应在Caffe中预训练的模型
注:在PyTorch中图片的组织方式是PIL——RGB,而在Caffe中图片的组织方式是OpenCV——BGR
3)Normalize:
功能:使用特定的均值和方差来normalize tensor,减均值除方差
参数:指定的均值和方差
上述是PyRetri中提供的图片预处理的方法,简单看了代码基本上在torchvision.transforms的基础上进行的二次开发。从更大的层面看,在计算机视觉中的图片增强预处理方法远远不止上述所述。常见的数据增强方法概括上来说,包括:翻转、旋转、缩放、裁剪、平移、加噪声、随机擦除、颜色亮度对比度方面进行变化等等,更一般地,针对增强还可以采用一些生成方法来进行图片生成。
基础网络Backbone
在很多计算机视觉任务中都会使用源于分类的基本网络骨架,在此基础上再进行一些特定任务的扩展与延伸。发展至今,经典网络从最开始的AlexNet、VGG等到现在的通过NAS涌现的一些网络(例如EfficientNet),可选择的网络很多。对于基于深度学习的图像检索,在特征提取部分往往也是采用在数据集上训练好的经典网络,然后抽取某层的输出(最开始是全连接层、现在一般是中间层特征然后在进行融合)。PyRetri库中提供了VGG16和ResNet50(后续应该会增加更多),在其进行的性能试验中也是通过采用在不同的数据上面训练的这两个模型的比较。
经典网络介绍: https://blog.csdn.net/u014448054/article/details/102612195
PyRetri 提供的MODEL ZOO: https://github.com/PyRetri/PyRetri/blob/master/docs/MODEL_ZOO.md
特征融合Aggregation
深度学习最早应用到图像检索的特征提取中时,最常使用的是全连接层输出的特征描述。然而选用上层的语义层其实是不利于object retrieval,因为上层的语义层丢失了object的空间信息,并且多篇论文都从实验的角度说明了选取中间层的特征更利于object retrieval。
实际上,在选取中间层来表达特征的过程中,我们可以去掉全连接层,从而使得我们可以摆脱掉输入图像尺寸约束(比如224*224)的约束,而保持原图大小的输入。
通常,图像分辨率越大,对于分类、检测等图像任务是越有利的。因而,从这一方面讲,选取上层的全连接层作为特征,并不利于我们的object retrieval任务。一种可能的猜想是,上层全连接层的语义特征,应该更适合做全局的相似。
虽然中间层更适合于做object retrieval,但是在选用中间层的feature map作为raw feature的时候,我们面临的一个主要问题是:如何将3d的tensor转成一个有效的向量特征表示? 这就涉及到了一些特征融合处理的方式,在深度学习中,一般会采用池化的方式进行特征融合,接下来会详细地介绍一些常用的特征融合方法。
-
最大池化 max pooling
MAX pooling指的是对于每一个channel(假设有N个channel),将该channel的feature map的像素值选取其中最大值作为该channel的代表,从而得到一个N维向量表示。
-
求和池化 sum pooling
SUM pooling指的是对于每一个channel(假设有N个channel),将该channel的feature map的所有像素值求和,这样每一个channel得到一个实数值,N个channel最终会得到一个长度为N的向量。
-
全局平均池化 global average pooling
AVG pooling指的是对于每一个channel(假设有N个channel),将**该channel的feature map的所有像素值求和在除以像素个数求平均值,**这样每一个channel得到一个实数值,N个channel最终会得到一个长度为N的向量。
# feature.shape (b,c,h,w)
feature = feature.mean(dim=3).mean(dim=2)
-
SPoC:sum-pooled convolutional
这种特征融合方式在sum pooling的基础上面考虑到了ROI的思想。具体地,针对深度特征向量,假定坐标点的空间位置与权重服从二维高斯分布,中心点为 μ \mu μ,方差 σ \sigma σ为中心点距离最近边界的距离的三分之一。据此,通过特征点的空间坐标求出权重矩阵,在进行加权求和来进行特征融合。
# SPoC核心代码
h, w = feature.shape[2:]
sigma = min(h, w) / 2.0 / 3.0
x = torch.Tensor(range(w))
y = torch.Tensor(range(h))[:, None]
spatial_weight = torch.exp(-((x - (w - 1) / 2.0) ** 2 + (y - (h - 1) / 2.0) ** 2) / 2.0 / (sigma ** 2)) #求权重
feature = (feature * spatial_weight).sum(dim=(2, 3)) #加权求和
-
CROW pooling : Cross-dimensional Weighting 跨维加权池化
CROW pooling 也是基于ROI的思想提供的池化方法,通过构建Spatial权重和Channel权重,其能够在一定程度上加大感兴趣区域的权重,降低非物体区域的权重。1)针对Spatial Weight,考虑到通过卷积滤波,响应强的地方一般都是物体的边缘等,因而将多个通道相加求和后,那些非零且响应大的区域,也一般都是物体所在的区域,因而我们可以将它作为feature map的权重。计算公式如下:
S i j = ( S i j ′ ( ∑ m , n S m , n ′ a ) 1 a ) 1 b S_{ij}=(\frac{S'_{ij}}{(\sum_{m,n}S_{m,n}^{'a})^{\frac{1}{a}}})^{\frac{1}{b}} Sij=((∑m,n