深度学习之 Cascade R-CNN

  • Zhaowei Cai, Nuno Vasconcelos. 《Cascade R-CNN: Delving into High Quality Object Detection》. CVPR 2018.
  • 论文链接:https://arxiv.org/abs/1712.00726
  • 代码链接:https://github.com/zhaoweicai/cascade-rcnn

前言

IOU阈值被用来定义正负例,当使用一个较低的IOU阈值训练object detector, 通常会导致noisy detection. 当提高阈值后发现性能会有所下降. 这主要可能是又两个原因:

  1. 当提升阈值之后正样本会"指数式地"减少,容易过拟合
  2. inference时存在mismatch的问题(即在train上取得最佳的IOU阈值对inference时产生的proposal并不能很好地进行回归)

本文提出的Cascade R-CNN主要就是为了解决此问题.

这篇文章是基于Faster RCNN进行改进的,Faster R-CNN网络只有一个RCNN网络,而Cascade RCNN将多个RCNN网络基于不同的IOU阈值进行级联,对检测的结果进行不断地优化。前一个RCNN网络的输出可以作为后一个RCNN网络的输入,越往后的检测模型,其界定正负样本的IOU阈值是不断上升的。 对这些逐级递增地proposal(原文称作hypotheses, 下同)resampling保证positive set的尺寸都相等, 这样能缓解过拟合问题(可能是因为逐级提升的缘故, 因此可以使用一些比较差的数据, 这样就扩充了positive set从而对过拟合缓解).

mismatch

  • 在training阶段,由于我们知道gt,所以可以很自然的把与gt的iou大于threshold(0.5)的Proposals作为正样本,这些正样本参与之后的bbox回归学习。
  • 在inference阶段,由于我们不知道gt,所以只能把所有的proposal都当做正样本,让后面的bbox回归器回归坐标。

我们可以想到training阶段和inference阶段,bbox回归器的输入分布是不一样的,training阶段的输入proposals质量更高(被采样过,IoU>threshold),inference阶段的输入proposals质量相对较差(没有被采样过,可能包括很多IoU<threshold的),这就是论文中提到mismatch问题,这个问题是固有存在的,通常threshold取0.5时,mismatch问题还不会很严重。

1. Introduction

R-CNN等模型常使用IOU阈值0.5, 这样会对positives的要求太过于loose, 着就会导致产生太多不达标的proposal(原文说法是noise bbox), 如图, 图中比较了0.5和0.7的差别:
在这里插入图片描述
(a)中u=0.5也是常用的正负样本界定的阈值,但是当阈值取0.5时会有较多的误检,因为0.5的阈值会使得正样本中有较多的背景,这是较多误检的原因;
(b)用0.7的IOU阈值可以减少误检,但检测效果不一定最好,主要原因在于IOU阈值越高,正样本的数量就越少,因此过拟合的风险就越大。

本文解决的重要思想是每一个单独的detector只对一个单独的IOU(原文称quality level)进行优化. 此前有类似的工作, 但本文的思想与其不同, 此前是对FP rate优化, 本文是对一个给定的IOU阈值优化.
在这里插入图片描述
(c)和(d)中的曲线是用来描述localization performance,其中横坐标表示输入proposal和ground truth的IOU值,纵坐标表示输出的proposal和ground truth的IOU值。红、绿、蓝3条曲线代表训练检测模型时用的正负样本标签的阈值分别是0.7、0.6、0.5。从(c)可以看出,当一个检测模型采用某个阈值(假设u=0.6)来界定正负样本时,那么当输入proposal的IOU在这个阈值(u=0.6)附近时,该检测模型比基于其他阈值训练的检测模型的效果要好。可以得出以下结论:

  • 只有proposal自身的阈值和训练器训练用的阈值较为接近的时候,训练器的性能才最好。
  • 如果两个阈值相距比较远,就会存在mismatch问题
  • 单一阈值训练出的检测器效果非常有限,单一阈值不能对所有的Proposals都有很好的优化作用。

那么很自然地想到能不能直接用较大的阈值(比如u=0.7)来训练检测模型呢?这样是不行的,从(d)显示,当RPN输出的proposal的IOU较小时,阈值u=0.5的RCNN检测器的效果要优于阈值u=0.6的RCNN检测器,当RPN输出的proposal的IOU较大时(接近0.6左右),效果相反。通常,单个IOU阈值的检测器处理其他级别(IOU阈值和proposal与ground truth的IOU相差较大,不在同一个level)不一定是最佳的。

