Simple Machine Learning App Using Apple’s Core ML Models
“Machine learning focuses on applications that learn from experience and improve their decision-making or predictive accuracy over time.” — IBM
Machine learning is an easier and smarter way to analyse data, this also means you can produce accurate results and analysis. In this short demo I’m going to show you how I created a simple, intelligent app that recognizes your handwritten digits (0–9) using the existing MNIST model from Apple.
You can download the model here: https://developer.apple.com/machine-learning/models/
Or learn more about Machine learning here: https://developer.apple.com/machine-learning/
Step 1: Create new Xcode project
Step 2: Simple UI
For the project we’ll use a very simple layout, at first you will need a placeholder for your digit, then two buttons for clearing the canvas and for recognizing the digits.
The canvas is created using a separate CanvasView in which I used UIKit to register touch. This demo is not focused on touch detection so you can read more about is here: https://developer.apple.com/documentation/uikit/uitouch
You should end up with a simple UI like this:
Step 3: Set up the Vision Model
To detect your digits we’ll use the Vision Framework, the Vision Framework performs different kind of detections so you can even use it to detect your face, barcodes, images, and so on. To request our analysis we’ll use VNCoreMLRequest which will take our model and a completionHandler.
func setupVision() { guard let visionModel = try? VNCoreMLModel(for: MNIST().model)
else {fatalError(“can not load Vision ML model”)} let classificationRequest = VNCoreMLRequest(model: visionModel,
completionHandler: self.handleClassification) self.requests = [classificationRequest]}
Step 4: Create a completionHandler
At last, we’ll create our completionHandler, in this function we’ll request our VNCoreMLRequest and if there are any errors we’ll print them.
As you can see we also set a confidence so that our model is trustable, and we are for 80% or more sure that the end result is correct. You can off course play with these values. At last using the DisptachQueue we’ll assign the value to the digitLabel we created in step 1.
func handleClassification (request:VNRequest, error:Error?) { guard let observations = request.results else {print(“no
results”); return} let classifications = observations
.flatMap({$0 as? VNClassificationObservation})
.filter({$0.confidence > 0.8})
.map({$0.identifier}) DispatchQueue.main.async {
self.digitLabel.text = classifications.first
}}