Модель CoreML, преобразованная из модели pytorch, дает неправильные вероятности прогнозирования

#pytorch #coreml #onnx #coremltools #onnx-coreml

#pytorch #coreml #onnx #coremltools #onnx-coreml

Вопрос:

У меня есть модель двоичной классификации pytorch, которую я преобразовал в CoreML. Я преобразовал свою модель прямо и косвенно через onnx, используя следующие учебные пособия / документацию соответственно https://coremltools.readme.io/docs/pytorch-conversion , и https://github.com/onnx/onnx-docker/blob/master/onnx-ecosystem/inference_demos/resnet50_modelzoo_onnxruntime_inference.ipynb .

Выходные данные, предшествующие функции softmax, и вероятности аналогичны как для исходного pytorch, так и для модели onnx, преобразованной из PyTorch. Но выходные данные для модели CoreML, преобразованной из PyTorch с помощью обучающей документации, полностью неверны. У меня не было ошибок при компиляции метода CoreML ни из одного метода.

Проверка весов последнего слоя для CoreML и Pytorch, похоже, одинакова. вывод модели CoreML до softmax дает мне {‘classLabel’: ‘_xx’, ‘classLabelProbs’: {‘_xx’: 29.15625, ‘xx’: -22.53125}}

в то время как выходные данные модели pytorch дают мне [-3.2185674 3.4477997]

Результат преобразования из onnx в CoreML выглядит следующим образом…

 58/69: Converting Node Type Add
59/69: Converting Node Type Relu
60/69: Converting Node Type Conv
61/69: Converting Node Type BatchNormalization
62/69: Converting Node Type Relu
63/69: Converting Node Type Conv
64/69: Converting Node Type BatchNormalization
65/69: Converting Node Type Add
66/69: Converting Node Type Relu
67/69: Converting Node Type GlobalAveragePool
68/69: Converting Node Type Flatten
69/69: Converting Node Type Gemm
Translation to CoreML spec completed. Now compiling the CoreML model.
Model Compilation done.
  

В то время как вывод модели pytorch при печати выглядит так для конечного слоя….

 (layer4): Sequential(
(0): BasicBlock(
(conv1): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(downsample): Sequential(
(0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(1): BasicBlock(
(conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(avgpool): AdaptiveAvgPool2d(output_size=(1, 1))
(fc): Linear(in_features=512, out_features=2, bias=True).
  

Как мне устранить количественные ошибки, полученные из моей модели CoreML, которая была преобразована из PyTorch?

Ответ №1:

Вероятно, это проблема с вашими параметрами предварительной обработки изображения: https://machinethink.net/blog/help-core-ml-gives-wrong-output /

Комментарии:

1. Я начал свою модель с предварительно подготовленной модели resnet18 и обучил ее своим данным. Я использовал ту же предварительную обработку изображения перед передачей его в модель как для моей модели pytorch, так и для моей преобразованной модели coreml. Это должно было позаботиться о том, о чем говорится в статье. Верно?

2. Да, если вы использовали те же параметры предварительной обработки для модели Core ML, то это не должно быть проблемой. Но обратите внимание, что ваш вывод в ~ 10 раз больше, чем вывод PyTorch, что обычно означает, что масштаб ввода уже неверен. Попробуйте преобразовать модель только с одним слоем, чтобы убедиться, что это работает нормально.

Ответ №2:

Обновить:

используя унифицированный API coreml, я добавил масштабированный слой. Мои выходные данные не дают никаких вероятностей для моего классификатора.

! [последние пару слоев преобразованной модели pytorch] [1] [1]: https://i.stack.imgur.com/9bzd2.png

последний слой выводит тензор вместо вероятностей. Поэтому я добавил функцию softmax через network.builder

builder.add_softmax(name="softmax", input_name="305", output_name="307:labelProbabilityLayerName")

у предыдущего последнего узла было выходное имя, равное «307:labelProbabilityLayerName», и я изменил его на «305», прежде чем добавить softmax() . таким образом, вывод предыдущего последнего узла является входом в мой softmax. Кроме того, теперь выходные данные могут быть переданы моему softmax, который теперь может подключаться к исходному классу string, распечатывая предполагаемые вероятности. Я все еще получаю сообщение об ошибке…

«Ошибка выполнения: ошибка компиляции модели: «Ошибка чтения спецификации protobuf. ошибка валидатора: слой ‘softmax’ использует входные данные с именем’307′, которых нет в этой сети.».»

Что не имеет смысла, потому что я определил свой softmax для использования «305», а также обновил этот последний слой, который является слоем innerproduct, для вывода 305.