这些观察表明,更高质量的检测要求检测器与其处理的假设之间的质量匹配更紧密,说的通俗一点就是,阈值高的检测器要求RPN输出的proposal与Ground truth的IOU也要高。

但是为了提高检测器的质量,仅在训练期间提高阈值u是不够的。。从(d)中u = 0.7的检测器可以看出,这会降低检测性能。问题在于,从proposal检测器出来的假设存在严重失衡(正负比例失衡,满足阈值条件的正样本数量很少),这种情况下容易导致过拟合。另一个原因就是inference时的mismatch问题。inference时RPN产生的proposal与ground truth一般不会很高,当检测器的网络的IOU阈值设的很高的时候,就会存在mismatch。

因此这条路是走不通的,所以就有了这篇文章的cascade R-CNN,简单讲cascade R-CNN是由一系列的检测模型组成,每个检测模型都基于不同IOU阈值的正负样本训练得到,前一个检测模型的输出作为后一个检测模型的输入,因此是stage by stage的训练方式,而且越往后的检测模型,其界定正负样本的IOU阈值是不断上升的。

为什么要设计成cascade R-CNN这种级联结构呢?

一方面:从(c)可以看出用不同的IOU阈值训练得到的检测模型对不同IOU的输入proposal的效果差别较大,因此希望训练每个检测模型用的IOU阈值要尽可能和输入proposal的IOU接近。另一方面:可以看(c)中的曲线,三条彩色曲线基本上都在灰色曲线以上,这说明对于这三个阈值而言,输出IOU基本上都大于输入IOU。那么就可以以上一个stage的输出作为下一个stage的输入,这样就能得到越来越高的IOU。总之,很难让一个在指定IOU阈值界定的训练集上训练得到的检测模型对IOU跨度较大的proposal输入都达到最佳,因此采取cascade的方式能够让每一个stage的detector都专注于检测IOU在某一范围内的proposal,因为输出IOU普遍大于输入IOU,因此检测效果会越来越好。

3. Object Detection

作者首先给了一张当时比较流行的方法示意图, 此图后文用到多次, 我们称之为结构图, 各大写字母含义图中也给出解释:
在这里插入图片描述
(a)是Faster RCNN,因为two stage类型的object detection算法基本上都基于Faster RCNN,所以这里也以该算法为基础算法。
(b)是迭代式的bbox回归,从图也非常容易看出思想,就是前一个检测模型回归得到的bbox坐标初始化下一个检测模型的bbox,然后继续回归,这样迭代三次后得到结果。(c)是Integral Loss,表示对输出bbox的标签界定采取不同的IOU阈值,因为当IOU较高时,虽然预测得到bbox很准确,但是也会丢失一些bbox。
(d)就是本文提出的cascade-R-CNN。cascade-R-CNN看起来和(b)这种迭代式的bbox回归以及(c)这种Integral Loss很像,和(b)最大的不同点在于cascade-R-CNN中的检测模型是基于前面一个阶段的输出进行训练,而不是像(b)一样3个检测模型都是基于最初始的数据进行训练,而且(b)是在验证阶段采用的方式,而cascade-R-CNN是在训练和验证阶段采用的方式。和(c)的差别也比较明显,cascade R-CNN中每个stage的输入bbox是前一个stage的bbox输出,而(c)其实没有这种refine的思想,仅仅是检测模型基于不同的IOU阈值训练得到而已。

3.1 Bounding Box Regression

我们知道bbox对于所框选的图片块 xxx 通常由四个坐标构成: b=(bx,by,bw,bh)\text{b} = (b_{x},b_{y},b_{w},b_{h})b=(bx,by,bw,bh), bbox regression就是将这个预测的bbox对实际bbox ggg 进行regress, 这个过程借助regressor f(x,b)f(x,b)f(x,b) 进行, 因此最终就是优化这样一个函数:

Rloc[f]=∑i=1NLloc(f(xi,bi),gi)R_{loc}[f] = \sum \limits_{i = 1}^{N}L_{loc}(f(x_{i},b_{i}),g_{i})Rloc[f]=i=1NLloc(f(xi,bi),gi)

