将 Caffe 模型转换为 CoreML

Posted

技术标签:

【中文标题】将 Caffe 模型转换为 CoreML【英文标题】:Converting Caffe model to CoreML 【发布时间】:2017-11-23 14:19:59 【问题描述】:

我正在努力理解 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 的双重输出不同)。

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

【问题讨论】:

我认为您不需要手动调整缓冲区大小。我认为 CoreML 会为您解决这个问题 我相信只有在使用 Vision 时才会出现这种情况。如果仅使用 CoreML 本身,我相信确实需要调整缓冲区的大小(我可以确认;如果我通过 CVPixelBuffer 而不调整大小,它会引发错误)。 对。除非您喜欢编写、重写和维护图像处理代码,否则使用 Vision 将图像提供给您的模型要简单得多。 @rickster 我更愿意使用 Vision,但是对于这个特定的模型,它不会在结果中提供任何输出。当我尝试使用 CoreML 时,我得到了一些结果,尽管不是我所希望的。使用 Vision,传递原始图像会产生空输出。 【参考方案1】:

您似乎没有按照模型预期的方式转换输入图像。 大多数 caffe 模型都期望“平均减去”图像作为输入,这个模型也是如此。如果您检查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。

【讨论】:

这很有意义!我查看了classify_nsfw.py 文件,但希望Vision 框架会为我处理所有这些。当失败时,我选择使用 CoreML,但没有考虑调整图像的必要性。是时候弄清楚如何进行所有这些转换了! @ZbadhabitZ - 除了 Shai 指出的内容之外,您可能还想在生成 mlmodel 时尝试将 is_bgr = True 设置为 caffe.convert(),因为大多数 Caffe 模型都使用 BGR 输入。默认情况下,Core ML 将假设 RGB 输入进行转换,我想交换颜色通道会对寻找人类肤色的东西的准确性产生很大影响。 @BradLarson 谢谢你!我曾尝试使用 coremltools 两种方式使用 is_bgr 标志转换模型,没有区别。可能需要先解决 Shai 的响应,然后我将使用 is_bgr 标记集再次尝试该模型。感谢您的评论! 您对如何以与 Python 相同的方式但在 Swift 中执行图像处理有任何指导吗? 您不需要在 Swift 中进行图像处理。当您将 Caffe 模型转换为 mlmodel 时,您需要将正确的参数传递给 caffe.convert() 函数,以便 mlmodel 知道如何为您进行图像处理。

以上是关于将 Caffe 模型转换为 CoreML的主要内容,如果未能解决你的问题,请参考以下文章

Core ML简介及实时目标检测及Caffe TensorFlow coremltools模型转换

Core ML简介及实时目标检测及Caffe TensorFlow coremltools模型转换

如何将 CoreML 模型转换为 TensorFlow 模型?

如何将 Turi Create 创建的 CoreML 模型转换为 Keras?

尝试使用 coremltools 4.1 将模型转换为 coreml 不工作

将模型从 tensorflow 转换为 Coreml (4.0) 时出现实例归一化错误