Coremltools: нельзя использовать некоторые выходные данные слоя не максимального подавления в последующих слоях - PullRequest
0 голосов
/ 14 апреля 2020

сводка из одного предложения : слой не максимального ограничения выводит четыре значения, но я могу использовать только два из этих четырех значений в качестве входных данных для последующих слоев.

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 правильно выводит то, что я хочу, но тогда я не могу использовать эти выходы в последующих слоях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...