在Objective-C中运行CoreML

4

我在使用Objective-C创建苹果的CoreML时遇到了一些问题。我已经使用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;
}

我会非常感激任何对此的帮助。


我很好奇你为什么想要使用Objective-C。上面的代码不是有效的Obj-C代码,这让我认为你对这门语言并不是很熟练。如果是这样的话,那么为什么要使用它呢?无论如何,代码应该像这样:MLMultiArray *input = [MLMultiArray initWithShape:@[@10, @10] dataType: MLMultiArrayDataTypeDouble error:&error];MLModel *model = [[MLModel alloc] initWithContentsOfFile: @"name"]; - Matthijs Hollemans
1个回答

3

首先,您需要导入您的模型类,对于您的情况,svm(最好以大写字母Svm开头):

#import "svm.h" 

这个类定义包含了所有输入输出和方法定义所需的信息。当您在左侧选择mlmodel文件时,可以通过单击类名旁边的小箭头来找到自动生成的类描述中的规范。在这个类描述中,不要删除html标签。

enter image description here

在您的情况下,输入是一个包含160个Double元素的MLMultiArray向量。因此,首先使用“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];
    }

这里涉及到的是苹果公司的MLMultiArray方法,名为

initWithShape
。我只是为了测试而将数组填充了“1”,您当然需要稍后用实际输入替换它。

不需要获取您的模型,只需实例化支持向量机,然后运行

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);
           }

当您打印出由XCode为您创建的svmModelOutput时,您可以检查预测的类标签作为整数以及所有标签的概率,如下所示:
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";
}

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