问题描述
问题:CoreMLTools reName_feature 不更新模型中的特征名称,仅在模型的“规范”中更新!
我为图像分类问题创建了一个顺序 Tensorflow 模型。 最初,在转换时(根据 Apple 文档):
# https://coremltools.readme.io/docs/tensorflow-2
mlmodel2 = ct.convert(model,inputs=[ct.ImageType()],input_names=['image'],image_input_names='image')
生成了一个 MLModel,它有一个名为“conv2d_3_input”的输入并且是一个 MultiArray (Float33. 1x299x299x1) 以及一个名为“Identity”的输出,它也是一个 Float32 的 MultiArray
幸运的是,快速入门文档位于:https://coremltools.readme.io/docs/introductory-quickstart#download-the-model 阐明了输入类型的修复需要向 ImageType 添加形状参数:
# Define the input type as image,# set pre-processing parameters to normalize the image
# to have its values in the interval [0,1]
image_input = ct.ImageType(shape=(1,299,1,))
mlmodel3 = ct.convert(model,inputs=[image_input],image_input_names='image')
所以现在生成的 MLModel 的输入类型为 Image (Grayscale 299 x 299)(太棒了!),但它仍然被称为“conv2d_3_input”
对于样式点,我想将输入特征重命名为“图像”。转换函数的名称参数(上面)没有效果。我接下来尝试直接更改模型的规格:
spec = mlmodel.get_spec()
#spec.description.input
ct.utils.rename_feature(spec,'conv2d_3_input','image')
#rename change spec but does not push new spec into model
spec.description.input
这正确地更改了规范中的输入名称:
[name: "image"
type {
imageType {
width: 299
height: 299
colorSpace: GRAYSCALE
}
}
]
然而,这显然并没有推动模型的变化!这是 mlmodel 的列表:
input {
name: "conv2d_3_input"
type {
imageType {
width: 299
height: 299
colorSpace: GRAYSCALE
}
}
}
output {
name: "Identity"
shortDescription: "Most likely ....."
type {
multiArrayType {
dataType: FLOAT32
}
}
}
Metadata {
shortDescription: "Converts image ........."
如何将特征名称的变化推送到实际的 mlmodel 中?
解决方法
在 coreMLtools 团队的 Aseem 的帮助下,这里是将修订后的 protobuf 规范推回模型的机制:
spec = mlmodel3.get_spec()
ct.utils.rename_feature(spec,'conv2d_3_input','image')
ct.utils.rename_feature(spec,'Identity','output')
# reload the model with the updated spec and re-save
model = ct.models.MLModel(spec)
model.save("mlModel3.mlmodel")
#observe the correct model
model
这在 Asem 的 WWDC2020 演讲中有更详细的介绍: https://developer.apple.com/videos/play/wwdc2020/10153/