将Python写的tensorflow代码文件打包为exe趟坑记录

将Python写的tensorflow代码文件打包为exe趟坑记录

本人python 菜鸟一枚,初写博客是为了把自己趟坑的经历记录下来,使自己和他人以后少走弯路,大牛们见笑。

最终成功的系统环境如下:windows 7 64bit, python 3.5.3, tensorflow-gpu 1.6.0, cuda9.0 cudnn7.0(或者tensorflow-gpu 1.4.0, cuda8.0 cudnn6.0,能运行,但个别函数会出错)

0、背景简述:
之所以搞这个是因为一个目标识别项目的需要,用户在对一些图像打上类别标签之后,我用python里面的迁移学习范例ImageRetrain训练出新的模型文件,然后再用C++加载该模型,对新的图像进行分类识别。其实按理说直接用C++调用py文件也可以,但我的C++程序调用了很多32位dll库,调用python却必须调用64位版本,无法编译为同一个进程内,所以只能把py文件打包为exe,C++来调用。

原计划用py2exe,但貌似py2exe 不支持python3.x,所以转向pyinstaller和cxfreeze。系统环境是Windows10 64bit, anaconda 5.0, python 3.6.4, tensorflow-gpu 1.7.0, cuda 9.0。

1、按照这位博主的做法趟过了几个坑:
https://blog.csdn.net/Sagittarius_Warrior/article/details/78457824
终于打包成功了,打包后的单个文件居然有700多兆,汗。
结果运行时被告知:
ImportError: No module named ‘tensorflow.python.pywrap_tensorflow_internal’
Failed to load the native TensorFlow runtime.
网上只找到一个博客:
https://blog.csdn.net/wyx100/article/details/78510749,但没有解决我的问题
因为我用PyCharm 或者Visual studio 在指定python解释器后都能正常运行这个py文件,在cmd下import tensorflow
也是没有问题的,为何打包之后tensorflow 却出了问题呢?百思不得解啊

2、转而使用cxfreeze,按照这个博主的做法:
https://blog.csdn.net/theeternal/article/details/78947971 又在趟过了几个坑之后,成功打包
结果运行时又被告知:
ImportError: cannot import name ‘_methods’
- **图片链接和图片上传**
网上没有先例,所以也没有解决方案,顿时心里一万匹草泥马奔腾!

3、到这里我还没有怀疑tensorflow版本的问题,怀疑是windows10的问题。我电脑上装了双系统,一个是windows10 64bit 系统,另一个是win7 64bit。抱着试一试的想法,切换到了windows 7环境下,卸掉原来的anaconda,重新下载安装了 python 3.5.3, 又pip install tensorflow-gpu ,默认给我装了个最新的1.10.0,
本想换成老的版本,但想到那个缓慢的安装过程我又忍了,抱着侥幸的心理试试看,又是cuda 9.0, cudnn 7.14什么的一顿装。配置好了tensorflow环境后,再次尝试用pyinstaller打包,问题依旧!cxfreeze问题依旧!五雷轰顶啊!

4、终于还是按照前辈们的告诫,老老实实用低版本的tensorflow了。换成tensorflow-gpu 1.4.0,以及cuda8.0 cudnn6.0
之后,pyinstaller打包的exe文件只有300多兆了,终于可以运行了!谢天谢地啊!

前前后后折腾了一整天,上了tensorflow这艘贼船真是生命不息,折腾不止啊!
所以还是那句话:用tensorflow 一定要经得住新版本的诱惑!遇到莫名其妙的问题就老老实实换版本吧!

5、后续补充:打包后的exe运行之后高兴没多久,就又报错了:
A protocol message was rejected because it was too big (more than 67108864 bytes). To increase the limit (or to disable these warnings), see CodedInputStream::SetTotalBytesLimit() in google/protobuf/io/coded_stream.h.
仔细一看,是我在调用TransformGraphWithStringInputs(为了优化训练后的模型文件opt_graph.pb)时,该函数内部使用ParseFromString报的错。这个函数应该很常用才对,而且我的模型80M也不算很大,这种内部错误实在太郁闷。

github上的大牛们说这是google.protobuf的限制问题,他们提供的解决方法我都试过了,在我这里统统无效,包括重装protobuf, 重新编译protobuf, 还有设置环境变量PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python,调用SetAllowOversizeProtos(True)等等,都可耻的失败了。我开始问候Google家人了!冷静下来想到这个tensorflow1.4.0毕竟是很老的版本,后续版本应该会解决这个问题,于是心惊胆战的升级到tensorflow-gpu 1.6.0,终于没再报错,万幸pyinstaller也没出错,终于可以歇口气了。tensorflow, windows党想说爱你真不容易!

猜你喜欢

转载自blog.csdn.net/julysea_nudt/article/details/81670521