从pytorch模型转换的coreML模型提供了错误的预测概率

时间:2020-10-25 00:12:46

标签: 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

对于原始pytorch和从PyTorch转换的onnx模型,softmax函数之前的输出和概率相似。但是,通过教程文档从PyTorch转换的coreML模型的输出是完全错误的。从任何一种方法编译coreML方法都没有错误。

检查coreML和Pytorch的最后一层的权重似乎是相同的。 softmax之前coreML模型的输出给了我 {'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).

我该如何解决从PyTorch转换而来的coreML模型产生的定量误差?

2 个答案:

答案 0 :(得分:0)

您的图像预处理选项可能有问题:https://machinethink.net/blog/help-core-ml-gives-wrong-output/

答案 1 :(得分:0)

更新:

使用coreml统一api,我添加了一个可缩放的层。我的输出没有给出分类器的任何概率。

![转换后的pytorch模型的最后几层] [1] [1]:https://i.stack.imgur.com/9bzd2.png

最后一层打印出张量而不是概率。所以我通过network.builder添加了softmax函数

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

上一个最后一个节点的输出名称等于“ 307:labelProbabilityLayerName”,在添加softmax()之前,我将其更改为“ 305”。这样,前一个最后一个节点的输出就是我的softmax的输入。而且,现在可以将输出传递给我的softmax了,现在可以将其连接到原始字符串类,以打印出预期的概率。 我仍然收到错误消息说...

“ RuntimeError:错误编译模型:”读取protobuf规范时出错。验证程序错误:“ softmax”层消耗了此网络中不存在的名为“ 307”的输入。”。

这没有任何意义,因为我将softmax定义为消耗'305',并且还更新了最后一层,它是内部乘积层,以输出305。

相关问题