初始化 CoreML 模型时崩溃:Error Domain=com.apple.CoreML Code=0 "Error in declaring network."

Posted

技术标签:

【中文标题】初始化 CoreML 模型时崩溃:Error Domain=com.apple.CoreML Code=0 "Error in declaring network."【英文标题】:Crash when initializing CoreML model: Error Domain=com.apple.CoreML Code=0 "Error in declaring network." 【发布时间】:2018-04-30 13:34:57 【问题描述】:

我在 App Store 上有一个应用程序,我从 Crashlytics 获取它的错误日志。在我的项目中初始化 CoreML 模型时,用户遇到的最常见错误之一(也是我无法重现的错误)发生。这是我初始化模型的方式:

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.")
    

    ...
  

...

在 Crashlytics 上看到的错误如下:

致命错误:“试试!”表达式意外引发错误:Error Domain=com.apple.CoreML Code=0“声明网络时出错。” UserInfo=NSLocalizedDescription=声明网络时出错。:文件 /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.65.2/src/swift/stdlib/public/core/ErrorType.swift,第 181 行

并且堆栈跟踪显示在执行guard 块时抛出了错误。实际上,它更深入并表明错误是在调用初始化程序时在顶部的静态初始化中引发的。初始化器以及整个 MobileNet.swift 类是自动生成的,如下所示:

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!)

调用init(contentsOf url: URL) 方法引发错误似乎很明显。但是,由于这是一个生成的文件,我相信我无法解决这个错误。

一种可能性是编译后的.mlmodelc 文件没有以某种方式复制到包中,当尝试使用URL 初始化MobileNet 对象时,我们得到一个未捕获的错误。这甚至可能吗?

非常感谢有关此问题的任何想法或指示。

【问题讨论】:

所有用户都会收到此错误吗?还是有些用户一直收到此错误?还是某些用户有时会收到此错误?如果是“一些用户,但一直都是”,那么他们使用的 ios 11 版本可能与应用程序不会崩溃的用户不同。换句话说,有可能在 iOS 11.x 中 Core ML 发生了一些变化,没有更新到这个版本的人可能会崩溃。 并非所有用户都会收到此错误。我和团队中的其他开发人员从未得到它。似乎也没有关于哪些设备和操作系统版本得到它的模式。我可以看到出现此错误的各种操作系统版本,例如 11.0.0、11.0.3、11.1.0、11.1.1、11.2.0 以及 iPhone 6、6 Plus、SE、7、7 Plus 和十、 型号是多少MB?可能此时设备的可用内存即将用完。 我也对此表示怀疑,因为大多数设备在崩溃时剩余的内存不足 10%。但是,也有一些设备在崩溃时可用内存超过 40%。整个应用程序在启动时占用不超过 100 MB,所以我不认为这是因为内存。 【参考方案1】:

调用 init(contentsOf url: URL) 方法引发的错误似乎很明显。但是,由于这是一个生成的文件,我相信我无法解决这个错误。

仅供参考,您可以将此生成的文件复制到一个新文件中,然后用它来初始化模型(只需重命名新文件中的类)。然后,尝试在新文件中更改这一行:

let bundle = Bundle(for: MobileNet.self)

到:

let bundle = Bundle.main

我不确定这是否能解决您的特定问题,但是当我将生成的文件移动到 Cocoapod 中时,它确实解决了我的问题

【讨论】:

【参考方案2】:

最好阅读 Xcode 输出面板顶部的错误。应该有类似这样的错误,显示实际错误:“Core ML 自定义神经网络层需要一个名为 'scaling' 的实现,但在全局命名空间中找不到。

就我而言,我使用的模型中有一个不受支持的层,因此我需要编写 MLCustomLayer。 https://developer.apple.com/documentation/coreml/core_ml_api/creating_a_custom_layer

【讨论】:

以上是关于初始化 CoreML 模型时崩溃:Error Domain=com.apple.CoreML Code=0 "Error in declaring network."的主要内容,如果未能解决你的问题,请参考以下文章

尝试初始化 CoreML 模型会导致模棱两可的错误消息

出货后持续训练 CoreML 模型

错误! coreML 模型对图像的预测是错误的,对视频是正确的

Objective-C 插件和 CoreML 模型在电子邮件或 Box 传输后失败

后台运行coreml时出错:Error计算NN输出错误

准备 CoreML 模型时出错:CoreML 代码生成不支持“<something>”