Reputation: 3671
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
Reputation: 400
I had this issue with a TabularRegression task and just solved it so will share what worked for me.
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."
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 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:)
.
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
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