提出问题
我们希望当我们检测的一个对象的时候,不仅仅是检测出它是一只狗这么简单,我们希望我们可以知道他是数据哪一类,比如是柯基、还是萨摩耶等。VOC数据集可以检测20种对象,但实际上对象的种类非常多,只是缺少相应的用于对象检测的训练样本。笔者尝试利用ImageNet大量的分类样本,联合COCO的对象检测数据集一起训练,使得YOLO即使没有学过很多对象的检测样本,也能检测出这些对象。
基本的做法就是使用COCO数据集用于检测模型的位置,使用Image Net分类数据集把检测到的对象准确的分类。如果是检测样本,训练时其Loss包括分类误差和定位误差,如果是分类样本,则Loss只包括分类误差
构建wordTree
对于一般的分类方法,数据集中有9000个对象,我们使用softmax分类器输出9000个单元就行的。但是当我们选用两个数据集(一个检测数据集,一个分类数据集)的时候会存在一个问题,那就是他们的分类不是完全互斥的,打个比方说,Coco的标签简单仅仅是属于哪一类“狗”还是“车”,但是ImageNet标签就比较详细,是汽车还是火车,这些都标记的十分清楚。因此在这里作者引入了一个多标签的分类模型(multi-label model)。
如上图所示的一样,作者通过使用wordnet知识图谱,构建了CoCo和ImageNet的标签关系的WordNet,包括根节点,叶子节点和分支,虽然对整体来说,这些对象不是相互互斥的但是每个节点的几个分支之间是相互互斥的,所以我们可在该层使用softmax分类器。
构建方法
我们设定一个根节点(physical object),然后找到CoCo和ImageNet中用于训练和测试的对象,将对象与WordNet的关系对比找到对应的节点,如果这个节点与根节点的路径只用一条,我们直接将这个路径添加到根节点上。如果这个节点有多个路径都可以到达根节点,我们则选择那个较短的路径。这样我们就构造出了TreeNet(如下图所示)。
怎么预测
标签的标注
就以往的标签相互互斥而言,会使用独热编码进行标记,检测对象对应的位置记为1,其他的位置记为0。但是对于这种分层标签我们该怎么做呢?我们以第一幅图为例子,比如我们要标记的对象是dog,我们就在该层中dog对应的位置记为1,然后将dog的上一层的对象mammal记为1,将mammal对应的上一层对象也记为1,依次类推,其余无关的位置记为0。
预测
如果我们想要计算特定节点的绝对概率,我们只需沿着路径通过树到达根节点,然后乘以条件概率。因此,如果我们想知道一张图片是否是Norfolk terrier ,我们需要计算
不过,为了计算简便,实际中并不计算出所有节点的绝对概率。而是采用一种比较贪婪的算法。从根节点开始向下遍历,对每一个节点,在它的所有子节点中,选择概率最大的那个(一个节点下面的所有子节点是互斥的),一直向下遍历直到某个节点的子节点概率低于设定的阈值(意味着很难确定它的下一层对象到底是哪个),或达到叶子节点,那么该节点就是该WordTree对应的对象
联合分类检测
既然我们可以使用WordTree组合数据集,就可以训练联合模型进行分类和检测。为训练出一个超大规模的检测器,使用了CoCo数据集中的所有的类,并且使用了ImageNet数据集中的前9000个类。还添加了ImageNet检测挑战中尚未包括的所有类。此数据集的相应WordTree有9418个类。由于ImageNet样本比COCO多得多,所以对COCO样本会多做一些采样(oversampling),适当平衡一下样本数量,使两者样本数量比为4:1。
YOLO9000依然采用YOLO2的网络结构,不过5个先验框减少到3个先验框,以减少计算量。YOLO2的输出是13 ∗ 13 ∗ 5 ∗ ( 4 + 1 + 20 ) 13*13*5*(4+1+20)13∗13∗5∗(4+1+20),现在YOLO9000的输出是13 ∗ 13 ∗ 3 ∗ ( 4 + 1 + 9418 ) 13*13*3*(4+1+9418)13∗13∗3∗(4+1+9418)。假设输入是416x416x3。
由于对象分类改成WordTree的形式,相应的误差计算也需要一些调整。对一个检测样本,其分类误差只包含该标签节点以及到根节点的所有节点的误差。比如一个样本的标签是dog,那么dog往上标签都是1,但dog往下就不好设置了。因为这个dog其实必然也是某种具体的dog,假设它是一个Norfolk terrier,那么最符合实际的设置是从Norfolk terrier到根节点的标签都是1。但是因为样本没有告诉我们这是一个Norfolk terrier,只是说一个dog,那么从dog以下的标签就没法确定了。
对于分类样本我们找到预测框中对象预测概率最大的框,该框就负责预测。