Search code examples
swiftxcodecreateml

Using CreateML Model in Xcode (ActivityClassifier)


I created an activity classifier model using CreateML and imported the model into my XCode project. And am trying to find answers to the following questions.. I created the instance of the model like this:

let activityClassifier = MyActivityClassifier_4()

  1. How am I supposed to access the constants of the model? For example, the prediction window value that shows here on the metadata of the model. I am having hard time finding an example code to get these values. I tried something along these line let predictionWindowSize = activityClassifier.model.modelParameters but could not figure it out. enter image description here
  1. Also, the model expects stateIn as an input. How can I create an empty MLMultiArray that matches the expected shape? stateIn: MLMultiArray(shape: <#T##[NSNumber]#>, dataType: <#T##MLMultiArrayDataType#>) I assume there is a suggested way to fetch features shape and etc...

I would greatly appreciate if you could also direct me on how to find these answers...


Solution

  • You can get the metadata by accessing modelDescription.metadata. For author, description, license, and version, you can use the appropriate MLModelMetadataKey:

    e.g.

    let model = try! MyActivityClassifier_4(configuration: .init()).model
    let author = model.modelDescription.metadata[.author]
    

    For the metadata in the "additional metadata" section, you need to use the .creatorDefinedKey key to get a nested dictionary. Things like prediction_windows are stored there.

    if let dict = model.modelDescription.metadata[.creatorDefinedKey] as? [String: Any],
       let predictionWindow = dict["prediction_window"] {
        print(predictionWindow)
    }
    

    For the inputs, you can see the shape and type of the array just by going to the "Predictions" tab after opening your model in Xcode.

    enter image description here

    In this case, both of the inputs shown above would be a double array with a single dimension, 100 elements in length. You can create it like this.

    MLMultiArray(shape: [100], dataType: .double)
    

    If you want to do this programmatically, you can too. Just give the name of your input to model.modelDescription.inputDescriptionsByName, and get the multiArrayConstraint.

    if let constraint = model.modelDescription.inputDescriptionsByName["stateIn"]?.multiArrayConstraint {
        print(constraint.shape)
        print(constraint.dataType)
    }