Deploying to Core ML

Using the Core ML Framework, you can retrieve the distance between a query image and all images in the reference data. Exporting this model in Core ML format can be performed using the export_coreml function.

model.export_coreml('MyImageSimilarityModel.mlmodel')

When you open the model in Xcode, it looks like the following:

Image similarity model in Xcode

The following Swift code is needed to consume the model in an iOS app.

let model = try VNCoreMLModel(for: MyImageSimilarityModel().model)

let request = VNCoreMLRequest(model: model, completionHandler: { [weak self] request, error in
    self?.processQuery(for: request, error: error)
})
request.imageCropAndScaleOption = .centerCrop
return request

Notice that the image similarity model in Core ML returns the distances between the query image and all images in the reference dataset. In order to retrieve the most similar images in the reference dataset, we must sort them by distance. We can do this by modifying the Core ML sample application as such:

func processQuery(for request: VNRequest, error: Error?, k: Int = 5) {
    DispatchQueue.main.async {
        guard let results = request.results else {
            self.referenceRanking.text = "Unable to rank image.\n\(error!.localizedDescription)"
            return
        }

        let queryResults = results as! [VNCoreMLFeatureValueObservation]
        let distances = queryResults.first!.featureValue.multiArrayValue!

        // Create an array of distances to sort
        let numReferenceImages = distances.shape[0].intValue
        var distanceArray = [Double]()
        for r in 0..<numReferenceImages {
            distanceArray.append(Double(distances[r]))
        }

        let sorted = distanceArray.enumerated().sorted(by: {$0.element < $1.element})
        let knn = sorted[..<min(k, numReferenceImages)]

        self.referenceRanking.text = String(describing: knn)
    }
}

results matching ""

    No results matching ""