How to initialize a MLMultiArray in CoreML

淺唱寂寞╮ 提交于 2019-12-12 16:25:08

问题


I've got an array of 40 arrays with 12 double features, so the type is [[double]]. Currently I'm sending this data to Google Cloud ML API to get a related prediction.

Since Apple recently introduced CoreML and coremltools, I converted my model from keras to .mlmodel to avoid thousand of google cloud api calls and do inference directly on my iPhone:

coreml_model = coremltools.converters.keras.convert(new_Model, input_names=['accelerations'],
                                                    output_names=['scores'])
coreml_model.save('PredictionModel.mlmodel')

After adding the model to my Xcode Project, it looks like:

I have no idea, where these others inputs and outputs are comming from. To get a prediction, I need to convert my Array of Arrays of 12 doubles to an MLMultiArray, but I don't know how to do this. Has anyone faced a similar problem? Here is my current unfinished approach:

_predictionModel = PredictionModel()
guard let mlMultiArray = try? MLMultiArray(dataPointer: <#T##UnsafeMutableRawPointer#>, shape: <#T##[NSNumber]#>, dataType: <#T##MLMultiArrayDataType#>, strides: <#T##[NSNumber]#>, deallocator: <#T##((UnsafeMutableRawPointer) -> Void)?##((UnsafeMutableRawPointer) -> Void)?##(UnsafeMutableRawPointer) -> Void#>) else {
        fatalError("Unexpected runtime error.")
    }
guard let predictionOutput = try? _predictionModel.prediction(accelerations: mlMultiArray, lstm_1_h_in: nil, lstm_1_c_in: nil, lstm_2_h_in: nil, lstm_2_c_in: nil) else {
        fatalError("Unexpected runtime error.")
    }

The related documentation can be found here.


回答1:


I achieved it by reading this blog :)

let data = _currentScaledMotionArrays.reduce([], +) //result is of type [Double] with 480 elements
guard let mlMultiArray = try? MLMultiArray(shape:[40,12], dataType:MLMultiArrayDataType.double) else {
    fatalError("Unexpected runtime error. MLMultiArray")
}
for (index, element) in data.enumerated() {
    mlMultiArray[index] = NSNumber(floatLiteral: element)
}
let input = PredictionModelInput(accelerations: mlMultiArray)
guard let predictionOutput = try? _predictionModel.prediction(input: input) else {
        fatalError("Unexpected runtime error. model.prediction")
}



回答2:


This is how I did it. Probably not the best way to handle optionals but gets the job done for testing

Create an instance of the MLMultiArray object with shape and data type

let mlArray = try? MLMultiArray(shape: [3], dataType: MLMultiArrayDataType.float32)

mlArray does not have an append function so you literally have to iterate through it and add values

for i in 0..<array.count {
     mlArray?[i] = NSNumber(value: input[i])
}

Full function

    func convertToMLArray(_ input: [Int]) -> MLMultiArray {

        let mlArray = try? MLMultiArray(shape: [3], dataType: MLMultiArrayDataType.float32)


        for i in 0..<array.count {
            mlArray?[i] = NSNumber(value: input[i])
        }


        return arr!
    }


来源:https://stackoverflow.com/questions/44460532/how-to-initialize-a-mlmultiarray-in-coreml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!