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.
- The model file appears in the Project Navigator with the descriptive information you added during the conversion with Core ML Tools
- An API is generated for using the model.
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.
- The model.prediction function is one of the functions that gets generated when the Core ML file is dragged into Xcode.
- The input type for Core ML prediction function is a MLMultiArray
- The input to the Keras model is an array of 20 word mappings, so our MLMultiArray size is [20,1,1]
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.