如何使用 CoreData 保存下载的 CoreML 模型?



我已经从后端下载了新的训练模型python代码:

    import Foundation
    import Alamofire
    import AlamofireObjectMapper
    import ObjectMapper
    import CoreML
    class func downloadModel(modelUrl: String) {
        let destenation = Support.getDestenationForModel(modelUrl: modelUrl)
        AF.download(modelUrl, to: destenation).downloadProgress { progress in
            print("Download Progress: (progress.fractionCompleted)")
        }
            .response { response in
                switch response.result {
                case .success(let success):
                    if let url = success?.absoluteURL {
                        FTApi.compileNewModel(url: url)
                    }
                    break
                case .failure(let err):
                    print(err)
                    break
                }
        }
    }

其中SupportgetDestenationForModel如下:

    class func getDestenationForModel(modelUrl: String) -> DownloadRequest.Destination {
        let destenation: DownloadRequest.Destination =  { url, options in
            guard let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first ,
                let modelUrl = URL(string: modelUrl) else {
                    preconditionFailure("unable to use documents directory")
            }
            let fileURL = documentsURL.appendingPathComponent(modelUrl.lastPathComponent)
            AppPrefrences.pathOfModel = modelUrl.lastPathComponent
            return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
        }
        return destenation
    }

下载完成后,我尝试使用以下代码将模型保存到CoreData(我没有找到任何其他方法,也许您可以推荐其他方法(:

    private class func compileNewModel(url: URL) {
        do {
            let compiledUrl = try MLModel.compileModel(at: url)
            guard let model = try? MLModel(contentsOf: compiledUrl)
                else {
                    print("cannot get content of model")
                    return
            }
            let coreMlModel = CML(context: PersistanceService.context)
            print(type(of: model)) // => MLNeuralNetworkEngine
            coreMlModel.model = (model as NSObject)
            PersistanceService.saveContext() // here I have an error
        } catch {
            print("cannot download the model!")
        }
    }

错误是:*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MLNeuralNetworkEngine encodeWithCoder:]: unrecognized selector sent to instance 0x104d38280'

这是我的CoreData实体类:

import Foundation
import CoreData

extension CML {
    @nonobjc public class func fetchRequest() -> NSFetchRequest<CML> {
        return NSFetchRequest<CML>(entityName: "CML")
    }
    @NSManaged public var model: NSObject?
}

我尝试将类型从 NSObject 更改为 MLModel ,但结果是一样的。

你为什么要尝试这个?这不是CoreData设计的那种东西。

正确的解决方案是将文件夹从编译的 URL 复制到应用的"应用程序支持"文件夹中的某个位置。然后,在创建 MLModel 对象时,请使用"应用程序支持"文件夹中的 URL。

阅读 Core ML 文档中的"在用户设备上下载和编译模型",了解如何执行此操作。

最新更新