将 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的主要内容,如果未能解决你的问题,请参考以下文章