
最近在整理细粒度图像检索FGIR方向的相关工作把这几年的论文笔记重新过了一遍。身边有好几个做电商、做相册应用、做安防的朋友都在问同一件事普通图像检索明明已经够用了为什么还要专门做细粒度图像检索他们遇到的实际问题很直接——搜车能搜出一大堆车的图但搜宝马五系还指望它跟搜宝马三系有区分度结果却几乎没有差别。这其实就是细粒度图像检索要解决的问题不只是判断这是一辆车而是进一步回答这到底是哪一款车。这个方向在 CV 社区里其实不算新但近几年因为电商找同款、车型识别、跨物种检索这些需求被反复拉出来讨论。我这次的论文阅读笔记系列第一篇先从整体框架入手把细粒度检索到底难在哪、方法怎么演进、复现时容易踩什么坑梳理清楚后续再逐篇拆具体工作。1. 细粒度图像检索到底在解决什么问题1.1 从找猫找狗到认品种传统图像检索解决的是类别层面的匹配问题用户给一张查询图系统从图库里找回同类的图像。这里面的类是很大的概念——猫、狗、车、飞机都属于粗粒度类别。做这类检索特征只要能把不同大类区分开就足够了哪怕是全局颜色分布、整体轮廓这种粗糙信息都能起到作用。细粒度图像检索把粒度往下踩了一层在同一个大类下面进一步区分不同的子类。同样是狗要区分哈士奇、阿拉斯加、萨摩耶同样是车要区分宝马 3 系和 5 系同样是鸟要区分绿头鸭和斑嘴鸭。这个难度完全不在一个量级因为类与类之间的差异往往只体现在很小的局部区域——比如鸟类的喙部颜色、翅膀羽色纹路汽车的进气格栅形状、大灯设计细节。如果拿一个典型的粗粒度检索模型直接去做细粒度检索效果通常很差。原因也不是模型笨而是训练目标根本没有给它细粒度语义的监督信号它学到的特征对这种微小差异不敏感。我给朋友的建议经常是你要先确认业务到底需要区分到什么粒度再考虑要不要上细粒度方案否则成本会高很多。1.2 细粒度检索和细粒度分类有什么不同这里很容易混淆值得单独说。细粒度图像分类Fine-Grained Visual Categorization, FGVC是给定一张图预测它的细粒度类别标签属于分类问题而细粒度图像检索是给定一张查询图从海量图库中找到同一子类的全部相关图像属于检索问题。它们共享很多技术底座比如特征提取和注意力机制但在评测方式和工程落地层面有明显差异维度细粒度分类细粒度检索任务形式单张图预测类别查询图在库中查找相关图像输出类别标签排序列表评估指标分类准确率 Top-1/Top-5mAP、PrecisionK、RecallK数据标注每张图要有类别标签除了标签还要定义匹配关系工程难点模型精度检索效率、特征存储、排序质量我在实际项目里发现有些团队会把检索问题强行套上分类模型的壳先做细粒度分类再输出类别标签去图库中筛选。这在类别数少、每类图像量大的场景下确实可行但一旦类别扩到上千甚至上万分类模型就难以处理高频新增类别检索模型的优势就体现出来了——它天然支持开放集合和动态更新新增图像只需要入库提取特征不需要重新训练分类头。1.3 细粒度检索难在哪细粒度检索的核心难点可以归纳为四个方面。第一是类间差异小。宝马 3 系和 5 系的整体轮廓几乎相同差异集中在进气格栅尺寸、前脸线条、C 柱倾角这些局部区域。模型必须学会把注意力放到这些对比性区域而不是笼统地提整体特征。第二是类内差异大。同一个子类在不同的拍摄角度、光照条件、遮挡和姿态下视觉表现差异可能比不同子类之间的差异还要大。这就要求特征表达具有一定的姿态和视角鲁棒性但同时又不能把所有变化都当成可忽略的噪声。第三是数据标注成本高。细粒度标签通常需要领域专家参与标注比如区分不同鸟种的人往往是观鸟专家造价远高于普通分类标签。这在工业场景里更头疼电商平台想按款式细分商品但人工标注海量 SKU 级别的视觉差异成本几乎是不可接受的。第四是检索本身的效率约束。真实检索系统面对的是百万级甚至亿级图库不能用穷举的方式跑一遍全图比对。这引出后文要讲的哈希方法以及如何用分类模型学到的特征做索引压缩。2. 传统方法里那些依然有价值的东西翻论文的时候有一个明显感受现在很多做深度学习的同学对传统方法不熟悉但细粒度检索领域有好几个核心思想都是从传统方法里长出来的不把源头梳理清楚看后面的深度论文会缺一根弦。2.1 手工特征加编码聚合的经典管线在深度学习普及之前细粒度检索的主流管线是局部特征提取 特征编码 聚合。局部特征通常是 SIFT它对旋转、尺度变化有一定鲁棒性能从图像中提取出大量的关键点描述子。但一张图可能有几千个 SIFT 描述子直接用这些离散向量做匹配计算量太大且非常零散。于是有了编码聚合这一步——把局部描述子聚合成一个固定长度的全局向量。最经典的三种编码方式是 BoW视觉词袋、VLAD 和 Fisher Vector。BoW 的思路是把局部特征聚类成若干个视觉单词然后用单词直方图表示图像。它的优点是简单缺点是量化误差大、信息损失严重。VLAD 在 BoW 基础上进一步保存了局部特征到聚类中心的残差向量信息量更丰富。Fisher Vector 更进一步用高斯混合模型拟合特征分布记录每个特征对每个高斯分量的期望得分。这三种编码里Fisher Vector 在细粒度检索上的表现通常最好因为它的特征表达维度更高、区分力更强但也带来了高维特征存储和计算开销。我记得当时做实验时Fisher Vector 的维度经常是几万维后面的检索索引还得另外设计。这个特征分辨力和计算开销的权衡在深度方法里也反复出现。2.2 局部部件信息才是细粒度的关键传统方法里有另一个重要分支显式利用局部部件part信息。细粒度识别的直觉是既然差异集中在局部区域那就干脆先检测出部件位置再对每个部件分别提取特征最后拼接或编码。当时比较有代表性的思路是用 part-based model 先定位鸟的头部、翅膀、胸部等部位然后对每个部位单独提取特征再融合。后来在检索任务上还有用 part-based k-meansPaK这类方法——把局部特征按部件聚类再结合几何约束做匹配。我记得当初看这些论文时最大的感受是思路朴素但逻辑成立部件定位提供了一种显式的注意力机制告诉模型该看哪里。这个思想对后续深度方法影响非常大后面讲的注意力机制本质上就是让网络自己学会定位与判别相关的部位只是把人工定义部件换成了自动学习。2.3 传统方法为什么最终被深度学习取代现在回看传统方法的瓶颈主要有三个。第一个是特征表达能力有限。SIFT 是通用的局部纹理描述子但并不是为细粒度语义设计的它捕捉不到宝马格栅和奔驰格栅风格差异这种高层语义。第二个是管线割裂、无法端到端优化。特征提取、编码、检索每一阶段都是独立设计、独立调参误差会逐级累积很难做全局优化。第三个是标注信息和领域知识利用不足。传统方法往往只用了图像层面的标签没有充分利用深度网络在强大的监督信号下提取特征的能力。深度卷积网络出来之后领域里很快就发现哪怕仅用 ImageNet 预训练的 CNN 网络提取特征配上再简单不过的 L2 归一化检索效果已经能超过精心设计的手工特征管线。这一下就把传统方法推到了边缘但传统方法探索出来的局部特征全局聚合部件注意力这两个重要框架一直被深度方法继承和升级。3. 深度学习方法的三条主线细粒度深度检索方向的论文非常多但剥开来看发展脉络可以归纳成三条主线特征表达、注意力机制、检索效率。每一条线都对应一个真实痛点。3.1 特征表达双线性池化与它的改进深度学习进入细粒度领域后第一个标志性突破是 Bilinear CNN。它提出的思路非常直接既然细粒度差异体现在局部特征的交叉组合上那就用两个特征提取网络分别提取特征然后对每个空间位置的特征向量做外积得到二阶统计信息。相比直接拼接两个网络的输出外积捕捉的是特征通道之间的共现关系能有效表达眼睛是黑色且爪子是黄色这类组合模式。但这篇论文的代价也很明显——外积之后特征维度瞬间膨胀在当时的算力下训练和推理都相当吃力。后续的紧凑双线性池化Compact Bilinear Pooling用 Tensor Sketch 或 Random Maclaurin Projection 把高维外积投影到低维空间在保住大部分表达能力的同时大幅降低计算和存储开销。我第一次看紧凑双线性那篇论文的时候有种原来数学工具还可以这么用的感觉。不过双线性池化这条线后来逐渐被注意力机制取代原因也不复杂它虽然捕捉了二阶特征交互但仍然是全局统一的特征交互没有给模型一个明确的该关注哪些区域的信号。在很多细粒度数据上不加注意力的模型容易把背景、干扰物体也纳入计算。3.2 注意力机制引导网络看到该看的地方注意力机制在细粒度识别里是一门显学。这条线我大致看了十几年间最核心的几篇工作。最早的想法从多粒度注意力开始比如递归注意力卷积神经网络RA-CNN——它用一个迭代过程逐步放大图像中判别性最强的区域相当于从全图到局部再到更细的局部每个尺度都做一次分类。这个由粗到细的思路跟人类识别过程很像先找到鸟在哪再看鸟头在哪最后看喙的颜色。多注意力 CNNMA-CNN则提出并行提取多个判别性部位让不同的注意力分支关注不同的区域这样可以同时抓住多个细粒度线索。相比之下RA-CNN 是串行的逐步聚焦MA-CNN 是并行的多区域捕捉两者各有侧重。我重点想提的是弱监督数据增强网络WS-DAN它把注意力机制从辅助分类带到了数据增强检索的方向。WS-DAN 的思路是用注意力图生成多种局部裁剪把这些局部区域和原图一起送入网络训练让模型在每个部分都能学到判别性特征。文章还提出用注意力图做特征融合这在检索任务里非常直接有效——在 CUB-200-2011 这类标准细粒度数据集上WS-DAN 的特征做检索效果比同时期的很多方法都好。在论文里WS-DAN 同时优化了分类损失和注意力图的多样性约束前者保证特征有语义判别力后者防止多个注意力分支都盯着同一个部位。这个设计思路放到今天的自监督方法里也依然适用。3.3 深度哈希细粒度检索的工程落地问题检索方向一直有个隐藏的工程问题——特征向量一般有几百上千维用浮点数存储和计算在海量图库中开销巨大。深度哈希方法的目标是把图像映射成一段短的二进制码比如 32 位、64 位既能极大压缩存储又能用汉明距离快速计算相似度。细粒度场景下的哈希比普通哈希更困难因为二进制码的信息容量有限而细粒度差异又极其微小。我看过的多篇哈希论文都在同一件事上挣扎如何在二值化的强约束下保住特征的判别力。DSH 的思路是在训练过程中逐步逼近二值输出HashNet 则用连续化的方式解决二值化的病态梯度问题。这些工作放到细粒度检索里效果确实还和全精度特征有明显的差距所以检索效率和检索精度的权衡始终贯穿这个子方向。3.4 度量学习的隐性关联除了显式的网络结构创新深度度量学习对细粒度检索的推动同样不能忽略。这里的核心改变在于损失函数——从单纯用 Softmax 分类头学特征过渡到用 Triplet Loss、Contrastive Loss、Proxy-based Loss 直接优化特征空间的同类靠近、异类排斥。细粒度检索特别喜欢用度量学习的原因是检索本身没有固定的类别边界而度量学习恰好能在特征空间中拉近同款车的距离。分类 Softmax 本质上是把特征推向类别中心的某个超平面分区不保证类内紧致而三元组、代理损失等方法则直接构造正负样本对来塑造特征空间。我看论文时注意到一个趋势前几年大家都在拼注意力模块怎么叠、池化怎么设计最近一两年则明显转向了多模态和自监督。但不管怎么变它们的底层都离不开特征表达 距离度量的框架。4. 复现这些论文时我踩过的实际坑泛泛读论文和动手复现是两回事。这个方向论文一对一的坑非常多我把印象最深的几个记在这篇笔记里当做给后面自己的提醒。4.1 数据集评估协议不一致是最容易翻车的地方细粒度检索方向的论文常用数据集包括 CUB-200-2011鸟类200 类11788 张、Stanford Cars196 类16185 张、Stanford Dogs120 类20580 张、FGVC-Aircraft100 类10200 张。看起来大家用的是同一个数据集但实际跑出来的结果不一定能互相比较。原因是每个工作用的划分方式、查询集和图库的构建策略可能完全不同。以 CUB 为例一种常见做法是每类随机取一部分作为查询集其余作为图库另一种做法是保证查询图库同类别但不含完全相同的图像。这两种设置下的 mAP 数值会差异很大。还有数据集里有大量同物种不同个体的图有的论文把同个体不同姿态的图也视为相关检索目标有的则把它们当成无关项——这直接影响 gt 构建和最终结果。我的建议是复现论文前一定要先看代码和文档里有没有明确说明评测设置只看论文里写的数据集名是不够的。为了给读者一个直观概念我把几个数据集的基本情况整理成表数据集类别数图像总数任务特点CUB-200-201120011788鸟类细粒度标准数据集Stanford Cars19616185车型细粒度标准数据集Stanford Dogs12020580犬类细粒度数据集FGVC-Aircraft10010200飞机型号细粒度数据集4.2 训练策略比网络结构更敏感复现细粒度论文时我碰到的最大问题不是模型结构搭不出来而是训练策略的细节差异带来的效果波动。细粒度数据集通常规模不大很容易过拟合所以训练细节格外关键。第一种常用技巧是迁移学习。绝大多数论文都用 ImageNet 预训练模型做初始化在实际复现时训练下游细粒度任务的学习率通常要比从头训练小很多尤其是骨干网络部分。我习惯把骨干网络学习率设为新加模块的 0.1 倍或者一开始冻结骨干网络只训练新模块等损失下降稳定后再解冻微调效果比一上来就全网络大学习率训练稳定得多。第二种是数据增强。细粒度检索任务里随机裁剪、水平翻转、随机擦除Random Erasing几乎成了标配。随机擦除在细粒度场景下尤其有用因为擦除部分区域可以迫使网络关注多个判别性部位而不会把注意力完全集中在某一个局部特征上。我在 CUB 上做过对比实验加入随机擦除后检索 mAP 有明显提升这其实是一种隐性的多局部特征学习。第三种是损失函数组合。只用一个 Softmax 分类损失时特征空间的类内紧凑性往往不够检索效果差强人意。把 Softmax 和 Triplet Loss 组合使用或者改用 Proxy-based 损失通常会有更好的特征度量性。这两个损失的权重、温度参数、样本挖掘策略都需要调。三元组样本挖掘用难样本挖掘Hard Mining效果好但训练初期容易导致模型坍塌我习惯先跑 Softmax 预热几个 epoch 再加 Triplet 权重。4.3 从 mAP 到真正好用之间的工程鸿沟论文里报的是 mAP但工业场景里用户更关心的是我搜一双鞋前排结果里有没有同款不同色的那一双。这中间隔着工程问题。一个问题是特征的归一化。论文里很多方法都要求对特征做 L2 归一化再用内积或余弦距离度量但实际部署时如果只存原始特征向量、忘记在查库阶段做同样处理检索质量会剧烈下降。这类问题在论文里几乎不会写但一到工程联调必现。另一个问题是检索分阶段策略。当图库很大时通常先用全局特征做粗召回把候选集从百万级缩小到几千级然后再用细粒度特征甚至局部特征做精排序。这个两阶段策略和纯论文环境下的全库比对不一样但效果、效率和可解释性都好很多。细粒度检索在这个体系里的定位往往是精排序阶段的特征来源。实时性是第三个容易忽略的点。电商场景下商品上新、下架频繁图库特征需要增量更新。哈希方法在这里的价值很大二进制码的存储和更新要比浮点特征廉价得多。但在充分训练之前别指望哈希方法能直接达到全精度特征的水平工程上要在数据库索引结构和模型设计两个层面共同推进。4.4 评测指标计算的隐蔽细节如果不想在评测上栽跟头mAP 的计算细节必须抠清楚。很多人理解 mAP 就是对每个查询算平均精确率再对所有查询取平均但真到代码实现时会发现很多细节问题重复图像是否要从图库中移除、同一图像是否既出现在查询集又出现在图库中、所有查询的精确率均值是直接平均还是按类别加权平均。这些细节只要有一个和论文代码不一致复现出来的数字就和报告差上一截。更隐蔽的是多对一匹配的情况。在检索任务里一个查询图可能对应图库中的多张相关图。有的工具包在 ranking 时只取第一个匹配位置计算 AP有的则取全部相关位置。这在小规模实验里差别可能不大但放到细粒度数据集上一个查询往往对应十几张相关图算法实现一旦写错指标整体就会掉好几个点。强烈建议复现时对照原论文官方评测代码的输入输出逐步核对宁可慢一点也不要凭自己对文字描述的想象写评测函数。5. 第一篇论文笔记的取舍与后续计划为什么第一篇要写这么散的内容我的想法是细粒度图像检索这个方向横向跨度很大如果不先把整个领域的地图、常见方法、评测陷阱讲清楚直接一头扎进某一篇具体论文里很容易迷失在模型结构的细节中看不到方法之间真正的承继关系。我之前写技术笔记时经常犯一个毛病把论文公式从头抄到尾看似详尽实际上没有形成自己的思考。这次整理笔记我给自己的筛选原则有三条。第一是优先级排序优先记录那些被后续工作大量引用的方法而不是单纯看发表时间或题目炫酷程度。双线性池化被注意力方法超越但它的特征交互思想至今影响还很大这类就值得多写。第二是关联性串联每篇论文都要刻意去想它解决了什么问题又引出了什么问题。RA-CNN 解决了细化尺度的问题却引入了计算开销大的问题后来又催生了更轻量的注意力计算方式。第三是工程导向凡是跟落地检索系统相关的细节比如评测协议、特征归一化、索引设计都要记录得更仔细因为它们普遍是论文里最容易带过、实际中最容易掉进去的坑。接下来几篇笔记我计划把 R-MAC基于区域最大激活的卷积特征聚合的全过程梳理一遍然后逐篇拆解注意力机制在细粒度检索中的具体设计之后再补一篇哈希方法在细粒度场景下的实验对比。这几条线基本覆盖了细粒度检索从特征提取到索引再到排序的核心链路拆透之后再做新方向的研究就会顺很多。关于细粒度检索这个方向我目前最深的体感是它不是一个单点技术而是一套从注意力到特征度量再到检索工程的组合拳。论文里再花哨的结构落到业务里最终都要经受两个考验——特征到底能不能区分目标子类以及这套系统在海量数据下能不能跑得起来。这个方向后续能延展的空间还挺大的比如用文本描述辅助细粒度检索、开放集条件下的细粒度检索、结合大模型做统一的细粒度理解与检索这些都在我接下来的观察清单里。