让coreml在Objective-C

时间:2017-11-28 15:07:06

标签: objective-c coreml

我无法在CoreML中创建一个使用Apple Objective-C的简单示例。我已经使用python创建了一个模型文件,它现在的工作非常简单:

coreml_model_svm = coremltools.models.MLModel("svm.mlmodel")
test_x = [1.0 for x in range(160)]
predictions_coreml_svm = coreml_model_svm.predict({"input":test_x})

我想在Objective-C中重现以上三行。我知道我的数据必须是MLMultiArray,并且需要将模型加载到MLModel中。我一直试图找到有关语法的一些信息,但似乎我不明白文档是如何工作的,所有的例子都在Swift中。到目前为止,这是我的代码。评论MLMultiArray会导致初始化MLModel的未捕获异常。如果没有评论MLMultiArray,我会no known class method for selector 'initWithShape:dataType:error'

#import <Foundation/Foundation.h>
#import <CoreML/CoreML.h>

//clang -framework Foundation coremltest.m -o coremltest
int main (int argc, const char * argv[])
{
        NSLog(@"start");

        NSArray * shape = [[NSArray alloc]  init];
        MLMultiArrayDataType dataType = MLMultiArrayDataTypeDouble;
        NSError * error = nil;

        MLMultiArray * input =  [MLMultiArray initWithShape:(NSArray*) shape
                             dataType:(MLMultiArrayDataType ) dataType
                        error:(NSError **) error];

        MLModel * mymodel = [[MLModel init] initWithContentsOfFile:@"svm.mlmodel"];

        return 0;
}

我很感激任何帮助。

1 个答案:

答案 0 :(得分:1)

首先你需要导入你的模型类,在你的情况下svm(从大写字母开始会更好的Svm):

#import "svm.h" 

此类定义包含输入和输出以及方法定义所需的所有信息。 当您在左侧选择mlmodel文件时,可以通过单击类名称旁边的小箭头在自动生成的类描述中找到此规范。在此课程描述中

enter image description here

在您的情况下,输入是一个MLMultiArray,其中包含160个双元素作为向量。首先使用 shape 数组

定义尺寸
NSArray *shape = @[@1, @160];

然后定义MLMultiArray,它将作为预测过程的 svmModelInput (再次由XCode自动定义):

    MLMultiArrayDataType dataType = MLMultiArrayDataTypeDouble;
    NSError *error = nil;

    MLMultiArray *theMultiArray =  [[MLMultiArray alloc] initWithShape:(NSArray*)shape
                                          dataType:(MLMultiArrayDataType)dataType
                                             error:&error] ;

    for (int i = 0; i < 160; i++) {
         [theMultiArray setObject:[NSNumber numberWithDouble:1.0] atIndexedSubscript:(NSInteger)i];
    }

使用过的

  

initWithShape

是Apple的 MLMultiArray 方法。我用“1”填充数组只是为了测试,但是你必须在以后用你的实际输入替换它。

无需获取您的模型,只需实例化您的svm然后运行

  

predictionFromInput:

再次由XCode构建的类的方法:

        svm *mySvm = [[svm alloc] init];

        svmOutput * svmModelOutput = [(svm *)mySvm predictionFromInput:theMultiArray error:&error];
        NSLog(@"SVM Model output = %lld -- %@", svmModelOutput.classLabel, svmModelOutput.classProbability );

           if (!error)
           {
               NSLog(@"svm finished without error");
           }
           else
           {
               NSLog(@"Error: %@", error.localizedDescription);
           }

当您打印出 svmModelOutput (由XCode为您创建)时,您可以将预测的classLabel检查为整数以及所有标签的概率,如下所示:

2017-12-04 07:32:45.765015+0100 CoreML_test[2634:877638] SVM Model output = 2 -- {
    11 = "0.002656571278812773";
    3 = "0.2121030282896462";
    10 = "0.004570897664662783";
    2 = "0.5825387375626612";
    9 = "0.02911120023388797";
    4 = "0.1690195649703292";
}