其中 LlocL_{loc}Lloc 在R-CNN是一个 L2L_{2}L2 loss, 而在Fast R-CNN, 是一个 L1L_{1}L1 loss. 为了使预测尽可能与实际接近, LlocL_{loc}Lloc 实际操作一个距离向量:

Δ=(δx,δy,δw,δh)\Delta = (\delta _{x},\delta _{y},\delta _{w},\delta _{h}) Δ=(δx,δy,δw,δh)

其中:

δx=(gx−bx)/bwδy=(gy−by)/bhδw=log(gw/bw)δh=log(gh/bh)\delta _{x} = (g_{x}−b_{x})/ b_{w}\:\delta _{y} = (g_{y}−b_{y})/ b_{h}\:\delta _{w} = log(g_{w}/ b_{w})\:\delta _{h} = log(g_{h}/ b_{h}) δx=(gxbx)/bwδy=(gyby)/bhδw=log(gw/bw)δh=log(gh/bh)

想要指出的是, bbox regression中一般b差异不大, 那么就会使 LlocL_{loc}Lloc 很小, 为了提升他的effectiveness, 那么一般会使其归一化 N(0,1)\text{ }N(0,1) N(0,1), 也就是 δx′=(δx−μ)/σx\delta _{x}^{′} = (\delta _{x}−\mu )/ \sigma _{x}δx=(δxμ)/σx.

此前有工作argue单独用一次regression step of f定位精度不够, 因此他们就重复进行f regress:

f′(x,b)=f∘f∘⋯∘f(x,b)f^{′}(x,b) = f \circ f \circ ⋯ \circ f(x,b) f(x,b)=fff(x,b)

即所谓迭代bbox regression(iterative bounding box regression), 此方法对应上图中(b), 但此方法还是有两个问题:

  1. 从第一张图(c)的实验可以知道基于不同IOU阈值训练的检测模型对不同IOU的proposal输入效果差别比较大,因此如果每次迭代都用基于相同IOU阈值的训练数据训练得到的检测模型,那么当输入proposal的IOU不在你训练检测模型时IOU值附近时,效果不会有太大提升。regressorf 是在0.5的阈值训练, 对于更高阈值的proposal, regressor欠优化, 对于IOU大于0.85的proposal抑制尤为明显.

  2. 每次迭代之后的分布都在明显变化, 很可能初始分布较好, 但经过几次迭代之后反而表现更差了. 下图给出一例。下图是关于迭代式bbox回归在不同阶段的四个回归值分布情况(蓝色点),可以看出在不同阶段这4个值得分布差异较大,对于这种情况,一成不变的检测模型显然难以在这种改变中达到最优效果。

在这里插入图片描述
正因为其特性, 此方法需要一些后期处理. 此方法因此也是不稳定的, 通常迭代超过两次以后基本再无太大变化.

3.2 Classification

和先前的方法基本不变, 分类时对于proposal分成 M+1M + 1M+1 类, 其中第0类是bg, 预测结果 KaTeX parse error: Expected 'EOF', got '\right' at position 20: …}(x) = p(y = k|\̲r̲i̲g̲h̲t̲.x), 其中 yyy 是指被预测对象类别, 那么最终得到被优化的函数:

Rcls[h]=∑i=1NLcls(h(xi),yi)R_{cls}[h] = \sum \limits_{i = 1}^{N}L_{cls}(h(x_{i}),y_{i}) Rcls[h]=i=1NLcls(h(xi),yi)

这里 lclsl_{cls}lcls 是经典交叉熵损失.

3.3 Detection Quality

和以前一样, 当 proposal IOU 大于某个阈值, 则预测label y, 否则为bg(label y = 0). IOU设置高或低的优缺点此前已经讲过, 此前有通过结构图中©的做法对多level的输出计算损失并优化:

Lcls(h(x),y)=∑u∈ULcls(hu(x),yu)L_{cls}(h(x),y) = \sum \limits_{u \in U}L_{cls}(h_{u}(x),y_{u}) Lcls(h(x),y)=uULcls(hu(x),yu)

U就是多IOU阈值. 因此所有classifiers在推理过程中一起使用, 但有个关键问 题是不同classifier接收的positives的数量不同! 在下图中的左图就是这种情况, 首先高IOU样本数量太少, 很容易过拟合; 其次高预设IOU classifier又不得不处理众多不适宜的第IOU样本. 另外这张图也请牢记, 我们称之为分布图.

