原文链接:高级使用
高级使用
本小节会更详细的描述评估指标,以及如何使用Core ML将模型部署到iOS或macOS应用程序中。
评估
如果在创建模型之前保留了标注的数据,你可以使用它来定量评估模型。你可以通过拆分数据来执行评估。
import turicreate as tc
train, val = data.random_split(0.8)
model = tc.object_detector.create(train)
scores = model.evaluate(val)
print(scores['mean_average_precision'])
0.23121281
请注意,如果我们使用训练数据来对模型进行评估,会得到一个明显高的分数,这个分数不能代表模型在新数据上的表现效果。让我们解释一下得分23.1%。当我们描述如何计算这个指标时,你将了解为什么很难获得高分。结果你可能会发现25%的mAP值表示的模型更具预测性。
首先,我们需要定义什么是正确的预测。你的模型不太可能给出与标注的边界框完全对应的边界框,因此我们需要衡量他们之间的接近程度。为此使用了一个称为intersection-over-union (IoU)
的分数。它是介于0%(无重叠)和100%(完全重叠)之间的值。如下所示
为了使预测被认为是正确的,它需要具有正确的类别标签和一个比预定阈值大的IoU分数。在例子中我们可以发现,如果不需要精确的定位,那么50%的阈值可能比较合适。如果两个或者多个预测的IoU值大于阈值,则只有一个预测被认为是正确的(true positive,TP),剩下的被认为是不正确的(false positive,FP)。模型完全没有标记出来的数据被归类为不正确的(false negative,FN)
基于这三种类型的预测(TP/FP/FN),我们可以计算精确度和召回得分。但是,在执行此操作之前,请记住该模型还会将每个预测和置信度相关联,置信度得分在0%和100%之间(记住包含两只狗的预测图片)。在计算TP/FP/FN之前,如果预测值的置信度低于置信度阈值,则该预测值不参与计算。代替手动设置置信度阈值,我们计算所有可能置信度阈值下的TP/FP/FN分数,然后对于每个置信度阈值计算出召回和精确度,连接成曲线。平均精度指的是精确度和召回曲线下的面积。平均精度指标按目标类别进行分别计算,最后去平均值的指标叫做mean average precision (mAP).
请记住,我们必须有一个IoU阈值才能计算mAP指标。mean_average_precision_50 (PASCAL VOC使用)表示IoU设置为50%。如果不需要精确的定位,可以使用mean_average_precision_50指标。但是,如果需要精确定位,则该指标可能无法区分模型是否有精确定位。为此,我们的主要指标计算方式是在50%至95%(以5个百分点为增量)的IoU阈值范围内再次平均mAP值。我们称该指标为mean_average_precision(COCO数据集使用)。在50%IoU阈值下评估为90%mAP的模型在其他IoU值下可能仅获得50%mAP值,因此,即使相对高质量的模型,mean_average_precision也会被计算出来一个较低的分数
Stacked 格式
预测值和标记的数据是一样的格式。每行代表一张图片和边界框,边界框位于在列表中。我们称这种格式为 unstacked格式。以stacked格式检查注释(预测值或者标记值)可能很有用。stacked格式每一行是一个单独的边界框。我们提供了两种格式之间转换的功能,如下所示:
predictions = model.predict(test)
predictions_stacked = tc.object_detector.util.stack_annotations(predictions)
print(predictions_stacked)
+--------+------------+-------+---------+---------+--------+--------+
| row_id | confidence | label | x | y | height | width |
+--------+------------+-------+---------+---------+--------+--------+
| 0 | 0.723 | dog | 262.220 | 155.497 | 73.928 | 90.453 |
| 0 | 0.567 | dog | 85.079 | 237.647 | 82.300 | 96.486 |
+--------+------------+-------+---------+---------+--------+--------+
你也可以转换回到unstacked格式:
unstacked_predictions = tc.object_detector.util.unstack_annotations(
predictions_stacked,
num_rows=len(test))
这可以使你以stacked格式排列标注数据,然后将数据转换为unstacked格式。num_rows
字段是可选的,如果你有不能被stacked格式表示的 TN(true negative) 图片时才需要该字段。返回的SArray unstacked_predictions
和predictions
的格式是一致的