问题描述
在过去一周中,我一直在努力对使用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将输入类型转换为图像(颜色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
不幸的是,这无法正常工作,我找不到任何可以帮助我的信息。
解决方法
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
是标签列表。