在这里插入图片描述

cascade-R-CNN在不同阶段预测得到的proposal的IOU值分布

Cascade R-CNN 和Integral Loss比较

Integral Loss共用pooling,只有一个stage,但有3个不共享的H,每个H处都对应不同的IoU阈值。Integral Loss存在的问题:

  • 我们从上图 proposal分布可以看到,第一个stage的输入IoU的分布很不均匀,高阈值proposals数量很少,导致负责高阈值的detector很容易过拟合。
  • 此外在inference时,3个detector的结果要进行ensemble,但是它们的输入的IoU大部分都比较低,这时高阈值的detector也需要处理低IoU的proposals,它就存在较严重的mismatch问题,它的detector效果就很差了。

4. Cascade R-CNN

结构如结构图所示.

Cascaded Bounding Box Regression

既然单个classifier很难适应多IOU, 那么作者就设计了顺序的多个classifier, 与iterative bounding box regression相对应, 本文的结构:

f′(x,b)=fT∘fT−1∘⋯∘f1(x,b)f^{′}(x,b) = f_{T} \circ f_{T−1} \circ ⋯ \circ f_{1}(x,b) f(x,b)=fTfT1f1(x,b)

这里每个 ftf_{t}ft 都是预优化过的,

它与iterative bounding box regression(IBBR for short)的不同有以下几点:

  • IBBR是对同一个网络重复迭代优化, cascaded regression是通过resample使每一级输出都能被下级使用.
  • cascaded regressor是既用于训练又用于推理, 那么训练集和推理集就不会有不匹配的情况了.
  • 每一级输出需要resample, 其后对每一级都会进行优化而不是向IBBR一样只是最终相当于对输入优化.

我想解释一下, 为什么输入为低IOU最后还会优出适应较高IOU的regressor, 这利用到全文第二张图的左图, 我再贴出来一边便于观察:

在这里插入图片描述

左图中我们可以看出输出在大多数情况都是好于输入的, 那么我们逐级递增地设置regressor, 最终输出的也就是单一regressor几乎不可能达到的高IOU.

Cascade Detection

在分布图中我们可以发现, 每一阶段处理之后分布重心都会向高IOU移动,这样有两个好处:

  1. 不容易过拟合.
  2. detector就可以对高IOU example训练, 而减轻以前的不匹配问题.

在每个阶段 ttt, R-CNN都要对classifierht hth_{t}ht 和regressorftftf_{t}ft在阈值 ut,ut>ut−1u^{t},u^{t} > u^{t−1}ut,ut>ut1 的状态下优化, loss为:

L(xt,g)=Lcls(ht(xt),yt)+λ[yt≥1]Lloc(ft(xt,bt),g)L(x^{t},g) = L_{cls}(h_{t}(x^{t}),y^{t}) + \lambda [y^{t} \geq 1]L_{loc}(f_{t}(x^{t},b^{t}),g) L(xt,g)=Lcls(ht(xt),yt)+λ[yt1]Lloc(ft(xt,bt),g)

其中 bt=ft−1(xt−1,bt−1)b^{t} = f_{t−1}(x^{t−1},b^{t−1})bt=ft1(xt1,bt1), g是 xtx^{t}xt 的ground truth. λ\lambdaλ 是调节参数. [yt≥1][y^{t} \geq 1][yt1] 是指只有不是bg时才计算 LlocL_{loc}Lloc.

Experimental Results

这里只使用了水平翻转, 在没有使用其他trick.

以下与各模型对比实验, 因为内容都比较直观, 以后可能不会补充对他们的分析.

在这里插入图片描述
在这里插入图片描述
cascade R-CNN和Iterative bbox、Integral loss的对比。
在这里插入图片描述
COCO数据集上的提升确实非常明显。主要通过在现有的two stage算法上添加cascade思想后的对比结果,另外还对比了训练、测试时间、参数量等信息。
在这里插入图片描述

Conclusion

正如一开始提到的两点问题, 作者在本文也是在尽力解决这些问题:

  1. 采用多阶段逐步提升IOU, 从而在低IOU样本中获取更多的"高IOU"样本。
  2. 对于最后一个阶段输出了高IOU样本, 训练classifier从而使其适应高IOU样本, 当其推理时对于高IOU的样本处理表现也更好。
  3. 每一个stage的detector都不会过拟合,都有足够满足阈值条件的样本。

