赞
踩
本页介绍了COCO使用的关键点评估指标。此处提供的评估代码可用于在公开可用的COCO验证集上获得结果。它计算下面描述的多个指标。为了在COCO测试集上获得结果,其中隐藏了实际真值注释,必须将生成的结果上传到评估服务器。下面描述的评估代码用于评估测试集的结果。
anns为标注信息,每条标注数据有一个标注Id,anns通过anns[ann['id']] = ann
实现某一条标注ann的id映射到该ann。即每个ann有一个唯一的id。
包含所有anno 的字典,有11004个键值对。key是anno的id,value是anno的值,也就是一条标注。
- ann={
- "segmentation": RLE or [polygon], # 分割信息
- "num_keypoints": int, # 标注的关节点数
- "area": float, # 标注区域面积
- "iscrowd": 0 or 1, # 是否是单人
- "keypoints": [x1,y1,v1,...], # 关节点信息,按照(x,y,v)的顺序排列,即坐标为(x,y),可见性为v; v=0,没有标注;v=1,有标注不可见(被遮挡);v=2,有标注可见
- "image_id": int, # 图片id
- "bbox": [x,y,width,height], # 图片中人的边框,这里x,y为边框的左上角的坐标
- "category_id": int, # 类别id,等于1表示人这一类
- "id": int, # 对象id(每个对象id都是唯一的,即不能出现重复)
- }
-
注意:
(1)新增的keypoints是一个长度为3*k的数组,其中k是category中keypoints的总数量,为17个。(1-‘nose’ 2-‘left_eye’ 3-‘right_eye’ 4-‘left_ear’ 5-‘right_ear’ 6-‘left_shoulder’ 7-‘right_shoulder’ 8-‘left_elbow’ -‘right_elbow’ 10-‘left_wrist’ 11-‘right_wrist’ 12-‘left_hip’ 13-‘right_hip’ 14-‘left_knee’ 15-‘right_knee’ 16-‘left_ankle’ 17-‘right_ankle’ )
每一个keypoint是一个长度为3的数组,第一和第二个元素分别是x和y坐标值,第三个元素是个标志位v,v为0时表示这个关键点没有标注(这种情况下x=y=v=0),v为1时表示这个关键点标注了但是不可见(被遮挡了),v为2时表示这个关键点标注了同时也可见。
(2)num_keypoints表示这个目标上被标注的关键点的数量(v>0),比较小的目标上可能就无法标注关键点。
ps:
iscrowd=0的时候,表示这是一个单独的物体,轮廓用Polygon(多边形的点)表示,iscrowd=1的时候表示两个没有分开的物体,轮廓用RLE编码表示,比如说一张图片里面有三个人,一个人单独站一边,另外两个搂在一起(标注的时候距离太近分不开了),这个时候,单独的那个人的注释里面的iscrowing=0,segmentation用Polygon表示,而另外两个用放在同一个anatation的数组里面用一个segmention的RLE编码形式表示
补充:
什么是RLE格式:
RLE:Run Length Encoding(行程长度压缩算法)
在机器视觉领域的深度学习中,每个数据集都有一份标注好的数据用于训练神经网络。
为了节省空间,很多数据集的标注文件使用RLE的格式,比如 kaggle 挑战赛的 Airbus Ship Detection Challenge。
但是神经网络的输入一定是一张图片,为此必须把RLE格式的文件转变为图像格式。
RLE用来表示二值图,里面有大量的0和1,所以很多重复,所以可以压缩,比如2*2的图像, [0,0;1,1] ,首先变成一维向量 [0,0,1,1] ,然后RLE标记[2,2], 上面提到的就是先用bbox得到图像位置,然后用RLE来标记,可以看到 is_crowd=1的时候bbox是整数
注意:
iscrowd=0那么segmentation就是polygon格式;只要iscrowd=1那么segmentation就是RLE格式。另外,每个对象(不管是iscrowd=0还是iscrowd=1)都会有一个矩形框bbox,矩形框左上角的坐标和矩形框的长宽会以数组的形式提供,数组第一个元素就是左上角的横坐标值。polygon格式比较简单,这些数按照相邻的顺序两两组成一个点的xy坐标,如果有n个数(必定是偶数),那么就是n/2个点坐标。
ploygon:这是对于单个对象来说的,表示的是多边形轮廓的写x,y坐标,肯定是偶数,如果有n个数,表示有n/2个坐标
RLE:size是图片大小,比如3*3
area是area of encoded masks,是标注区域的面积。如果是矩形框,那就是高乘宽;如果是polygon或者RLE,那就复杂点。
在一个annotation的实例中有两个id,其中image_id指的是这个annotation属于哪一张图片,即前面提到的图片的id,另外一个“id”指的是这个annotation的一个id。
注意: annotation的image_id是不唯一的,代表的是,这个annotation是指向image_id图片的标注,因为图片的标注不止一个,可能有好几个标注。
从person_keypoints_val2017.json文件中摘出一个annotation的实例如下:
- "annotations": [{
- "segmentation": [ # 对象的边界点(边界多边形)
- [125.12, 539.69, 140.94, 522.43, 100.67, 496.54, 84.85, 469.21, 73.35, 450.52, 104.99, 342.65, 168.27, 290.88, 179.78, 288, 189.84, 286.56, 191.28, 260.67, 202.79, 240.54, 221.48, 237.66, 248.81, 243.42, 257.44, 256.36, 253.12, 262.11, 253.12, 275.06, 299.15, 233.35, 329.35, 207.46, 355.24, 206.02, 363.87, 206.02, 365.3, 210.34, 373.93, 221.84, 363.87, 226.16, 363.87, 237.66, 350.92, 237.66, 332.22, 234.79, 314.97, 249.17, 271.82, 313.89, 253.12, 326.83, 227.24, 352.72, 214.29, 357.03, 212.85, 372.85, 208.54, 395.87, 228.67, 414.56, 245.93, 421.75, 266.07, 424.63, 276.13, 437.57, 266.07, 450.52, 284.76, 464.9, 286.2, 479.28, 291.96, 489.35, 310.65, 512.36, 284.76, 549.75, 244.49, 522.43, 215.73, 546.88, 199.91, 558.38, 204.22, 565.57, 189.84, 568.45, 184.09, 575.64, 172.58, 578.52, 145.26, 567.01, 117.93, 551.19, 133.75, 532.49]
- ],
- "num_keypoints": 10,
- "area": 47803.27955,
- "iscrowd": 0,
- "keypoints": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 309, 1, 177, 320, 2, 191, 398, 2, 237, 317, 2, 233, 426, 2, 306, 233, 2, 92, 452, 2, 123, 468, 2, 0, 0, 0, 251, 469, 2, 0, 0, 0, 162, 551, 2],
- "image_id": 425226,
- "bbox": [73.35, 206.02, 300.58, 372.5],
- "category_id": 1,
- "id": 183126
- },
- {
- #另一个annotations的信息
- }
- ......
- ],
cats为种类信息,每条种类数据有一个种类id,cats通过cats[cat['id']] = cat
实现种类cat_id到某条种类数据的映射。即每个种类都是有唯一的id。
包含所有的category的字典,有1个键值对。key是category的id,value是对应category的一些基本信息。对于行人检测的只有一个类来说,这里只有person。
最后,对于每一个category结构体,keypoints是一个长度为k的数组,包含了每个关键点的名字;skeleton定义了各个关键点之间的连接性(比如人的左手腕和左肘就是连接的,但是左手腕和右手腕就不是)。目前,COCO的keypoints只标注了person category (分类为人)。
categories是一个包含多个category实例的列表,而一个category结构体描述如下:
- {
- "supercategory": str, #主类别名 这里仅为person这一类别
- "id": int, #类对应的id (0 默认为背景)这里仅为1,person类别
- "name": str, #子类别
- "keypoints": [str], #每个关键点的名字
- "skeleton": [edge] #各个关键点之间的连接性
- }
从person_keypoints_val2017.json文件中摘出一个category的实例如下:
- cat = {'supercategory': 'person',
- 'id': 1,
- 'name': 'person',
- 'keypoints': ['nose', 'left_eye', 'right_eye', 'left_ear', 'right_ear', 'left_shoulder',
- 'right_shoulder', 'left_elbow', 'right_elbow', 'left_wrist', 'right_wrist',
- 'left_hip', 'right_hip', 'left_knee', 'right_knee', 'left_ankle', 'right_ankle'],
- 'skeleton': [[16, 14], [14, 12], [17, 15], [15, 13], [12, 13], [6, 12], [7, 13], [6, 7], [6, 8], [7, 9],
- [8, 10], [9, 11], [2, 3], [1, 2], [1, 3], [2, 4], [3, 5], [4, 6], [5, 7]]}
imgs为图片信息,每条图片数据有一个图片Id,imgs通过imgs[img['id']] = img
实现图片img_id映射到img。即每张图片有一个唯一的id。
包含所image的字典,有5000个键值对。key是image_id,value是image的基本信息。
- imgs={'license': 3,
- 'file_name': 'COCO_val2017_000000016744.jpg',
- 'coco_url': 'http://mscoco.org/images/16744',
- 'height': 335,
- 'width': 500,
- 'date_captured': '2013-11-20 14:29:03',
- 'flickr_url': 'http://farm3.staticflickr.com/2393/2228750191_11de3ec047_z.jpg',
- 'id': 16744
- },
- ..... 不断的重复 其他相同格式的数据
imgToAnns为图片的id,即img_id到图片对应的标注信息的映射,因为一张图片可能有多个标注,故该映射的默认值为list,通过imgToAnns[ann['image_id']].append(ann)
实现。即一张图片可以有多个标注。
image和anno的对应关系,imgToAnns有字典有1个键值对,其值为长度为11004的list对象,list中的每个元素都是Img_id,对应每条anns的img_id。key是image_id,value是一个包含了这张图片里所有anno的list。
catToImgs为种类id到属于该种类的具体图片的映射,因为一个种类可以对应多张图片,即一个类别映射到图片id,所以该映射的默认值为list,通过catToImgs[ann['category_id']].append(ann['image_id'])实现。即一个种类可以有多张图片。
category和image的对应关系,有2693个键值对,每个键为img_id,每个值为一个存放了1至多个ann标注信息的list。key是category,value是一个包含了有这个category的image的image_id。
取coco的几个具体标注例子,简单的代码示例如下:
- from collections import defaultdict
- anns,cats,imgs = {},{},{}
- imgToAnns, catToImgs = defaultdict(list), defaultdict(list)
-
- ann ={'segmentation': [[125.12, 539.69, 140.94, 522.43, 100.67, 496.54, 84.85, 469.21, 73.35, 450.52, 104.99, 342.65, 168.27, 290.88, 179.78, 288, 189.84, 286.56, 191.28, 260.67, 202.79, 240.54, 221.48, 237.66, 248.81, 243.42, 257.44, 256.36, 253.12, 262.11, 253.12, 275.06, 299.15, 233.35, 329.35, 207.46, 355.24, 206.02, 363.87, 206.02, 365.3, 210.34, 373.93, 221.84, 363.87, 226.16, 363.87, 237.66, 350.92, 237.66, 332.22, 234.79, 314.97, 249.17, 271.82, 313.89, 253.12, 326.83, 227.24, 352.72, 214.29, 357.03, 212.85, 372.85, 208.54, 395.87, 228.67, 414.56, 245.93, 421.75, 266.07, 424.63, 276.13, 437.57, 266.07, 450.52, 284.76, 464.9, 286.2, 479.28, 291.96, 489.35, 310.65, 512.36, 284.76, 549.75, 244.49, 522.43, 215.73, 546.88, 199.91, 558.38, 204.22, 565.57, 189.84, 568.45, 184.09, 575.64, 172.58, 578.52, 145.26, 567.01, 117.93, 551.19, 133.75, 532.49]], 'num_keypoints': 10, 'area': 47803.27955, 'iscrowd': 0, 'keypoints': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 309, 1, 177, 320, 2, 191, 398, 2, 237, 317, 2, 233, 426, 2, 306, 233, 2, 92, 452, 2, 123, 468, 2, 0, 0, 0, 251, 469, 2, 0, 0, 0, 162, 551, 2], 'image_id': 425226, 'bbox': [73.35, 206.02, 300.58, 372.5], 'category_id': 1, 'id': 183126}
- img = {'license': 2, 'file_name': '000000015335.jpg', 'coco_url': 'http://images.cocodataset.org/val2017/000000015335.jpg', 'height': 480, 'width': 640, 'date_captured': '2013-11-25 14:00:10', 'flickr_url': 'http://farm6.staticflickr.com/5533/10257288534_c916fafd78_z.jpg', 'id': 15335}
- cat = {'supercategory': 'person', 'id': 1, 'name': 'person', 'keypoints': ['nose', 'left_eye', 'right_eye', 'left_ear', 'right_ear', 'left_shoulder', 'right_shoulder', 'left_elbow', 'right_elbow', 'left_wrist', 'right_wrist', 'left_hip', 'right_hip', 'left_knee', 'right_knee', 'left_ankle', 'right_ankle'], 'skeleton': [[16, 14], [14, 12], [17, 15], [15, 13], [12, 13], [6, 12], [7, 13], [6, 7], [6, 8], [7, 9], [8, 10], [9, 11], [2, 3], [1, 2], [1, 3], [2, 4], [3, 5], [4, 6], [5, 7]]}
-
- anns[ann['id']] = ann
- imgs[img['id']] = img
- cats[cat['id']] = cat
-
- imgToAnns[ann['image_id']].append(ann)
- catToImgs[ann['category_id']].append(ann['image_id'])
-
- print(anns)
- print(imgs)
- print(cats)
- print(imgToAnns)
- print(catToImgs)
以下代码参考cocoapi:
- import json
- from collections import defaultdict
- annotation_file = '../../annotations/instances_val2017.json'
- dataset = json.load(open(annotation_file, 'r'))
- # print(dataset)
-
- #共有5类映射关系需要保存
- anns, cats, imgs = {}, {}, {}
- imgToAnns, catToImgs = defaultdict(list), defaultdict(list)
-
- print(dataset.keys())
- if 'annotations' in dataset:
- # for ann in dataset['annotations']:
- #第1条标注
- ann = dataset['annotations'][0]
- print(ann)
- print(type(ann))
- for k in ann.keys():
- print(k,ann[k])
- imgToAnns[ann['image_id']].append(ann) #根据image_id映射到对应的标注
- anns[ann['id']] = ann #根据标注id映射到对应的标注
- print(imgToAnns)
- print(anns)
- print(' ')
-
- if 'images' in dataset:
- # for img in dataset['images']:
- img = dataset['images'][0]
- print(img)
- print(type(img))
- for k in img.keys():
- print(k,img[k])
- imgs[img['id']] = img #根据image_id映射到对应的图片信息
- print(imgs)
- print(' ')
-
- if 'categories' in dataset:
- # for cat in dataset['categories']:
-
- cat = dataset['categories'][0]
- print(cat)
- cats[cat['id']] = cat #根据cat_id映射到对应的cat种类
- print(cats)
- print(' ')
-
- if 'annotations' in dataset and 'categories' in dataset:
- # for ann in dataset['annotations']:
- ann = dataset['annotations'][0]
- for k in ann.keys():
- print(k,ann[k])
- catToImgs[ann['category_id']].append(ann['image_id']) #根据种类的id映射到对应的图片的id。
- print(catToImgs)
包含person_keypoints_train2017.json和person_keypoints_val2017.json两个文件。
格式如下:
- info{
- "year" : int, # 数据集年份号
- "version" : str, # 数据集版本
- "description" : str, # 数据集描述
- "contributor" : str, # 贡献者
- "url" : str, # 数据集官方网址
- "date_created" : datetime, # 数据集创建详细时间
- }
-
- images{
- "id" : int, # 图像id
- "width" : int, # 图像宽度
- "height" : int, # 图像高度
- "file_name" : str, # 图像文件名
- "license" : int, # 许可证
- "flickr_url" : str, # flickr链接
- "coco_url" : str, # coco链接
- "date_captured" : datetime, # 拍摄时间
- }
-
- licenses{
- "id" : int, # license的编号,1-8
- "name" : str, # 许可证名称
- "url" : str, # 许可证网址
- }
-
- annotation{
- "segmentation" : RLE or [polygon], # 分割信息
- "num_keypoints" : int, # v=1,2的关键点的个数,即有标记的关键点个数
- "area" : float, # 面积
- "iscrowd" : 0 or 1, # 0时segmentation为polygon,1为REL
- "keypoints" : [x1,y1,v1,...],
- "image_id" : int,
- "bbox" : [x,y,width,height],
- "category_id" : int,
- "id" : int, # annotation的id,每个对象对应一个annotation
- }
-
- segmentation{
- "counts" : int,
- "size" : width,height,
- }
-
- categories{
- "supercategory" : str, # person
- "id" : int, # annotation的id,每个对象对应一个annotation
- "name" : str, # person
- "keypoints" : [str] # 长度为k的关键点名字符串
- ["nose","left_eye","right_eye","left_ear","right_ear",
- "left_shoulder","right_shoulder","left_elbow",
- "right_elbow","left_wrist","right_wrist",
- "left_hip","right_hip","left_knee","right_knee",
- "left_ankle","right_ankle"]
- "skeleton" : [edge], # 关键点的连通性,主要是通过一组关键点边缘队列表的形式表示,
- # 用于可视化.
- [[16,14],[14,12],[17,15],[15,13],[12,13],
- [6,12],[7,13],[6,7],[6,8],[7,9],[8,10],
- [9,11],[2,3],[1,2],[1,3],[2,4],[3,5],[4,6],[5,7]]
- }
包含COCO_test-dev2017_detr_detections.json和COCO_val2017_detr_detections.json两个文件。表示的需要读取的DETR检测框信息。格式如下:
- [{
- "image_id" : int,
- "category_id" : int,
- "bbox" : [x,y,width,height],
- "segmentation" : RLE or [polygon],
- "score" : float,
- "id" : int, # annotation的id,每个对象对应一个annotation
- "area" : float, # 面积
- "iscrowd" : 0 or 1, # 0时segmentation为polygon,1为REL
- }]
score表示人体检测框的置信度,得到过程如下:
给定一张图,运行目标检测程序(例如YOLO)后,总共有N个bounding box输出出来,可以通过非极大值抑制算法得到最后可靠的结果。大致分两步,第一步根据阈值去除那些置信度低的bounding box,然后进入一个循环,首先挑选出最大置信度的bounding box作为预测输出,然后去除那些与这个最大置信度的bounding box的IoU超过0.5的bounding box,因为我们可以看到一个对象有很多bounding box,它们很多是相交的,这样一个对象的bounding box就确定好了,然后,我们再进入循环,找出下一个对象的bounding box,最后直到没有剩余的bounding box,循环结束。
COCO关键点任务需要同时检测对象并将其关键点定位(对象位置不在测试时间给出)。由于同时检测和关键点估计的任务是相对较新的,我们选择采用受物体检测度量启发的新颖度量。为了简单起见,我们将这个任务称为关键点检测,将预测算法称为关键点检测器。我们建议在继续之前查看对象检测的评估指标。
评估关键点检测的核心思想是模拟用于目标检测的评估指标,即平均精确度(AP,average precision)和平均召回率(AR,average recall)及其变体。这些度量的核心是实际真实对象和预测对象之间的相似性度量。在对象检测的情况下,IoU(intersection-over-union,叫做交并比)作为这种相似性度量(对于框和片段)。IoU隐含定义了实际真实对象与预测对象之间的匹配,并允许计算精度召回曲线。为了采用AP / AR进行关键点检测,我们只需要定义一个类似的相似性度量。我们通过定义与IoU具有相同作用的对象关键点相似度(OKS,object keypoint similarity)来实现这一点。
对于每个对象,实际真值关键点具有形式,其中x,y是关键点位置,v是定义为的可见性标志。v = 0表示未标记,v = 1表示标记但不可见,v = 2表示标记且可见。每个地面真值对象也有一个比例尺s,我们将其定义为物体分段区域的平方根(Each ground truth object also has a scale s which we define as the square root of the object segment area)。有关实际真值格式的详细信息,请参阅下载页面。
对于每个对象,关键点检测器都必须输出关键点位置和对象级别的置信度(object-level confidence)。对象的预测关键点应该具有与实际真值相同的形式:。然而,在评估过程中,检测器的预测vi并不是目前使用的,即关键点检测器不需要预测每个关键点的可见度或置信度(visibilities or confidences)。
我们将对象关键点相似性(OKS)定义为:
v = 0,GT 没有点
v = 1,GT 有点但是看不见(被遮挡)
v = 2, GT 有点也看得见
为了计算OKS,我们通过一个非标准化的高斯将标准差传递给标准偏差
我们调整
为了获得感知上有意义和可解释的相似性度量,我们设置。通过设定,在
OKS是所有(标记的)对象关键点之间的平均关键点相似度。下面我们用来描绘预测的OKS分布,假设每个对象有10个独立的关键点(蓝色曲线),以及在双重注释数据(绿色曲线)上人类OKS得分的实际分布:
图像不完全匹配的原因有如下几个:
(1)对象关键点不是独立的,
(2)每个对象的标记关键点的数量是不同的,
(3)真实数据包含1-2%的异常值(大部分是是由于注释者误将左当成右或当两个人靠近时注释错误造成的)。
不过,这种行为大致如预期的那样。我们得出一些关于人类表现的结论
(1)在0.50的OKS中,人类的表现几乎完美(95%),
(2)人类的中位数为~0.91,
(3)在OKS为0.95后人类的表现迅速下降。请注意,此OKS分布可用于预测人类AR(因为AR不依赖于误报)。
Precision 精确率(查准率)。表示正确识别物体A的个数占总识别出的物体个数n的百分数Precision = TP / (TP+FP)
Recall 召回率(查全率)。表示正确识别物体A的个数占测试集中物体A的总个数的百分数Recall = TP / (TP+FN)
fp :false positive误报,即预测错误
fn :false negative漏报,即没有预测到
tp:true positive
tn:true negative
iou:intersection-over-union
Accuracy 准确率。正确分类的样本数除以所有的样本数,正确率越高,分类器越好。Accuracy=(TP+TN)/ (TP+TN+FP+FN)
以上介绍都是基于2分类的,并不是多分类的
以下10个指标用于表征COCO上的关键点检测器的性能:
Average Precision (AP):
AP % AP at OKS=0.50:0.05:0.95(primary challenge metric)
APOKS=.50 % AP at OKS=0.50 (loose metric)
APOKS=.75 % AP at OKS=0.75 (strict metric)
AP Across Scales:
APmedium % AP for medium objects: 322 < area < 962
APlarge % AP for large objects: area > 962
Average Recall (AR):
AR % AR at OKS=0.50:0.05:0.95
AROKS=.50 % AR at OKS=0.50
AROKS=.75 % AR at OKS=0.75
AR Across Scales:
ARmedium % AR for medium objects: 322 < area < 962
ARlarge % AR for large objects: area > 962
1)除非另有说明,否则AP和AR在多个OKS值(0.50:0.05:0.95)之间取平均值。
2)正如所讨论的,我们为每个关键点类型
3)AP(所有10个OKS阈值的平均值)将决定挑战胜利者。当考虑COCO的关键点性能时,这应该被认为是最重要的一个指标。
4)计算所有度量标准,每个图像最多允许20个最高得分检测(我们使用20个检测,而不是像对象检测挑战那样的100个,因为当前人是唯一具有关键点的类别)。
5)小对象(分段区域面积(segment area)<322)不包含关键点注释。
6)对于没有标注关键点的对象(包括人群),我们使用宽松的启发式方法,以允许根据幻觉关键点(hallucinated keypoints)(置于实际真实对象内以便最大化OKS)匹配检测结果。 这与使用框/段(boxes/segments)来忽略区域的处理非常相似。详细信息请参阅代码。
7)无论被标记的还是可见的关键点的数量如何,每个对象都具有相同的重要性。我们不过滤只有几个关键点的对象,也不会根据存在的关键点的数量来加权对象示例。
评估代码可在COCO github上找到。 具体来说,分别参见Matlab或Python代码中的CocoEval.m或cocoeval.py。另请参阅Matlab或Python代码(demo)中的evalDemo。在运行评估代码之前,请按结果格式页面上描述的格式准备结果,建议先看一下这个格式。
除了评估代码之外,我们还提供了一个函数analyze()来详细分析多实例关键点估计中的错误。这在Ronchi等人的多实例姿态估计的基准和误差诊断中(Benchmarking and Error Diagnosis in Multi-Instance Pose Estimation)被广泛地描述。代码生成这样的图像。
我们展示了来自Zhe Cao等人的2016年ECCV 2016关键挑战获胜者Pose Affinity Fields检测器的分析结果。
该图总结了所有类型的错误对多实例姿态估计算法的性能的影响。它由一系列精确召回(PR,Precision Recall)曲线组成,其中每条曲线保证严格地高于前面的曲线,因为该算法的检测在(任意的)OKS阈值为0.9时被逐步校正。图例显示曲线下面积(AUC,Area Under the Curve)。曲线如下(检查项目页面的完整说明):
1)Original Dts.:在OKS = 0.9(严格的OKS(strict KOS)下的AP)时,原始检测获得的PR,对应于APOKS=0.9度量的曲线下面积。
2)Miss:在所有遗漏错误(miss error)都被纠正之后,OKS = 0.9处的PR(严格的OKS下的AP)。缺失(miss)是一个很大的定位误差:检测到的关键点不在正确的身体部位附近。
3)Swap:在所有交换错误(swap errors)都被纠正之后,OKS =0.9处的PR(严格的OKS下的AP)。交换(swap)是由于图像中不同人的相同身体部分(即右肘right elbow)之间的混淆。
4)Inversion:在所有的逆误差(inversion errors)被纠正之后,OKS =0.9处的PR(严格的OKS下的AP)。倒置(inversion)是由于同一个人身体部位的混乱(即左右肘)造成的。
5)Jitter:在所有抖动错误(jitter errors)被纠正之后,OKS =0.9处的PR(严格的OKS下的AP)。 抖动(jitter)是一个小的定位误差:检测到的关键点在正确的身体部位附近。
6)Opt. Score:所有的检测算法在评估时使用oracle函数重新计算之后,OKS = 0.9处的PR(AP在严格的OKS)。在检测和实际真值之间匹配的数量重新计分达到最大值。
7)FP:所有背景误报(fps)被移除后的PR。 FP是一个阶跃函数,直到达到最大召回率为1,然后降到0(跨类别平均后曲线更平滑)。
8)FN:删除所有剩余的错误时的PR(微不足道的AP = 1(trivially AP=1))。
在上述检测器的情况下,OKS = 0.9的整体AP是0.327。纠正所有miss错误导致AP的大幅改善到0.415。修正swaps改善到0.488,修正inversions改善到0.545,获得较小的收益。当jitter错误被消除时,获得另一个大的改进,导致0.859的AUC。这显示了如果CMU算法具有关键点的完美定位,性能将会如何。在定位很好的情况下,置信度得分错误(confidence score errors)的影响并不显著,但仍然导致AUC提高约2%(0.879)。最佳评分检测大大减少了背景误报(Background False Positives)的影响,因为检测很少保持不匹配。最后,去除背景错报(Background False Negatives)提供了剩余的AUC以获得完美的表现。总之,在OKS = 0.9时CMU的错误主要是不完美的定位,主要是抖动错误和错过检测(missed detections)。
对于给定的检测器,代码共生成180个图,在3个区域范围(中,大,全)和10个评估阈值(0.5 :0. 05 :0.95)内分析所有错误。分析代码将自动生成一个PDF报告,其中包含总体性能总结,方法行为对不同类型错误的敏感性及其对性能的影响,以及几个最重要的失败案例。
注意:analyze()可能需要很长时间才能运行,请耐心等待。因此,我们通常不会在评估服务器上运行此代码,您必须使用验证集在本地运行代码。你可以在这个GitHub repository中找到analyze()函数。
用来存储预训练参数的文件。其中288为宽,384为高,宽高比为3:4。coco数据集存储方式如下:
- ${POSE_ROOT}
- `-- models
- `-- pytorch
- |-- imagenet
- | `-- hrnetv2_w32_imagenet_pretrained.pth
- |-- pose_coco
- | |-- deform_pose_transformer_res101_384x288.pth
- | |-- deform_pose_transformer_res50_384x288.pth
- | |-- pose_transformer_hrnet_w32_384x288.pth
- | |-- pose_transformer_hrnet_w32_512x384.pth
- | |-- pose_transformer_res101_384x288.pth
- | |-- pose_transformer_res101_512x384.pth
- | |-- pose_transformer_res50_384x288.pth
- | `-- pose_transformer_res50_512x384.pth
- `-- pose_mpii
- |-- pose_transformer_hrnet_w32_256x256.pth
- |-- pose_transformer_hrnet_w32_384x384.pth
- |-- pose_transformer_res101_256x256.pth
- |-- pose_transformer_res101_384x384.pth
- |-- pose_transformer_res101_512x512.pth
- |-- pose_transformer_res152_256x256.pth
- |-- pose_transformer_res152_384x384.pth
- |-- pose_transformer_res50_256x256.pth
- |-- pose_transformer_res50_384x384.pth
- `-- pose_transformer_res50_512x512.pth
用来存储模型超参数的文件。coco数据集一般如下:
- ${POSE_ROOT}
- |-- experiments
- `-- |-- coco
- `-- |-- transformer
- |-- w32_384x288_adamw_lr1e-4.yaml
- |-- w32_512x384_adamw_lr1e-4.yaml
- |-- res50_384x288_adamw_lr1e-4.yaml
- |-- res50_512x384_adamw_lr1e-4.yaml
- |-- res101_384x288_adamw_lr1e-4.yaml
- |-- res101_512x384_adamw_lr1e-4.yaml
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。