Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Crash when initializing CoreML model: Error Domain=com.apple.CoreML Code=0 "Error in declaring network."

Tags:

ios

swift

coreml

I have an app on the App Store and I'm getting its error logs from Crashlytics. One of the most frequent errors the users get (and the one I failed miserably to reproduce) occurs when initializing a CoreML model in my project. Here is how I initialize the model:

class VisionManager: NSObject {
  /// Prediction model
  private static let model = MobileNet()

  ...

  override init() {
    super.init()

    guard let visionModel = try? VNCoreMLModel(for: VisionManager.model.model) else {
      // this case should never happen as we know for sure that the model we are using is an image classification model
      fatalError("The CoreML model being used is not compatible with the Vision framework.")
    }

    ...
  }

...
}

The error, as seen on Crashlytics, reads as follows:

fatal error: 'try!' expression unexpectedly raised an error: Error Domain=com.apple.CoreML Code=0 "Error in declaring network." UserInfo={NSLocalizedDescription=Error in declaring network.}: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.65.2/src/swift/stdlib/public/core/ErrorType.swift, line 181

And the stack trace shows that the error is thrown when executing the guard block. Actually, it goes deeper and shows that the error was thrown inside the static initialization at the top, when calling the initializer. The initializer, together with the whole MobileNet.swift class is automatically generated and looks like this:

init(contentsOf url: URL) throws {
  self.model = try MLModel(contentsOf: url)
}

/// Construct a model that automatically loads the model from the app's bundle
convenience init() {
  let bundle = Bundle(for: MobileNet.self)
  let assetPath = bundle.url(forResource: "MobileNet", withExtension:"mlmodelc")
  try! self.init(contentsOf: assetPath!)
}

It seems obvious that the error is thrown calling the init(contentsOf url: URL) method. However, since this is a generated file, I believe there isn't much I can do to tackle this error.

One possibility is that the compiled .mlmodelc file is not copied to the bundle somehow, and when trying to initialize the MobileNet object with that URL, we get an uncaught error. Is that even possible?

Any ideas or pointers on this issue is greatly appreciated.

like image 943
halileohalilei Avatar asked Nov 16 '17 21:11

halileohalilei


1 Answers

It seems obvious that the error is thrown calling the init(contentsOf url: URL) method. However, since this is a generated file, I believe there isn't much I can do to tackle this error.

FYI, you can copy this generated file into a new file and use it instead to initialize the model (just rename the classes inside the new file). Then, try changing this line in your new file:

let bundle = Bundle(for: MobileNet.self)

to:

let bundle = Bundle.main

I'm not sure if this will fix your particular problem, but it did for me when I moved the generated file into a Cocoapod

like image 67
hartw Avatar answered Nov 02 '22 02:11

hartw