【问题标题】:CoreML Output labels NSCFString - Labels not showing correctlyCoreML 输出标签 NSCFString - 标签未正确显示
【发布时间】:2021-01-04 10:41:03
【问题描述】:

我正在开发一个需要使用 CoreML 模型来执行图像分类的 iOS 应用程序。

我使用 Google Cloud Platform AutoML Vision 来训练模型。 Google 提供了该模型的 CoreML 版本,我下载了它以在我的应用程序中使用。

我按照 Google 的教程进行操作,一切似乎都很顺利。然而,当它使用时间开始使用模型时,得到了非常奇怪的预测。我得到了预测的信心,然后我得到了一个非常奇怪的字符串,我不知道它是什么。

<VNClassificationObservation: 0x600002091d40> A7DBD70C-541C-4112-84A4-C6B4ED2EB7E2 requestRevision=1 confidence=0.332127 "CICAgICAwPmveRIJQWdsYWlzX2lv"

我指的字符串是CICAgICAwPmveRIJQWdsYWlzX2lv

经过一番研究和调试,我发现这是一个 NSCFString。

https://developer.apple.com/documentation/foundation/1395135-nsclassfromstring

显然这是基础 API 的一部分。有人有这方面的经验吗?

CoreML 文件还附带一个带有正确标签的 dict.txt 文件。我必须将此字符串转换为标签吗?我该怎么做。

这是我到目前为止的代码。

//
//  Classification.swift
//  Lepidoptera
//
//  Created by Tomás Mamede on 15/09/2020.
//  Copyright © 2020 Tomás Santiago. All rights reserved.
//

import Foundation
import SwiftUI
import Vision
import CoreML
import ImageIO

class Classification {
    
    private lazy var classificationRequest: VNCoreMLRequest = {
        do {
            let model = try VNCoreMLModel(for: AutoML().model)
            let request = VNCoreMLRequest(model: model, completionHandler: { [weak self] request, error in
                if let classifications = request.results as? [VNClassificationObservation] {
                    print(classifications.first ?? "No classification!")
                }
            
            })
            
            request.imageCropAndScaleOption = .scaleFit
            return request
        }
        catch {
            fatalError("Error! Can't use Model.")
        }
    }()
    
    func classifyImage(receivedImage: UIImage) {
        
        let orientation = CGImagePropertyOrientation(rawValue: UInt32(receivedImage.imageOrientation.rawValue))
        
        if let image = CIImage(image: receivedImage) {
            DispatchQueue.global(qos: .userInitiated).async {
                
                let handler = VNImageRequestHandler(ciImage: image, orientation: orientation!)
                do {
                    try handler.perform([self.classificationRequest])
                }
                catch {
                    fatalError("Error classifying image!")
                }
            }
        }
    }
}

【问题讨论】:

  • NSCFString 视为NSString,它只是一个内部类。由于它是一个 NSString,它应该可以毫无问题地桥接到 String
  • 感谢您的回复。问题是我不想要那个字符串。我想要正确的标签,这不是模型应该返回的标签...:/

标签: ios swift machine-learning computer-vision coreml


【解决方案1】:

标签存储在您的 mlmodel 文件中。如果您在 Xcode 12 模型查看器中打开 mlmodel,它将显示这些标签是什么。

我的猜测是,您的 mlmodel 文件包含“CICAgICAwPmveRIJQWdsYWlzX2lv”等等,而不是实际标签。

Google 的 AutoML 似乎没有将正确的类标签放入 Core ML 模型中。

您可以在应用程序中制作字典,将“CICAgICAwPmveRIJQWdsYWlzX2lv”等映射到真实标签。

或者您可以通过使用 coremltools 编辑 mlmodel 文件来替换这些标签。 (我的电子书 Core ML Survival Guide 有一章是关于如何替换模型中的标签。)

【讨论】:

  • 您好!感谢你的回复。模型查看器是否仅在 Xcode 12 中可用?
  • 它也存在于以前版本的 Xcode 中,但它们不显示标签。 Xcode 12 中添加了该新功能。您还可以使用免费的 Netron 工具查看类标签。或者,您可以使用 coremltools 库将模型加载到 Python 脚本中并以这种方式进行检查。
  • 目前我的 CoreML 模型正在接收 UIImage,但输出是 MultiArray MultiArray (Float32)。我在 Google AutoML Vision Tool 中训练它对图像进行分类,所以我希望它能给我一个标签。但它没有......我搜索了很多,我可以弄清楚如何去做。最初,我有一个接收 MultiArray Float(1 * 224 * 224) 并返回另一个 MultiArray 浮点数的 CoreML 模型。我使用 CoreML 工具对其进行了转换,现在它收到了一个图像。但我不能改变输出。我真的很挣扎,我需要帮助。你能帮我进一步吗?
  • 当我打印模型的规格时,我得到这个作为输出: output { name: "scores" type { multiArrayType { dataType: FLOAT32 } } } 我想改变这个对象给我置信度和分类标签。我想改变输出类型。
  • 你告诉我的不合算。如果您的模型不是分类器,您将不会获得 VNClassificationObservation 结果。 Core ML 模型可以是不同的类型:分类器、回归器或通用神经网络。如果模型是分类器,您只会获得 VNClassificationObservation。但如果您的输出是 MultiArray,则模型不是分类器。因此,您现在提供的信息似乎与您提出的问题无关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多