将 Caffe 模型转换为 CoreML

Converting Caffe model to CoreML

我正在努力了解 CoreML。对于入门模型,我下载了 Yahoo's Open NSFW 个 caffemodel。你给它一张图片,它会给你一个概率分数(在 0 到 1 之间),即图片包含不合适的内容。

使用 coremltools,我已将模型转换为 .mlmodel 并将其引入我的应用程序。它出现在 Xcode 中,如下所示:

在我的应用程序中,我可以成功传递图像,输出显示为 MLMultiArray。我遇到麻烦的地方是理解如何使用这个 MLMultiArray 来获得我的概率分数。我的代码是这样的:

func testModel(image: CVPixelBuffer) throws {

    let model = myModel()
    let prediction = try model.prediction(data: image)
    let output = prediction.prob // MLMultiArray
    print(output[0]) // 0.9992402791976929
    print(output[1]) // 0.0007597212097607553
}

作为参考,CVPixelBuffer 正在调整为模型要求的所需 224x224(一旦我弄明白了,我就会开始使用 Vision)。

如果我提供不同的图像,我打印到控制台的两个索引确实会发生变化,但它们的分数与我 运行 Python 中的模型得到的结果大不相同.在 Python 中测试时传入模型的相同图像给出了 0.16 的输出,而根据上面的示例,我的 CoreML 输出有很大不同(和字典,不像 Python 的双输出) 比我期望看到的要多。

是否需要做更多的工作才能获得我期望的结果?

您似乎没有按照模型期望的方式转换输入图像。
大多数 caffe 模型期望 "mean subtracted" 图像作为输入,这个模型也是如此。如果您检查 Yahoo's Open NSFW (classify_nsfw.py 提供的 python 代码:

# Note that the parameters are hard-coded for best results
caffe_transformer = caffe.io.Transformer({'data': nsfw_net.blobs['data'].data.shape})
caffe_transformer.set_transpose('data', (2, 0, 1))  # move image channels to outermost
caffe_transformer.set_mean('data', np.array([104, 117, 123]))  # subtract the dataset-mean value in each channel
caffe_transformer.set_raw_scale('data', 255)  # rescale from [0, 1] to [0, 255]
caffe_transformer.set_channel_swap('data', (2, 1, 0))  # swap channels from RGB to BGR

图像也有一种特定的方式 resized to 256x256 and then cropped to 224x224

要获得完全相同的结果,您需要在两个平台上以完全相同的方式转换输入图像。

有关其他信息,请参阅 this thread