参考:

  • https://blog.csdn.net/u014380165/article/details/80602027
  • https://www.cnblogs.com/edbean/p/11306577.html
  • https://zhuanlan.zhihu.com/p/92779720
  • https://zhuanlan.zhihu.com/p/42553957

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/453719.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

转换文档参数_明明2秒可以搞定Word、Excel相互转换,你却用了半小时!真亏了...

我们在用office三件套工作的时候&#xff0c;经常都需要对文件的格式进行转换&#xff0c;像是Word文档和Excel表格的转换&#xff0c;很多小伙伴都要花上半个小时甚至以上的时间才能搞定&#xff0c;效率实在不行。别担心&#xff0c;今天小编将分享能快速完成Word、Excel转换…

深度学习之 DCN(Deformable Convolution)-可变形卷积

Paper link: http://openaccess.thecvf.com/content_ICCV_2017/papers/Dai_Deformable_Convolutional_Networks_ICCV_2017_paper.pdfhttps://arxiv.org/pdf/1703.06211 Code link: https://github.com/msracver/Deformable-ConvNets Abstract 如何有效地对几何图形的变化进行…

软件开发 项目进展 软件架构 指南

软件开发&#xff0c;标准化流水线式开发的实施构想 软件开发&#xff0c;标准化流水线式开发的实施构想 近日看到一篇博文&#xff0c;讨论标准化流水线开发模式的话题&#xff0c;但是这篇博文仅仅提出这个问题&#xff0c;未见回应。 这其实是一个很大的问题&#xff0c;我…

c++ 舞伴配对问题_挑战新物体描述问题,视觉词表解决方案超越人类表现

编者按&#xff1a;最近&#xff0c;研究者们发布了 nocaps 挑战&#xff0c;用以测量在没有对应的训练数据的情况下&#xff0c;模型能否准确描述测试图像中新出现的各种类别的物体。针对挑战中的问题&#xff0c;微软 Azure 认知服务团队和微软研究院的研究员提出了全新解决方…

深度学习之双线性插值(Bilinear interpolation)

1. 什么是插值 Interpolation is a method of constructing new data points within the range of a discrete set of known data points. Image interpolation refers to the“guess”of intensity values at missing locations. 图片放大是图像处理中的一个特别基础的操作。…

深度学习之 OHEM (Online Hard Example Mining)

论文 《Training Region-based Object Detectors with Online Hard Example Mining》链接 https://arxiv.org/pdf/1604.03540.pdf Astract 摘要主要讲了四点&#xff1a; (1) 训练过程需要进行参数的空间搜索(2) 简单样本与难分辨样本之间的类别不平衡是亟需解决的问题(3) 自…

音视频 详解

avi文件格式详解 AVI是音频视频交错(Audio Video Interleaved)的英文缩写&#xff0c;它是Microsoft公司开发的一种符合RIFF文件规范的数字音频与视频文件格式&#xff0c;原先用于Microsoft Video for Windows (简称VFW)环境&#xff0c;现在已被Windows 95/98、OS/2等多数操…

c6011取消对null指针的引用_C++| 函数的指针参数如何传递内存?

函数的参数是一个一级指针&#xff0c;可以传递内存吗&#xff1f;如果函数的参数是一个一级指针&#xff0c;不要指望用该指针去申请动态内存。看下面的实例&#xff1a;#include using namespace std;void GetMemory(char *p, int num){p (char *)malloc(sizeof(char) * num…

深度学习目标检测之 YOLO v2

论文名&#xff1a;《YOLO9000: Better, Faster, Stronger》原文&#xff1a;https://arxiv.org/pdf/1612.08242v1.pdf代码&#xff1a;http://pjreddie.com/darknet/yolo/ YOLO v2 斩获了CVPR 2017 Best Paper Honorable Mention。在这篇文章中&#xff0c;作者首先在YOLOv1的…

深度学习目标检测之 YOLO v3

论文名&#xff1a;《YOLOv3: An Incremental Improvement》论文地址 https://pjreddie.com/media/files/papers/YOLOv3.pdfhttps://arxiv.org/abs/1804.02767v1 论文代码 https://github.com/yjh0410/yolov2-yolov3_PyTorchkeras&#xff1a;https://github.com/qqwweee/keras…

