将Caffe模型转换为CoreML

4
我正在努力理解CoreML。作为一个入门模型,我已经下载了Yahoo's Open NSFW caffemodel。您提供一张图片,它会给出一个概率分数(介于0和1之间),表示该图像是否包含不适当的内容。
使用coremltools,我已将该模型转换为.mlmodel并引入我的应用程序中。它在Xcode中显示如下:

enter image description here

在我的应用程序中,我可以成功传递一张图片,输出出现为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 会为你处理。 - Guig
我认为这可能仅适用于使用Vision的情况下。如果仅使用CoreML本身,则我确实认为缓冲区需要调整大小(我可以确认;如果我传递未调整大小的CVPixelBuffer,它会抛出错误)。 - ZbadhabitZ
没错。除非你喜欢编写、重写和维护图像处理代码,否则使用Vision将图像提供给模型要简单得多。 - rickster
@rickster 我更愿意使用Vision,但是对于这个特定的模型,它在结果中没有提供任何输出。当我尝试使用CoreML时,我得到了一些结果,但不是我所希望的。使用Vision,传递原始图像会产生空输出。 - ZbadhabitZ
1个回答

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

此处有一种特定的方法,可以将图像缩放到256x256,然后裁剪为224x224。
为了获得完全相同的结果,您需要在两个平台上以完全相同的方式转换输入图像。
请参见此线程获取更多信息。

2
@ZbadhabitZ - 除了Shai指出的之外,当生成你的mlmodel时,你可能想尝试将is_bgr = True设置为caffe.convert(),因为大多数Caffe模型使用BGR输入。默认情况下,Core ML会假定RGB输入进行转换,我想交换颜色通道对于寻找人类肤色的东西的准确性会有很大影响。 - Brad Larson
@BradLarson 谢谢您!我已经尝试使用coremltools将模型转换,并使用is_bgr标志两种方式,但没有任何区别。Shai的回复可能需要先解决,然后我会再次尝试使用设置了is_bgr标签的模型。感谢您的评论! - ZbadhabitZ
您是否有关于如何在Swift中以与Python相同的方式执行图像处理的指导? - ZbadhabitZ
2
你不需要在Swift中进行图像处理。当你将Caffe模型转换为mlmodel时,你需要向caffe.convert()函数传递正确的参数,以便mlmodel知道如何为你处理图像。 - Matthijs Hollemans
我在代码中尝试了同样的模型,但仍然没有得到期望的输出。比如将图像直接调整为224 x 224,但输出不同。我不理解先将图像调整为256 x 256,再裁剪为224 x 224的意义。 - Amrit Trivedi
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接