Coremltools:不能在后续层中使用非最大抑制层的某些输出



编辑:这似乎是Coremltools中的一个错误。请参见此处:https://github.com/apple/coremltools/issues/691#event-3295066804


一句话总结:非最大抑制层输出四个值,但我只能使用这四个值中的两个作为后续层的输入。

我正在使用Apple的Core ML Tools包构建一个神经网络模型,并添加了一个非最大值抑制(NMS(层。根据文档,该层有四个输出:

  • 输出1:方框坐标,对应于幸存的方框
  • 输出2:盒子分数,对应幸存的盒子
  • 输出3:幸存盒子的索引[这是我想在后续层中使用的输出]
  • 输出4:NMS算法之后选择的框数

我已经用一些简单的输入建立了一个测试模型,NMS层正确地为上面列出的四个输出中的每一个返回期望值。如果我在后续层中使用输出#1或输出#2,我这样做没有问题。然而,如果我试图在后续层使用输出#3或输出#4,我会得到一个错误,说输入"在前面层的任何输出中都找不到">

Jupyter笔记本

复制这个问题最简单的方法是下载并浏览这个Jupyter笔记本。

或者,下面的示例代码也将介绍我遇到的问题。

示例代码

我设置了一些样本输入数据如下:

boxes = np.array(
[[[0.00842474, 0.83051298, 0.91371644, 0.55096077],
[0.34679857, 0.31710117, 0.62449838, 0.70386912],
[0.08059154, 0.74079195, 0.61650205, 0.28471152]]], np.float32)
scores = np.array(
[[[0.87390688],
[0.2797731 ],
[0.72611251]]], np.float32)
input_features = [('boxes', datatypes.Array(*boxes.shape)),
('scores', datatypes.Array(*scores.shape))]
output_features = [('output', None)]
data = {'boxes': boxes,
'scores': scores }

我构建了如下测试模型:

builder = neural_network.NeuralNetworkBuilder(input_features, output_features, disable_rank5_shape_mapping=True)
# delete the original output, which was just a placeholder while initializing the model
del builder.spec.description.output[0]
# add the NMS layer
builder.add_nms(
name="nms",
input_names=["boxes","scores"],
output_names=["nms_coords", "nms_scores", "surviving_indices", "box_count"],
iou_threshold=0.5,
score_threshold=0.5,
max_boxes=3,
per_class_suppression=False)
# make the model output all four of the NMS layer's outputs
for name in ["nms_coords", "nms_scores", "surviving_indices", "box_count"]:
builder.spec.description.output.add()
builder.spec.description.output[-1].name = name
builder.spec.description.output[-1].type.multiArrayType.dataType = ft.ArrayFeatureType.FLOAT32
# # add a linear activation layer (intentionally commented out)
# builder.add_activation(
#     name="identity",
#     non_linearity="LINEAR",
#     input_name="surviving_indices",
#     output_name="activation_output",
#     params=[1.0,0.0])
# initialize the model
model = coremltools.models.MLModel(builder.spec)

此时,当我呼叫时

output = model.predict(data, useCPUOnly=True)
print(output)

一切如预期。

例如,如果我调用print(output['surviving_indices'],结果是[[ 0. 2. -1.]](正如预期的那样(。

但是,我不能使用surviving_indicesbox_count输出作为后续层的输入。例如,如果我添加了一个线性激活层(通过取消上面的块(,我会得到以下错误:

Input 'surviving_indices' of layer 'identity' not found in any of the outputs of the preceding layers.

如果我使用box_count输出(即,通过在add_activation层中设置input_name="box_count"(,我也会遇到同样的问题。

我知道NMS层正确地返回名为surviving_indicesbox_count的输出,因为当我调用print(builder.spec.neuralNetwork.layers[0])时,我得到以下结果:

name: "nms"
input: "boxes"
input: "scores"
output: "nms_coords"
output: "nms_scores"
output: "surviving_indices"
output: "box_count"
NonMaximumSuppression {
iouThreshold: 0.5
scoreThreshold: 0.5
maxBoxes: 3
}

此外,如果我使用nms_coordsnms_scores输出作为线性激活层的输入,我就没有任何问题。它将从NMS层的输出中正确输出未修改的nms_coordsnms_scores值。

我很困惑为什么NMS层正确地输出了我想要的内容,但随后我无法在后续层中使用这些输出。

问题似乎已经解决。使用升级

pip install coremltools>=5.0b3

根据CoreMLTools团队成员的评论:

  • https://github.com/apple/coremltools/issues/691#issuecomment-900673764

我的macOS是11.3,我使用的是coremltools版本5.0b3。

请确认一切都已修复。请在Big Sur或Monterey测试版上安装coremltools==5.0b3,然后验证您不再看到此错误。

最新更新