【问题标题】:CoreML Model spec - change output type to dictionaryCoreML 模型规范 - 将输出类型更改为字典
【发布时间】:2021-01-06 05:06:07
【问题描述】:

在过去的一周里,我一直在努力对使用 Google 的 AutoML Vision 工具构建的分类器进行推理。

起初我以为一切都会顺利,因为 Google 允许导出最终模型的 CoreML 版本。我以为我只需要使用 Apple 的 CoreML 库就可以让它工作。当我导出模型时,Google 提供了一个 .mlmodel 文件和一个带有分类标签的 dict.txt 文件。对于当前模型,我有 100 个标签。

这是我在模型上运行推理的 Swift 代码。

private lazy var classificationRequest: VNCoreMLRequest = {
        do {

            let classificationModel = try VNCoreMLModel(for: NewGenusModel().model)

            let request = VNCoreMLRequest(model: classificationModel, completionHandler: { [weak self] request, error in
                self?.processClassifications(for: request, error: error)
            })

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

当我尝试传递 UIImage 以在模型上运行推理时,问题就开始了。原始模型的输入类型是 MultiArray (Float32 1 x 224 x 224 x 3)。使用 Coremltools 库,我能够使用 Python 将输入类型转换为 Image (Color 224 x 224)。

这行得通,这是我的代码:

import coremltools
import coremltools.proto.FeatureTypes_pb2 as ft

spec = coremltools.utils.load_spec("model.mlmodel")

input = spec.description.input[0]
input.type.imageType.colorSpace = ft.ImageFeatureType.RGB
input.type.imageType.height = 224
input.type.imageType.width = 224

coremltools.utils.save_spec(spec, "newModel.mlmodel")

我现在的问题是输出类型。我希望能够访问分类的置信度以及分类的结果标签。再次使用 coremltools,我能够访问输出描述,我得到了这个。

name: "scores"
type {
  multiArrayType {
    dataType: FLOAT32
  }
}

我正在尝试以这种方式进行更改:

f = open("dict.txt", "r")
labels = f.read()

class_labels = labels.splitlines()
print(class_labels)
class_labels = class_labels[1:] # remove the first class which is background
assert len(class_labels) == 57

# make sure entries of class_labels are strings
for i, label in enumerate(class_labels):
  if isinstance(label, bytes):
    class_labels[i] = label.decode("utf8")

#classifier_config = ct.ClassifierConfig(class_labels)

output = spec.description.output[0]
output.type = ft.DictionaryFeatureType

很遗憾,这不起作用,我找不到任何可以帮助我的信息。

【问题讨论】:

  • 你找到解决上述问题的方法了吗,我对使用 google autoML 或 coreML 模型有同样的问题

标签: tensorflow machine-learning coreml google-cloud-automl coremltools


【解决方案1】:

ct.ClassifierConfig 仅在您转换模型时有用,即当您调用 ct.convert(...) 时。

如果您已经有一个 mlmodel,则无法通过这种方式更改类标签。您必须使用 spec 在 mlmodel 对象中更改它们。

鉴于该规范,您可以这样做:

labels = spec.neuralNetworkClassifier.stringClassLabels 
del labels.vector[:]
new_labels = [ ... ] 
labels.vector.extend(new_labels)

coremltools.utils.save_spec(spec, "YourNewModel.mlmodel")

其中new_labels 是标签列表。

【讨论】:

  • 如果我使用此脚本导出模型已损坏,您对此有任何解决方案吗?谢谢
猜你喜欢
  • 2014-04-26
  • 2018-02-16
  • 2017-12-10
  • 2023-03-03
  • 2020-06-26
  • 2020-10-30
  • 2020-01-24
  • 2017-12-30
  • 2017-11-23
相关资源
最近更新 更多