CoreML遇到的问题和原因

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值