最近要做一个实时的语义分割项目,需要完成手机端的部署。这篇文章主要是对模型转换做一个总结。
首先模型训练,不多说,网上有很多资源,但是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类型。这个bug很好解决,只需要在export_model.py中返回去掉tf.cast,在segmentation_predictions在转换成uint-8类型,可以打印进行测试。
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,发现还是报错。
于是选择了使用tflite_convert工具,完成了转换。
—————————————————————————————
其中查了很多博客,大多都有问题,因为yolov3,图像分类等等转换成tflite是很简单的,但是语义分割模型并没有很多参考,这里贴上github上issues,希望能对大家有一点参考,deeplab在转换模型有很多坑还有待解决,大家不用气馁。
https://github.com/tensorflow/tensorflow/issues/23747
链接: link.
作者查看了18年年底的解决方案,至少编写tensorflow的大佬都没有找到问题的所在,是一位作者在无意间使用分类任务转换成功了模型,可能这就是开源的魅力所在吧。