从pytorch模型转换而来的coreML模型给出了错误的预测概率

从pytorch模型转换而来的coreML模型给出了错误的预测概率,pytorch,coreml,onnx,coremltools,onnx-coreml,Pytorch,Coreml,Onnx,Coremltools,Onnx Coreml,我有一个pytorch二进制分类模型,我将其转换为coreML。我分别使用以下教程/文档通过onnx直接和间接地转换了我的模型 ,及 对于原始Pytork和从Pytork转换而来的onnx模型,softmax函数之前的输出和概率相似。但是,通过教程文档从PyTorch转换而来的coreML模型的输出是完全不正确的。从这两种方法编译coreML方法时我都没有错误 检查coreML和Pytorch最后一层的重量似乎是相同的。softmax之前的coreML模型的输出给了我 {'classLabel

我有一个pytorch二进制分类模型,我将其转换为coreML。我分别使用以下教程/文档通过onnx直接和间接地转换了我的模型 ,及

对于原始Pytork和从Pytork转换而来的onnx模型,softmax函数之前的输出和概率相似。但是,通过教程文档从PyTorch转换而来的coreML模型的输出是完全不正确的。从这两种方法编译coreML方法时我都没有错误

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

如何解决从Pytork转换的coreML模型产生的定量错误?

可能是图像预处理选项的问题:

更新:

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

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

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

builder.add\u softmax(name=“softmax”,input\u name=“305”,output\u name=“307:labelProbabilityLayerName”)

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

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


这没有意义,因为我将我的softmax定义为使用“305”,并将最后一层(即innerproduct层)更新为输出305。

我使用预训练的resnet18模型开始了我的模型,并使用数据对其进行了训练。在将图像传递给pytorch模型和转换后的coreml模型之前,我对图像进行了相同的预处理。这应该考虑到这篇文章所说的内容。是吗?是的,如果对核心ML模型使用相同的预处理选项,那么这不应该是问题。但请注意,您的输出比PyTorch输出大约10倍,这通常意味着输入的比例已经错误。尝试转换一个只有一个图层的模型,看看效果是否正常。