(Deeplabv3+MobilenetV2)语义分割模型部署手机端(ckpt-pb-tflite)

最近要做一个实时的语义分割项目,需要完成手机端的部署。这篇文章主要是对模型转换做一个总结。

首先模型训练,不多说,网上有很多资源,但是tf官网保存的模型是ckpt格式,要完成移动端部署,需要将ckpt转换成freeze pb,再将pb转换成tflite。


首先是针对非量化模型

记录一下踩过坑:
1.ckpt转换成pb
/research/deeplab目录下有一个export_model.py文件,这个文件可以直接将ckpt转换成pb,但是后续用toco转换成tflite会有很多坑。作者都进行了尝试,主要有以下错误产生。
1.1 Check failed: array.data_type == array.final_data_type Array “ImageTensor” has mis-matching actual and final data types (data_type=uint8, final_data_type=float)

这个错误就是推理过程中segmentation_predictions最后cast成了float32类型,但是数据是uint-8类型。我一开始是在在export_model.py中返回去掉tf.cast,在segmentation_predictions在转换成uint-8类型,然后就没有bug,但是最后预测的label与gt比较,由于类型不匹配,于是没有利用此方法修改,(大家可以用动手尝试)
(Deeplabv3+MobilenetV2)语义分割模型部署手机端(ckpt-pb-tflite)_第1张图片
1.2 Unimplemented: this graph contains anoperator of type Cast for which the quantized form is not yet implemented. Sorry, and patches welcome (that’s a relatively fun patch to write, mostly providing the actual quantized arithmetic code for this op).
这个错误我一直没有办法解决,一开始以为是模型有些层不支持,但是很快打消了这个念头。作者尝试了官方的预训练权重,mobilenetv2,xception65等等,都发生了这个问题。

具体原因是因为toco工具的问题。作者使用了toco进行转换,首先进行了量化,但是报这个错误,因为toco可能对有些层不支持量化。火来将inference_input_type改成FLOAT,发现还是报错,后来发现是因为在训练过程中有一个quantize_delay开关(表示前多少次是非量化训练,之后量化训练,由于是非量化训练,默认为-1,所以应该使用FLOAT推理)

于是选择了使用tflite_convert工具,完成了转换。
(Deeplabv3+MobilenetV2)语义分割模型部署手机端(ckpt-pb-tflite)_第2张图片

—————————————————————————————
量化模型的转换官网给出了步骤,下面记录一下踩过的坑。
量化模型的训练和非量化模型的训练唯一不同的就是quantize_delay_step,因为之前受到yolo模型的启发,于是决定设置为7000,就可以训练了。

测试ckpt时候与量化模型稍有区别。
需要增加了两个开关,一个还是quantize_delay_step,如果仅仅就这样,会报错xxx not found in checkpoint
这时候博主对应eval.py里面的开关进行寻找,去掉了decoder_output_stride这个开关,模型就能完成的测试。

—————————————————————————————
其中查了很多博客,大多都有问题,因为yolov3,图像分类等等转换成tflite是很简单的,但是语义分割模型并没有很多参考,这里贴上github上issues,希望能对大家有一点参考,deeplab在转换模型有很多坑还有待解决,大家不用气馁。

(Deeplabv3+MobilenetV2)语义分割模型部署手机端(ckpt-pb-tflite)_第3张图片
https://github.com/tensorflow/tensorflow/issues/23747
链接: link.

你可能感兴趣的:(模型部署)