我创建了一个基于自定义.mlmodel模型的PyTorch文件,首先将PyTorch模型转换为ONNX,然后使用onnx_coreml将其转换为CoreML。使用虚拟数据(每个值为1.0的3x224x224数组),我已经验证了PyTorch模型、ONNX模型(使用Caffe后端运行)和CoreML模型(使用coremltools)都得到了相同的结果。
但是,当我将相同的模型导入Xcode并在电话上运行时,即使使用虚拟数据,模型输出也不匹配。
我使用的设备似乎没有什么不同(我已经在iPhones上试过了,从XS一直到SE)。所有程序都在运行iOS 12.2,并使用Xcode 10.2.1
下面是我用来创建虚拟数据并从我的模型中获得预测的代码(在Swift中):
let pixelsWide = Int(newImg.size.width)
let pixelsHigh = Int(newImg.size.height)
var pixelMLArray = try MLMultiArray(shape: [1, 1, 3, 224, 224], dataType: .float32)
for y in 0 ..< pixelsHigh {
for x in 0 ..< pixelsWide {
pixelMLArray[[0,0,0,x,y] as [NSNumber]] = 1.0
pixelMLArray[[0,0,1,x,y] as [NSNumber]] = 1.0
pixelMLArray[[0,0,2,x,y] as [NSNumber]] = 1.0
}
}
do {
let convModel = CNNModel()
var thisConvOutput = try convModel.prediction(_0: pixelMLArray)._1161
} catch { print("Error") }我已经验证了输入和输出标签是正确的,等等。这运行顺利,但是thisConvOutput的前三个值是: 0.000139,0.000219,0.003607
比较而言,运行PyTorch模型的前三个值是: 0.0002148、0.00032246和0.0035419
和使用coremltools的完全相同的.mlmodel : 0.00021577,0.00031877,0.0035404
长话短说,我不熟悉Swift,我想知道在初始化/填充我的"pixelMLArray“以在我的设备上运行Xcode模型时是否做了一些愚蠢的事情,因为coremltools的.mlmodel结果与我使用PyTorch获得的结果非常接近。有人能帮忙吗?
发布于 2019-05-01 09:58:08
设备上的核心ML输出: 0.000139,0.000219,0.003607
来自coremltools的输出: 0.00021577,0.00031877,0.0035404
请注意,这些是非常小的数字。当Core在GPU上运行您的模型(可能在神经引擎上,不确定)时,它使用16位浮点。它们的精度比32位浮点小得多.
请注意,0.000139和0.00021577不是相同的数字,但它们都在1e-4左右。这低于16位浮标的精度限制.但是0.003607和0.0035404几乎是相同的数字,因为它们大约大10倍,因此不会失去那么多的精度。
尝试使用CPU在设备上运行Core模型(在实例化模型时可以传递一个选项)。您可能会看到,您现在得到的结果与coremltools版本更接近(而且可能是相同的),因为CPU上的Core ML使用32位浮点数。
结论:从你到目前为止所显示的情况来看,你的模型看起来像预期的那样工作,考虑到你会因为16位浮点的计算而失去精确性。
https://stackoverflow.com/questions/55928844
复制相似问题