30本pdf完整版的经典Linux学习和开发教程和资料下载 android arm java 资料大全

史上最牛的Linux内核学习方法论 点击下载我的arm_linux移植笔记 点击下载S3C2440完全开发流程 点击下载Linux系统命令及其使用详解完整版 点击下载Linux主要shell命令详解 点击下载深入理解Linux内核(第三版 pdf英文版) 点击下载深入分析Linux内核源代码教程pdf完整版 点击下…

Fedex Ship Manager Software安装

本文出自Simmy的个人blog&#xff1a;西米在线 http://simmyonline.com/archives/552.html 这个软件的安装颇费了我一番周章&#xff0c;特地Log之。下载&#xff1a;http://www.fedex.com/apac_english/fsmsoftware/ 安装完后&#xff0c;接着输入用户信息&#xff0c;然后连…

【转】博客美化(3)为博客添加一个漂亮的分享按钮

阅读目录 1.社会化分享2.选择一个分享按钮3.添加到博客园博客博客园美化相关文章目录&#xff1a;博客园博客美化相关文章目录 在前2篇博客“博客美化(1)基本后台设置与样式设置”与"博客美化(2)自定义博客样式细节"中详细介绍了博客样式设置的相关问题&#xff0c;当…

深度学习目标检测之 YOLO v4

论文原文&#xff1a;https://arxiv.org/abs/2004.10934代码 原版c&#xff1a; https://github.com/AlexeyAB/darknetkeras:https&#xff1a;//github.com/Ma-Dan/keras-yolo4pytorch&#xff1a;https://github.com/Tianxiaomo/pytorch-YOLOv4 前言 2020年YOLO系列的作者…

[Android] 年年有鱼手机主题

自制的年年有鱼手机主题&#xff0c;希望大家喜欢&#xff01;~ 下载地址&#xff1a;https://yunpan.cn/cqauQbiM97idd &#xff08;提取码&#xff1a;d272&#xff09; 本文转自haiyang45751CTO博客&#xff0c;原文链接&#xff1a; http://blog.51cto.com/haiyang457/1…

mysql 小数做索引_10 分钟掌握 MySQL 的索引查询优化技巧

本文的内容是总结一些MySQL的常见使用技巧&#xff0c;以供没有DBA的团队参考。如无特殊说明&#xff0c;存储引擎以InnoDB为准。MySQL的特点了解MySQL的特点有助于更好的使用MySQL&#xff0c;MySQL和其它常见数据库最大的不同在于存在存储引擎这个概念&#xff0c;存储引擎负…

模块与包

一 模块介绍 1、什么是模块&#xff1f; #常见的场景&#xff1a;一个模块就是一个包含了一组功能的python文件,比如spam.py&#xff0c;模块名为spam&#xff0c;可以通过import spam使用。#在python中&#xff0c;模块的使用方式都是一样的&#xff0c;但其实细说的话&#x…

解决eclipse + pydev 编译过程中有中文的问题

最近在学习python编程&#xff0c;开发环境设置好了&#xff0c;是用eclipse pydev 来做开发的环境&#xff0c;配置好了之后&#xff0c;需要解决的一个关键问题就是老问题了&#xff1a;如何解决代码中的中文问题。。。 其实但我们在配置编程环境的时候&#xff0c;就需要设…

程序员的思考--终于确定了自己的技术发展方向

经过了将近5年的工作沉淀以后&#xff0c;终于确定了自己的职业发展方向。从现在开始终于可以有的放矢了&#xff0c;不再迷茫了。回想以往&#xff0c;找到这个方向&#xff0c;确实不是一件容易的事情&#xff0c;一路也是迷茫的走过来&#xff0c;随着知识和工作经验的积累&…

【原】iOS:手把手教你发布代码到CocoaPods(Trunk方式)

概述 关于CocoaPods的介绍不在本文的主题范围内&#xff0c;如果你是iOS开发者却不知道CocoaPods&#xff0c;那可能要面壁30秒了。直奔主题&#xff0c;这篇文章主要介绍如果把你的代码发布到CocoaPods代码库中&#xff0c;让别人可以使用“pod search yourOpenProject”命令查…