Разница во времени при распознавании фотографий Swift

#swift #coreml #vision

#swift #coreml #apple-видение

Вопрос:

Я создал приложение, которое распознает цветы на фотографии. Фотография может быть из галереи или сделана с помощью камеры. У меня есть функция:

 func detectFlower(image: CIImage,completion: @escaping (_ getString:String?,_ error:Error?,_ getDouble:Double?,_ getArray:Array<VNConfidence>?,_ getArray:Array<String>?)-> Void)  {
        
        guard let model = try? VNCoreMLModel(for: NewFlowersModel().model) else {
            
            fatalError("Cannot import a model.")
        }
        let methodStart = Date()
        let request = VNCoreMLRequest(model: model) { (request, error) in
            
            let classifiedNameOfFlower = request.results?.first as? VNClassificationObservation
            let classifiedValues = request.results as? [VNClassificationObservation]
            let methodFinish = Date()
            let nameOfFlower = String(classifiedNameOfFlower?.identifier ?? "Unexpected type")
            let executionTime = methodFinish.timeIntervalSince(methodStart)
            
            let classificationConfidences = classifiedValues?.prefix(10).map {
                ($0.confidence)
            }
            
            let classificationIdentifiers = classifiedValues?.prefix(10).map {
                ($0.identifier)
            }
            completion(nameOfFlower,nil,executionTime, classificationConfidences, classificationIdentifiers)
        }
        
        let handler = VNImageRequestHandler(ciImage: image)
        do {
            try handler.perform([request])
        } catch {
            print(error)
            completion(nil, error, nil, nil, nil)
        }
    }
  

который используется для распознавания. В нем есть две константы let methodStart = Date() и let methodFinish = Date() для измерения времени. Позже в коде есть константа, которая вычисляет разницу let executionTime = methodFinish.timeIntervalSince(methodStart) .

Я заметил странную зависимость — когда я запускаю приложение, первое сканирование возвращает разницу во времени, например, 0,395959 секунды. Следующее сканирование возвращает намного меньшее время, например 0,033615 сек. К чему это может привести? Что вызывает разницу во времени, и что при первом сканировании это время всегда самое длительное?

Ответ №1:

Загрузка модели с диска, вероятно, занимает большую часть этого времени. Вы воссоздаете всю модель каждый раз, когда выполняете обнаружение:

 guard let model = try? VNCoreMLModel(for: NewFlowersModel().model) else { ... }
  

В первый раз, когда вы делаете это, вам нужно загрузить много данных с диска. После этого большая часть данных будет кэшироваться, но обычно это неправильный способ сделать это, потому что вы все еще тратите много усилий на воссоздание структур данных.

Что вы хотите сделать, это создать модель и запрос только один раз, возможно, во время запуска приложения, или когда вы переходите к этому экрану, или всякий раз, когда вы ожидаете, что пользователь захочет использовать движок ML. Сохраните его в свойстве или в общем объекте. Затем, каждый раз, когда вы получаете новое изображение, просто создайте VNImageRequestHandler и выполните его.