2

我已经使用 Microsoft 的 customvision.ai 服务训练了一个对象检测CoreML 模型。我将其导出以在我的应用程序中使用,以使用相机实时识别某些对象。然而,CoreML 模型输出一个 double 类型的 MultiArray。我不知道如何破译或使用这些数据,因为这是我第一次使用多维数组。我一直在尝试找出自定义视觉对象检测模型应该输出什么(例如 CGRect 或 UIImage),所以我知道我想将 MultiArray 转换为什么,但在 Microsoft 网站上的任何地方都找不到此信息。微软似乎有一个用于图像分类模型的演示应用程序,但没有用于对象检测模型的演示应用程序。

为了了解多维数组中可能包含的内容,我尝试将其打印出来并得到这个结果......

Double 1 x 1 x 40 x 13 x 13 array

我也试过打印.strides多维数组的元素并得到了这个......

[6760, 6760, 169, 13, 1]

我不知道这些信息是否真的有用,只是想给你们我到目前为止所做的一切。

所以,我的问题是这个 MultiArray 包含什么信息(它是 UIImage 还是 CGRect 之类的东西?还是不同的东西?)以及如何将这个多维数组转换为我可以实际使用的有用数据集?

4

3 回答 3

1

我没有使用 customvision.ai 服务,但我之前使用过对象检测模型。13x13 数组很可能是覆盖输入图像的网格。对于这个数组中的每个单元——通常对应于原始图像中的一个 32x32 像素块——有 40 个数字的预测。

这在一定程度上取决于 customvision.ai 使用哪种模型,这 40 个数字意味着什么。但通常它们包含一个或多个边界框的坐标以及类别概率。

如果模型是 YOLO(这很可能,因为它也有一个 13x13 的输出网格),每个单元格有多个预测。每个预测都有 4 个数字来描述边界框,1 个数字来描述这个边界框包含对象num_classes的概率,以及具有不同类别概率的数字。

(5 + num_classes) x num_predictions所以每个网格单元都有数字。如果模型对每个网格单元进行 5 次预测,并且您已经训练了 3 个类,那么您将获得(5 + 3)*5 = 40每个网格单元的数字。

请注意,我在这里做了很多假设,因为我对您的模型类型以及您训练过的对象类别一无所知。

这 40 个数字可能有也可能没有真正的边界框坐标。您可能需要编写额外的代码来“解码”这些数字。同样,此逻辑取决于模型类型。

我假设 customvision.ai 有一些关于如何执行此操作的文档或示例代码。

您还可以在我的几篇博文中阅读有关此主题的更多信息:

于 2019-01-20T17:29:56.757 回答
1

9 个月后,我在尝试解决这个确切问题时偶然发现了你的问题。今天找到了解决方案,我想我会发布它。

看看这个 github 示例。

https://github.com/Azure-Samples/cognitive-services-ios-customvision-sample/tree/master/CVS_ObjectDetectorSample_Swift

它使用了一个名为 MicrosoftCustomVisionMobile 的 Cocoapod。

该 cocoapod 包含 CVSInference 框架,该框架有一个类 CVSObjectDetector,它将为您完成解析 3 维 MLMultiArray 输出的所有繁重工作。您需要做的就是将 UIImage 提供给它以进行检测并运行推理。然后,您可以使用 CVSObjectDetector 的强类型属性读取检测到的标识符、它们的边界框和置信度。确保在绘制之前将坐标转换回您的视图空间!

如果您像我一样在 Xamarin 中工作,您可以使用 Sharpie 为 pod 创建 C# 绑定,然后您就可以开展业务了。

于 2020-08-27T21:25:06.243 回答
0

这是一个很晚的答案,但我遇到了同样的问题,这就是我的解决方案。你应该用类似的东西得到你的预测:

guard let modelOutput = try? model.prediction(input: modelInput) else {
    fatalError("Unexpected runtime error.")
}

然后,根据您在模型中定义的输出名称(此处名称为“Identity”): 在此处输入图像描述

您应该能够像这样访问多维数组中的数据:

for i in 0..<apoiOutput.Identity.count {
    print(modelOutput.Identity[i].floatValue)
}
于 2021-05-26T22:30:10.603 回答