【发布时间】:2020-07-16 18:47:01
【问题描述】:
我第一次需要将 mu keras 模型转换为 coreml。这可以通过coremltools 包来完成,
import coremltools
import keras
model = Model(...) # keras
coreml_model = coremltools.converters.keras.convert(model,
input_names="input_image_NHWC",
output_names="output_image_NHWC",
image_scale=1.0,
model_precision='float32',
use_float_arraytype=True,
custom_conversion_functions={ "Lambda": convert_lambda },
input_name_shape_dict={'input_image_NHWC': [None, 384, 384, 3]}
)
但是,我有两个 lambda 层,其中第一个是深度到空间(pixelshuffle),另一个是缩放器:
def tf_upsampler(x):
return tf.nn.depth_to_space(x, 4)
def mulfunc(x, beta=0.2):
return beta*x
...
x = Lambda(tf_upsampler)(x)
...
x = Lambda(mulfunc)(x)
据我所知,我发现的唯一建议是使用自定义层,但以后需要在 Swift 代码中实现我的层。像 MyPixelShuffle 和 MyScaleLayer 这样的东西以某种方式实现为 XCode 项目中的类(?):
def convert_lambda(layer):
# Only convert this Lambda layer if it is for our swish function.
if layer.function == tf_upsampler:
params = NeuralNetwork_pb2.CustomLayerParams()
# The name of the Swift or Obj-C class that implements this layer.
params.className = "MyPixelShuffle"
# The desciption is shown in Xcode's mlmodel viewer.
params.description = "pixelshuffle"
params.parameters["blockSize"].intValue = 4
return params
elif layer.function == mulfunc:
# https://stackoverflow.com/questions/47987777/custom-layer-with-two-parameters-function-on-core-ml
params = NeuralNetwork_pb2.CustomLayerParams()
# The name of the Swift or Obj-C class that implements this layer.
params.className = "MyScaleLayer"
params.description = "scaling input"
# HERE!! This is important.
params.parameters["scale"].doubleValue = 0.2
# The desciption is shown in Xcode's mlmodel viewer.
params.description = "multiplication by constant"
return params
但是,我发现 CoreML 实际上有我需要的层,它们可以在 ScaleLayer 和 ReorganizeDataLayer 中找到
如何使用这些原生层来替换 keras 模型中的 lambda?是否可以为网络编辑 coreML protobuf?或者如果它们有 Swift/OBj-C 类,它们是如何被调用的?
可以通过coremltools.models.neural_network.NeuralNetworkBuilder删除/添加层来完成吗?
更新:
我发现keras converter 实际上调用了神经网络构建器来添加不同的层。 Builder has the layer builder.add_reorganize_data I need。现在是如何替换模型中的自定义层的问题。我可以将它加载到 builder 和 ispect 层中:
coreml_model_path = 'mymodel.mlmodel'
spec = coremltools.models.utils.load_spec(coreml_model_path)
builder = coremltools.models.neural_network.NeuralNetworkBuilder(spec=spec)
builder.inspect_layers(last=10)
[Id: 417], Name: lambda_10 (Type: custom)
Updatable: False
Input blobs: ['up1_output']
Output blobs: ['lambda_10_output']
【问题讨论】:
标签: keras coreml coremltools