我用keras retinanet 50训练了一个模型,现在我有一个h5文件,当用静态图像测试它时效果很好。
我很想在iOS(和/或Android)应用中使用它,但我无法将其转换为例如coreml:
import coremltools
coreml_model = coremltools.converters.keras.convert(model) # => error occurs
coreml_model.save('my_model.mlmodel')
错误是
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-7-ba230c07a72c> in <module>()
1 import coremltools
----> 2 coreml_model = coremltools.converters.keras.convert(model)
3 # Saving the Core ML model to a file.
4 coreml_model.save('my_model.mlmodel')
/home/jonas/projects/keras/keras-env/local/lib/python2.7/site-packages/coremltools/converters/keras/_keras_converter.pyc in convert(model, input_names, output_names, image_input_names, is_bgr, red_bias, green_bias, blue_bias, gray_bias, image_scale, class_labels, predicted_feature_name, model_precision, predicted_probabilities_output, add_custom_layers, custom_conversion_functions)
743 predicted_probabilities_output,
744 add_custom_layers,
--> 745 custom_conversion_functions=custom_conversion_functions)
746
747 return _MLModel(spec)
/home/jonas/projects/keras/keras-env/local/lib/python2.7/site-packages/coremltools/converters/keras/_keras_converter.pyc in convertToSpec(model, input_names, output_names, image_input_names, is_bgr, red_bias, green_bias, blue_bias, gray_bias, image_scale, class_labels, predicted_feature_name, model_precision, predicted_probabilities_output, add_custom_layers, custom_conversion_functions, custom_objects)
541 add_custom_layers=add_custom_layers,
542 custom_conversion_functions=custom_conversion_functions,
--> 543 custom_objects=custom_objects)
544 else:
545 raise RuntimeError(
/home/jonas/projects/keras/keras-env/local/lib/python2.7/site-packages/coremltools/converters/keras/_keras2_converter.pyc in _convert(model, input_names, output_names, image_input_names, is_bgr, red_bias, green_bias, blue_bias, gray_bias, image_scale, class_labels, predicted_feature_name, predicted_probabilities_output, add_custom_layers, custom_conversion_functions, custom_objects)
185
186 # Check valid versions
--> 187 _check_unsupported_layers(model, add_custom_layers)
188
189 # Build network graph to represent Keras model
/home/jonas/projects/keras/keras-env/local/lib/python2.7/site-packages/coremltools/converters/keras/_keras2_converter.pyc in _check_unsupported_layers(model, add_custom_layers)
98 else:
99 if type(layer) not in _KERAS_LAYER_REGISTRY:
--> 100 raise ValueError("Keras layer '%s' not supported. " % str(type(layer)))
101 if isinstance(layer, _keras.layers.wrappers.TimeDistributed):
102 if type(layer.layer) not in _KERAS_LAYER_REGISTRY:
ValueError: Keras layer '<class 'keras_resnet.layers._batch_normalization.BatchNormalization'>' not supported.
我也试过导出权重和体系结构(json)并再次加载模型,但错误保持不变。
根据最后的答案(https://www.quora.com/Does-Residual-Learning-work-without-batch-normalization)我明白batchnormalization仅用于训练,所以有没有办法将其转换为coreml?
修改
感谢Matthjis的评论,我尝试了以下内容:
import keras
class BatchNormalization(keras.layers.BatchNormalization):
"""
Identical to keras.layers.BatchNormalization, but adds the option to freeze parameters.
"""
def __init__(self, freeze, *args, **kwargs):
print("here we are")
self.freeze = freeze
super(BatchNormalization, self).__init__(*args, **kwargs)
# set to non-trainable if freeze is true
self.trainable = not self.freeze
def call(self, *args, **kwargs):
# return super.call, but set training
print("here we are")
return super(BatchNormalization, self).call(training=(not self.freeze), *args, **kwargs)
def get_config(self):
print("here we are")
config = super(BatchNormalization, self).get_config()
config.update({'freeze': self.freeze})
return config
然后
import coremltools
coreml_model = coremltools.converters.keras.convert(model, custom_conversion_functions={"BatchNormalization": BatchNormalization})
但我仍然得到同样的错误......
答案 0 :(得分:1)
在推理期间也使用批量标准化,Core ML支持它。
但是,keras_resnet.layers._batch_normalization.BatchNormalization
不是Keras的标准BatchNormalization图层,因此coremltools不了解如何处理它。
好消息:这个新的BatchNormalization层扩展了Keras标准BatchNormalization层,因此可以使您的模型与Core ML一起使用。 https://github.com/broadinstitute/keras-resnet/blob/master/keras_resnet/layers/_batch_normalization.py
三个选项:
BatchnormLayerParams
对象。有关如何处理coremltools中自定义图层的更多信息:http://machinethink.net/blog/coreml-custom-layers/ 您可以使用keras_resnet.layers._batch_normalization.BatchNormalization
图层替换模型中的keras.layers.BatchNormalization
图层,然后照常运行coremltools。
找出你的coremltools的安装位置,然后在 _keras2_converter.py 中,为keras_resnet.layers._batch_normalization.BatchNormalization添加一行,如下所示:
keras_resnet.layers._batch_normalization.BatchNormalization: _layers2.convert_batchnorm,
您还必须将keras_resnet
导入此文件,否则coremltools将无法找到此模块。然后像往常一样运行coremltools。