MillerMedia
MillerMedia

Reputation: 3671

CoreML model prediction on image recognition only working on iPhone 11 and 12 models

I created an image recognition .mlmodel file in the Create ML app. I am now using it in an iOS app.

It works great on iPhone 11 and iPhone 12 (and the corresponding models) but not on iPhone 8, iPhone 8 Plus and iPhone X. There are likely other models it does not work on but those are the ones I can confirm so far.

The code I am using is:

do {
    let prediction = try self.model.prediction(image: pixelBuffer!)
} catch {
    print("\(error)")
}

On the models where this does not work, the error printed in the console is:

Error Domain=com.apple.CoreML Code=1 "Predicted feature named 'classLabel' was not output by pipeline" UserInfo={NSLocalizedDescription=Predicted feature named 'classLabel' was not output by pipeline}

Due to the lack of documentation on CoreML I could not find a solid trace on this error. There are some random posts on SO and there's also Git issues on the Turicreate Github (the underlying Python library which Core ML runs) but nothing that seems to give direct answers to this issue.

Any help would be greatly appreciated. Thanks!


Based on this Apple Developer forum post, it appears that there could be some difference between devices with A7 processor and those that pre-date that. Is it possible it's failing silently?

https://developer.apple.com/forums/thread/93105


In the output class of the ML model, there are a few lines of code that read:

lazy var classLabel: String = {
    [unowned self] in return self.provider.featureValue(for: "classLabel")!.stringValue
}()

This is in an auto-generated file that happens when the build on the simulator happens so even editing the file in the text editor gets overwritten on every build. I'm thinking it may be helpful to output the output of the model if at all possible to see what it is actually returning.


I have tracked this down to the function:

open func prediction(from input: MLFeatureProvider, options: MLPredictionOptions) throws -> MLFeatureProvider

In the MLModel class declaration in MLModel.h. This is where the error is thrown from; I have logged the input data all the way to this point and this is the function that throws the error so it is coming from the framework itself.

Upvotes: 1

Views: 780

Answers (2)

Christian Fox
Christian Fox

Reputation: 400

I had this issue with a TabularRegression task and just solved it so will share what worked for me.

The Error

The error was thrown here: let output = try model.prediction(from: row)

The error message was: "Column '[targetColumnName]' not present in the feature columns of the given table."

My Code

In my code I am decoding Row objects from a CSV table. The targetColumnName was present in the table and in the Row class.

My Row class conforms to MLFeatureProvider and implements func featureValue(for featureName: String) -> MLFeatureValue?.

The Actual Issue

The error message is misleading or at least it was in my case. The actual issue was with a feature column/value not the target. For one of the features nil was being returned from featureValue(for:).

The Solution

I found the culprit simply by adding a print statement, the last feature name to be printed before the error is throw is the missing value.

func featureValue(for featureName: String) -> MLFeatureValue?` {
    print("ML requested featureName: \(featureName)")
    // Code to retrieve feature values
}

Upvotes: 1

Matthijs Hollemans
Matthijs Hollemans

Reputation: 7892

The model you created is a so-called pipeline model, which means it contains two sub-models. The first of these is the Vision FeaturePrint model, the second is a classifier that works on these feature prints and outputs class labels.

According to the error message, the pipeline is not outputting the classLabel result anywhere. Since it works on some iPhones and not others, this may be a bug in Core ML. However, it could also be a problem with the model, or with different iOS versions. Hard to say exactly what's going on here.

You can look at the model with the Netron tool (open source), which should give you some idea of whether classLabel is actually present in the model or not.

Upvotes: 0

Related Questions