Adding Core ML to an iOS App

- swift core ml ai apple ios iphone xcode core ml tools

This year at WWDC Apple announced Core ML, a new foundational machine learning framework that delivers easy integration with Apple products. After attending the Introducing Core ML session, I was excited to fire up the Xcode 9 beta and start seeing what Core ML could do. During the session the presenter showed how simple it is to use an existing model with Core ML, and I had to see for myself.

1. Core ML Tools - Converting the Model

Along side the Core ML release, Apple also released Core ML Tools, a Python tool for converting existing models from Keras, Caffe, SciKit-learn, or libSVM formats, to the Core ML format.

Installing the tool is as easy as using pip

pip install -U coremltools

Luckily enough, I was able to find a Keras model on Github that did what I wanted my app to do, detect clickbait headlines.

With the model in hand, converting it to the Core ML format is as easy as two lines of Python code.

# The Keras model we start with
model = ConvolutionalNet(vocabulary_size=len(vocabulary),
    embedding_dimension=EMBEDDING_DIMENSION,
    input_length=SEQUENCE_LENGTH)
model.load_weights("../models/detector.h5")

# Necessary line 1, creating the Core ML Model
coreml_model = coremltools.converters.keras.convert(model,
    ["headline"],
    "clickbaityness")

# Not necessary, but recommended descriptive text
coreml_model.author = 'Saurabh Mathur, Core ML conversion by Mike Caulley'
coreml_model.license = 'GNU GPL'
coreml_model.short_description = 'Article headline clickbait detector.'
coreml_model.input_description['headline'] = 'An article headline as a tokenized array.'
coreml_model.output_description['clickbaityness'] = 'Probability that the headline is clickbait.'

# Necessary line 2, saving the model
coreml_model.save('clickbait_model.mlmodel')

Full code for the model and the conversion script is located here.

Once the script is run, you are left with a .mlmodel file that can be brought into Xcode.

2. Bringing to Model to Xcode

Keeping with the theme of easy, bringing the model into Xcode only takes a drag and a drop of the file into the Xcode window.

When you drag and drop a couple things happen.

Here is what a function consuming the API might look like.

static func calculateClickBaitPercentageFor(_ headline: String) -> Double? {
    let cleanedHeadlineArray = headline.clean.words
    let indices = Vocab.wordsToIndices(words: cleanedHeadlineArray)
    let input = Vocab.padSequence(sequence: indices, maxLength: 20)
    let model = clickbait_model()
    let data = input.reduce([], +)
    
    guard let mlMultiArray = try? MLMultiArray(shape:[20,1,1],
                                               dataType:MLMultiArrayDataType.int32) else {
                                                fatalError("Unexpected runtime error. MLMultiArray")
    }
    
    for (index, element) in data.enumerated() {
        mlMultiArray[index] = NSNumber(integerLiteral: element)
    }
    
    if let result = try? model.prediction(headline: mlMultiArray) {
        return result.clickbaityness[0] as? Double
    } else {
        return nil
    }
}

A few things to notice.

And that quickly we are able to have machine learning in our iOS app!

If you would like to check out the full code, it is available here.