作者:breezecheng、morajiang、lyleleeli,腾讯 WXG 应用研究员
微信识图已经在微信的扫一扫识物,微信聊天/朋友圈/公众号长按图片搜一搜等场景上线,并且从最初的电商类目(鞋子、箱包、美妆、服装、家电、玩具、图书、食品、珠宝、家具等),扩展到更加丰富的万物场景,囊括了植物、动物、汽车、红酒、地标、菜品、名画、商标、作业以及其他通用场景。在算法架构上,微信识图主要由三大核心步骤组成,即为主体检测 子类目预测 子类目细粒度同款检索,开发一个高性能的检测器对于前两个步骤至关重要,本文将主要介绍我们针对微信识图场景的数据多源异构特性而打造的后台检测器.
一. 物体检测的作用及难点
一般来说, 抛开手机端前置的一些预处理操作(比如手机静止判定, 清晰帧选取, 散点特效图), 检测器在整个识图流程中位于第一步, 即我们需要首先定位到用户视野中心所关注的物体, 将其从嘈杂的背景中扣取出来用于后续的细粒度物体识别. 业内众多的识图产品, 无一例外嵌入了物体检测算法. 那么如何设计一个高性能的物体检测器自然是大家都格外关注的一个点.
为了让大家更好的理解检测在整个识图算法架构中的作用, 我们这里将微信识图的整体框架展示在图 1.2 中, 大家对细节感兴趣的话可以, 可以浏览我们组之前的文章《微信扫一扫识物技术解析》[1]. 这里我们重点介绍物体检测部分, 它对主体检测和类目预测两个环节都起到重要作用. 这里大家可能容易跟学术界的物体检测概念混淆起来, 因为学术界的物体检测涵盖了物体定位和类目预测, 为何下面的架构图将其拆解成了两个模块, 这里主要是因为微信识图面向的是开集问题, 相对学术界的闭集检测问题(假定训练集中涵盖了测试集的所有物体类目), 我们需要处理用户的任何输入请求, 并返回精确的检测结果, 因而在类目预测阶段仅仅靠检测模型是不够的, 我们需要将检索匹配结果嵌入来综合预测物体的类目, 本文 3.6 章节我们会对该问题进行更加细致的阐述.
图1.2 微信识图整体算法架构
检测的作用不言而喻, 但是做好检测任务并不是一个简单的事情. 比如图 1.1 中百度识万物的检测器就因为将耳机 键盘 鼠标垫一起检测出来, 而导致后续将其误识别为办公桌. 微信识图面向的是万物识别, 我们将检测面对的难点和挑战总结为下面几点:
(1) 注意力问题. 为了优化扫一扫识物体验, 我们需要检测的物体是用户视觉中心关心的物体, 减少用户不必要的交互操作
(2) 开集检测问题. 适配用户任意输入请求(可能是从未见过的子类目)
(3) 标注成本问题. 项目落地钟物体检测的标注时间和金钱成本不容忽视
(4) 多源异构性问题. 这是最具挑战的一点, 我们多说一句. 多源性是指我们检测器需要处理不同来源的数据, 如室内嘈杂的办公桌, 室外空旷的草地, 用户随手上传的街拍数据, 卖家精心评测自家的电商数据, 不同来源的数据在光线, 清晰度, 尺度, 视角都变化巨大; 异构性则是根据我们对不同垂类的定位和检索要求来定义的, 如电商, 汽车, 动物我们一般要求框图是物体明显的边界, 而植物, 地标和菜品通常有可能是边界模糊, 需要涵盖绿叶, 背景和器皿, 红酒我们主要定位是酒标而不是酒瓶(酒标对红酒的识别更具判别性), 名画我们定位的是画作本身而不是相框(很多画作不带相框), 商标主要定位图案 logo(纯文字 logo 由 OCR 来完成, 暂时还未上线), 作业检测的目的是切分不同的题目(不同学科如英语, 数学题目的定义差异巨大, 不像电商等垂类有明确的主体概念), 结构迥异的垂类也就带来了更加严峻的困难样本检测问题, 长尾检测问题, 以及模型收敛问题, 参考图 1.3.
(5) 隐私, 传输流量和并发问题. 对于用户隐私图片如账单等图片自动判别不进行后续识图操作, 对用户高清图快速定位显著区域并抠图, 减少流量处理, 以及部署模型的精度和速度折中问题.
如何解决上述 5 大问题, 在介绍微信识图的检测算法之前, 我们先来回顾下学术界的物体检测算法.
图1.3 不同垂类对物体检测任务的定义
二. 物体检测在学术界的发展进程回顾
微信识图检测算法, 也正好逼迫自己好好理顺一下学术界的检测算法的发展脉络.
图2.1 R-CNN整体架构[2]
基于深度学习的物体检测算法的开山之作必然是 R-CNN[2], 我们先对其进行简单的介绍. R-CNN 核心模块包含: 1) 输入是基于传统 Selective Search 得到的候选 proposals; 2) backbone 采用当时主流的 AlexNet/VGG16 等模型; 3) 由于输入是 proposal, 直接复用分类任务设计的网络, 无 neck 设计; 4) 可以理解为典型的两阶段算法, 先得到候选位置, 在对候选位置进行分类和校准; 5) 依赖 NMS 等后处理输出最终的检测结果. 后续的物体检测算法基本都是对该框架的各个模块进行改进和优化, 我们借鉴 yolov4[10]的框架图来对目前主流的物体检测算法进行了归纳和串联, 如下图 2.2 所示. 这里不再对每种改进的细节进行赘述, 大家感兴趣可以找原文或者文章解读进行细致的了解.
图 2.2 物体检测的发展历程 (请点击放大查看)
尽管学术上的物体检测算法不断迭代升级, 在物体检测 benchmark 库 coco[30]上刷榜也是你追我赶, 但是距离微信识图的实际落地需求还有不少 gap:
(1) 学术上物体检测评测指标关注召回图片上所有物体(所有位置所有尺度的物体)以及检测框的重合度, 而我们实际落地更关心用户视觉中心感兴趣物体的定位和识别精度;
(2) 学术上物体检测大都面向闭集问题, 即训练集中物体类目和测试集物体类目一致, 而我们实际落地需求面向的是开集问题, 需要处理用户任意输入请求(很多从未见过的子类目);
(3) 学术上物体检测不需要考虑标注成本问题(直接采用开源已经标注好的数据库就行), 而我们需要快速支持业务端新增加的各种垂类识别请求;
(4) 学术上检测数据库基本拍摄风格较为一致, 而我们面对的是电商, 植物, 动物, 汽车, 酒标, 菜品, 地标, 商标, 切题等多源异构的数据, 对模型的泛化性要求更高;
(5) 学术上物体检测大都不需要考虑隐私, 传输带宽和并发量问题, 而我们服务于微信的海量用户, 需要充分考虑隐私图片禁止识别, 以及传输带宽和高并发问题。
基于上述 5 点问题, 我们提出了自己完整的物体检测架构,下面我们对其进行详细阐述。
三. 面向多源异构数据的物体检测模型
3.1 检测器整体架构
图3.1 微信识图检测器整体架构图
图 3.1 可视化了完整的微信识图检测器架构, 主要包含以下几个模块:
a.画面静止判断, 避免用户无意识打开微信扫一扫的误识别请求; b.清晰帧判断, 避免对模糊画面进行识别; c.移动端检测器, 快速完成画面的主体检测(二类检测), 对于无主体的画面不继续后续操作, 对于有主体的画面进行抠图传给后台检测, 抠图可以极大的降低流量贷款, 解决弱网识图问题; d.后台高精度检测器, 将垂类拆分成具有表观的物体和概念物体单独更新网络, 检测器采用多头输出模块, 全图多分类模块, 常用检测的 anchor 分类头部和回归头部; e.选框策略优化, 模拟用户视觉中心注意力; f.标题分类模型 bert, 辅助入库检测时类目预测; g.检索匹配模型, 辅助在线检测时类目修正; h.半监督算法标注检测数据库, 支持移动端检测器/后台检测器训练; i.后台检测器结果返回客户端; j.帧间跟踪; k.跳转判定. 下面我们对几个重要环节进行介绍.
3.2 检测数据标注
兵马未动, 粮草先行, 对于深度学习的时代更是如此, 对于移动端检测器和后台检测器, 都需要大量的检测框标注数据来支持模型的训练. 这里我们主要采用的是两阶段检测器算法 人工标注相结合的方法来进行快速标注, 如下图 3.2 所示. 我们主要是利用开源已有的检测标注数据库 人工标注的少量垂类库进行初始化训练 faster-rcnn[4], 然后利用该模型对大量的未标注的电商以及其他垂类数据库进行预测, 将高置信度的框直接保留, 中等置信度的框抠图出来进行人工校准类别(我们发现检测框的位置基本比较准确, 容易出错的是类别, 人工纠正类别可以大大加快校验的速度), 这些中高置信度的框作为 gt 直接更新下一轮模型的训练. 重复上述过程到未标注商品库全部标记完毕.
图3.2. 算法 人工辅助物体检测框快速标注
尽管上述算法大大加快了检测数据的标注效率, 但是依然存在不少可以改进的点. 1) 新扩充一个垂类, 依然需求人工标注不小规模的样本进行启动; 2) 置信度的阈值选取需要根据每个垂类来人工选择; 3) 人工修正中等置信度的 bbox 的类别在时间和金钱成本上依然不容忽视. 如何又快又方便的来支持一个新增垂类的检测框标注? 或许无监督预训练一个新垂类的检测模型(或者基于其他垂类 fintune), 在基础上构建半监督学习框架, 依赖极少量人工标注框来快速自监督学习和标注是个方向. 近期, 我们组内工作 UP-DETR[32]已经向前迈出了无监督预训练检测模型的第一步. 下一步如何探索基于极少量人工标注框的半监督检测算法将更加有意义.
图3.3 无监督检测模型预训练UP-DETR[32].
3.3 移动端快速检测
为了优化扫一扫识物的用户体验, 以及减少客户端向后台发送的流量, 我们首先开发了移动端主体检测模型. 该模型主要完成的是二类检测, 当用户扫一扫的视野里面没有发现物体的时候, 可以快速返回提醒用户对准电商/植物等我们支持的垂类数据, 避免无效的流量请求后台; 当视野里面有物体的时候, 移动检测器可以定位物体的大概区域, 对图片进行抠图后再发送给后台, 有利于减少流量, 提升弱网下的用户体验. 对移动端检测算法细节感兴趣的同学, 可以浏览我们组之前的文章《如何快?揭秘“扫一扫”识物的移动端物体检测》[31].
3.3 多标签分类识别
为了充分尊重隐私, 并且快速初步划分用户请求的垂类类目, 有助于针对性处理, 我们在检测器的整体架构中嵌入了全图多标签分类模块(一张图片包含多个类目的物体, 比如同时有动物/植物/汽车), 如图 3.2 所示. 对于判定为用户隐私的数据, 比如订单截图, 聊天截图等等, 我们会禁止后续识别操作, 返回空的识别结果, 而对于我们支持的电商/植物/汽车/题库等垂类, 我们可以辅助类目分类, 也可以帮助选择多源异构检测器的分支结果, 比如具有表观性的垂类如电商则选择第一条流的检测结果即为 bbox 检测, 而对于概念性的垂类如题库则选择第二条流的检测结果即为切题. 学术上的多标签分类模型一般采用的是分类架构设计, 相比纯分类模块的设计, 我们的模型则能够有效的吸收检测模块对物体位置的强注意力, 极大的提升了多标签分类头部的精度, 我们将实验对比效果列举如下表 3.1 所示.
表3.1 多标签分类模型精度对比
3.4 具有表观一致性的物体定位和识别
我们的后台检测器采用的是典型的双流设计, 分别用来支持具有表观一致性的物体检测, 和无表观一致性的概念物体检测(如切题等). 我们先讲述第一个, 也是通常意义下的物体检测. 这里我们对比了一些 benchmark 工作在垂类检测上的性能, 如下表 3.2 所示.
表3.2 表观一致性物体检测性能对比. *表示扩充了训练样本
权衡速度和精度之后, 最后我们选择的是 retinanet 的架构作为我们的检测模型, 虽然 ATSS[19]/PAA[20]引入能极大的提升正样本采样的质量, 提升检测的评测指标. 但是我们实际测试发现精度的提升更多来自于更多的小物体召回, 对于扫一扫识物而言, 我么更加关心的是用户视野中心的显著的物体, 小物体大都是我们要过滤掉的噪声, 因而引入 ATSS/PAA 模块, 反而增加了后处理的复杂程度, 因而实际使用中我们并没有采用 ATSS 或者 PAA 模块.
3.5 无表观一致性的概念体定位和识别
常见的物体检测, 同类之间都有很强的表观一致性, 但是对于我们面对的一些新的垂类比如题库(语文,数学,英语,物理,化学,生物,地理,历史,政治等), 商标(耐克, 星巴克, 车标) 等类内差距非常大, 更偏向概念层面的类别定义, 这时候检测任务的多源异构问题更加突出. 如果直接将这些垂类和电商等垂类混在一起训练, 发现模型完全不收敛.
为了解决多源异构数据的物体检测, 我们构造了图 3.1 中间方框中的检测模块. 主要有几个环节来稳定模型收敛: (1) 双流架构设计. 将所有的垂类拆分成两组数据, 一组是具有表观一致性的垂类, 一组是无表观一致性的概念体垂类, 两组数据独立交替更新参数共享的检测网络(只有 backbone 和 neck 共享, 头部不共享) (2) 全图分类模块加速模型收敛. (3) 梯度裁剪策略防止梯度爆炸.
其中(1)和(3)是不可或缺的, 我们发现缺少任何一个模块, 都无法让模型有效的进行收敛. 而模块(2)的引入在适应数据的 domain 差异性有一定的帮助.
3.6 选框策略及类目预测
扫一扫识物的检测区别通用意义的检测两个明显的特点就是我们需要关注用户视觉中心的显著物体, 另外就是我们需要处理开集的物体检测问题. 本章节我们重点介绍我们如何处理这两个问题.
对于第一个问题, 选择用户视觉中心的显著物体, 我们增加了一个选框策略模块, 如图 3.4 所示. 对于扫模式和相册模式(在线检测环节), 我们充分模拟用户的视觉注意力中心, 将检测框的位置, 置信度, 物体面积进行加权组合得到每个框的最终排序分数, 输出用户最有可能的想要扫描的物体. 但是由于该后处理模块是独立于网络的训练之外的, 需要花费大量的时间在调整参数和细节处理中. 后续我们将重点借鉴 GFocal[25,26]将置信度重新定义为结合了框位置, 标签分类, 面积来综合度量的一个指标, 更加自适应的来指导模型训练, 更有利于最终的选框策略. 对于离线入库模式来说, 视觉中心的定义是根据商家售卖商品的品牌来确定的, 比如图中是售卖百褶裙, 那么百褶裙就是需要检测的框, 而上衣/鞋子就是需要去除的干扰框, 如何将文本标题和检测框进行匹配起来, 有效的完成入库操作, 我们将重点借鉴 CLIP[33]来优化该模式下的选框策略.
图3.4 微信扫一扫识物不同模式下的选框策略
下图 3.5 所示. 后续我们小组对该方法进一步进行优化, 将检测的置信度, 检索的距离嵌入一个网络进行有效的融合, 得到最终的类别排序.
图3.5 检测框的类目预测修正
3.7 模型部署和加速
考虑到模型延时和并发, 我们对后台检测模型进行了加速, 如下图 3.6 所示. 我们对几个关键的耗时模块分别进行了加速处理, 如数据加载模块从 PIL/opencv 预处理切换到了 DALI 预处理, 模型前向模块进行了 tensorRT 的 int8 量化, 两个模块从串行改为并行处理. 这里需要注意 DALI 模块存在一些问题, 比如显存不稳定(需要将 resize 操作挪回到 cpu 操作, 稳定显存利用), 对传输的坏图无法捕捉异常(需要手动更改 DALI 的源代码进行嵌入异常捕捉模块).
图3.6 后台检测器加速
加速后的实际效果如下表 3.3 所示, 这里可以看到整个提速效果还是非常显著的. 这里有一点大家可能会疑惑, 为啥第三行的 trt_float32 的显存耗用会比 pytorch 版本的 baseline 多出 200M 的显存耗用, 这个问题我也查了很久, 目前还是不是特别肯定, 猜测是我们在实现 trt 量化的 c 代码中有多余的显存申请操作, 这个后续我们会继续查验该问题.
表3.3 检测模型加速效果
下一个版本我们将会继续对该检测模型进行加速, 采用更小更快的架构如 yolov5[34]来进行实验, 同时为了保证实时性的前提下进一步提升模型精度, 我们会嵌入蒸馏学习模块[35].
四. 总结和展望
本文重点介绍了微信识图的物体检测算法, 在解决更加实际的落地难点问题中进行的改进. 后续我们将重点在如何快速拓展新垂类检测, 如何进一步加速模型并提升精度, 如何进一步端到端学习选框策略等问题上进行发力.
五. 参考文献
[1] 微信扫一扫识物技术解析
[2] R. Girshick, et al. Rich feature hierarchies for accurate object detection and semantic segmentation. CVPR 2014.
[3] R. Girshick. Fast r-cnn. CVPR 2015.
[4] S. Ren, et al. Faster r-cnn: Towards real-time object detection with region proposal networks. NIPS 2015.
[5] J. Dai, et al. R-fcn: Object detection via region-based fully convolutional networks. NIPS 2016.
[6] Z. Li, et al. Light-head r-cnn: In defense of two-stage object detector. arXiv 2017
[7] J. Redmon, et al. You only look once: Unified, real-time object detection. CVPR 2016.
[8] J. Redmon, et al. YOLO9000: better, faster, stronger. CVPR 2017.
[9] J. Redmon, et al. Yolov3: An incremental improvement. arXiv 2018.
[10] A. Bochkovskiy, et al. Yolov4: Optimal speed and accuracy of object detection. arXiv 2020.
[11] W. Liu, et al. Ssd: Single shot multibox detector. ECCV 2016.
[12] T. Lin, et al. Focal loss for dense object detection. ICCV 2017.
[13] L. Hei, et al. Cornernet: Detecting objects as paired keypoints. ECCV 2018.
[14] C. Zhu, et al. Feature selective anchor-free module for single-shot object detection. CVPR 2019.
[15] T. Zhi, et al. Fcos: Fully convolutional one-stage object detection. ICCV 2019.
[16] R. Hamid, et al. Generalized intersection over union: A metric and a loss for bounding box regression. CVPR 2019.
[17] Z. Zheng, et al. Distance-IoU loss: Faster and better learning for bounding box regression. AAAI 2020.
[18] M. Tan, et al. Efficientdet: Scalable and efficient object detection. CVPR 2020.
[19] S. Zhang, et al. Bridging the gap between anchor-based and anchor-free detection via adaptive training sample selection. CVPR 2020.
[20] K. Kang, et al. Probabilistic anchor assignment with iou prediction for object detection. ECCV 2020.
[21] S. Liu, et al. Path aggregation network for instance segmentation. CVPR 2018.
[22] Q. Chen, et al. You Only Look One-level Feature. CVPR 2021.
[23] Z. Yang, et al. Reppoints: Point set representation for object detection. ICCV 2019.
[24] Y. Chen, et al. Reppoints v2: Verification meets regression for object detection." NIPS 2020.
[25] X. Li, et al. Generalized focal loss: Learning qualified and distributed bounding boxes for dense object detection. arXiv 2020.
[26] X. Li, et al. Generalized Focal Loss V2: Learning Reliable Localization Quality Estimation for Dense Object Detection. arXiv 2020.
[27] N. Carion, et al. End-to-end object detection with transformers. ECCV 2020.
[28] X. Zhu, et al. Deformable DETR: Deformable Transformers for End-to-End Object Detection. arXiv 2020.
[29] X. Zhou, et al. Objects as points. arXiv 2019.
[30] https://cocodataset.org/#detection-leaderboard
[31] 如何快?揭秘“扫一扫”识物的移动端物体检测: http://km.oa.com/group/24938/articles/show/413354
[32] Z. Dai, et al. UP-DETR: Unsupervised Pre-training for Object Detection with Transformers. CVPR 2021
[33] A. Radford, et al. Learning transferable visual models from natural language supervision. arXiv 2021.
[34] https://github.com/ultralytics/yolov5
[35] X. Dai, et al. General Instance Distillation for Object Detection. CVPR 2021