issue list
· unsupported ops of type gatherv2
· Embedding layer: ‘embedding_1’: height dimension of the input blob must be 1.
· NSLocalizedDescription = “Failure dynamically resizing for sequence length.”
· NSLocalizedDescription = “Neural Network inputs can only be of size 1, 3, or 5.”;
· Invalid dst shape when converting from Keras to Coreml
unsupported ops of type gatherv2
NLP处理中需要用到 Embedding Layer,
Tensorflow中的Embedding层会用到 gatherV2 ops,而CoreML不支持GatherV2 算子,因此会报这个错误。
解决办法
用 Keras 构建 NLP 模型中的 Embedding 层,这个在CoreML中是支持的。
eight dimension of the input blob must be 1
相关错误
· channel dimension of the input blob must be 1.
· width dimension of the input blob must be 1.
CoreML的 Embedding Layer 要求在 C H W 三个维度上必须要都为1,就是只接受以下形式的输入
input shape = (1, 1, 1)
通常在 Keras 或者 Tensorflow 中会构建以下形式的输入
input shape = (None, sequence length)
其中 None 是 batch size。
为了满足 CoreML Embedding layer 的规则,需要将输入增加一个维度,也即是在 Keras中把输入改为
input shape = (None, sequence length, 1)
CoreML 接受的输入维度是rank 1, 3, 5,
[batch_size, sequence_length, channel, width, height]
这里增加的最后一个维度会被CoreML扩展为 C H W,这样就能顺利地输入到 Embedding layer。
“Failure dynamically resizing for sequence length.”
原因:输入数据维度无法被CoreML识别
常见原因:如果定义了一个模型,第一层是 keras.layers.Input(),后面没有增加一层 Reshape 对输入维度进行调整而是直接送入到Embedding,那么这个模型虽然在 Keras 规则下能成功训练并使用来预测,但在转换为 CoreML 后就无法正常输入数据来 predict了,这是CoreML底层框架的bug。
解决办法:在Input之后增加一层Reshape,在Keras角度把维度扩展为
input shape = (None, sequence length, 1)
从 CoreML 角度是
input shape = (None, sequence length, 1, 1, 1)
能解决问题。
Neural Network inputs can only be of size 1, 3, or 5
常见问题,因为 CoreML 只接受输入为 rank1, rank3, rank5 的数据。除此之外的所有数据格式在predict的时候都会引起这个异常。
可以用TextCNN模型,构建一个rank2的输入数据,塞到coreml模型里尝试引起这个异常。
data = {'input_text': np.array([[1.0]])} <-- rank2
result = coreml_model.predict(data, useCPUOnly=True)['sentiment']
print('predict with coreml result: %s ' % result)
Invalid dst shape when converting from Keras to Coreml
这是coreml的一个bug,原因是coreml在做模型转换的时候对维度的扩展算法有bug,下面是一段可以重现问题的代码
sequence_length = 400
input_text = layers.Input(shape=(sequence_length, ), name='input_text')
emb = layers.Embedding(1000, 64, name='embedding')(input_text)
reshape = layers.Reshape([sequence_length, 64, 1], name='reshape')(emb)
model = keras.models.Model(inputs=[input_text], outputs=[reshape])
converted = coremltools.converters.keras.convert(model,
input_names='input_text',
output_names='reshape')
把 sequence_length 改为399就可以重现问题,异常log类似如下
RuntimeWarning: You will not be able to run predict() on this Core ML model. Underlying exception message was: Error compiling model: "compiler error: Invalid dst shape1 x 1 x 64 x 1->399->64 x 400 x 1 x 0 x 1 x ".
解决方法:
在输入层和embedding中间增加reshape层
sequence_length = 400
input_text = layers.Input(shape=(sequence_length, ), name='input_text')
reshape_1 = layers.Reshape(input_shape=(sequence_length, ), target_shape=(sequence_length, 1, ))(input_text) <--- focus on here
emb = layers.Embedding(1000, 64, name='embedding')(reshape_1)
reshape = layers.Reshape([sequence_length, 64, 1], name='reshape')(emb)
model = keras.models.Model(inputs=[input_text], outputs=[reshape])
converted = coremltools.converters.keras.convert(model,
input_names='input_text',
output_names='reshape')
相关问题记录在coreml的git上
Invalid dst shape when converting from Keras to Coreml #496