сводка из одного предложения : слой не максимального ограничения выводит четыре значения, но я могу использовать только два из этих четырех значений в качестве входных данных для последующих слоев.
I ' m построение модели нейронной сети с использованием пакета Apple Core ML Tools, и я добавил слой без максимального подавления (NMS) . Этот слой имеет четыре выхода в соответствии с документацией:
- выход 1: координаты блоков, соответствующие выжившим блокам.
- выход 2: оценки блоков, соответствующие оставшимся блокам.
- вывод 3: индексы выживших ящиков. [это вывод, который я хочу использовать на следующем слое]
- вывод 4: количество блоков, выбранных после алгоритма NMS
Я установил создать тестовую модель с несколькими простыми входными данными, и уровень NMS правильно вернет ожидаемые значения для каждого из четырех выходных данных, перечисленных выше. Если я затем использую вывод # 1 или вывод # 2 в следующем слое, у меня нет проблем с этим. Однако, если я пытаюсь использовать выходные данные № 3 или выходные данные № 4 в последующем слое, я получаю сообщение об ошибке, в котором говорится, что вход «не найден ни в одном из выходов предыдущих слоев».
Блокнот Jupyter
Самый простой способ воспроизвести проблему - это загрузить и go через Jupyter Notebook .
В качестве альтернативы, приведенный ниже пример кода также решает проблему I ' m.
Пример кода
Я настроил некоторые входные данные примера следующим образом:
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_indices
или box_count
в качестве входных данных для следующего слоя. Например, если я добавлю слой линейной активации (раскомментировав блок выше), я получу следующую ошибку:
Input 'surviving_indices' of layer 'identity' not found in any of the outputs of the preceding layers.
У меня та же проблема, если я использую вывод box_count
(т.е. , установив input_name="box_count"
в слое add_activation
).
Я знаю, что слой NMS правильно возвращает выходные данные с именами surviving_indices
и box_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_coords
или nms_scores
в качестве входных данных для слоя линейной активации, у меня нет проблем. Он будет правильно выводить неизмененные значения nms_coords
или nms_scores
из вывода слоя NMS.
Я озадачен тем, почему слой NMS правильно выводит то, что я хочу, но тогда я не могу использовать эти выходы в последующих слоях.