打包过程中遇到了许多问题,本身tensorflow 2.0就挖了一个大坑,这里记录下遇到文件及解决方法,最后把用到的相关文件分享出来,供大家参考使用。
1 模块找不到的几种表现形式
一般是在运行打包的Exe时,会报错,通常缺少模块表现如下:
(1)ModuleNotFoundError: No module named ‘tensorflow.python.platform’
(2)ImportError: cannot import name ‘pywrap_tensorflow’ from ‘tensorflow_core.python’
(3)qt.qpa.plugin: Could not find the Qt platform plugin “windows” in “”
2 隐藏调用的模块
这是tensorflow 2.0带来的一个大坑!!
与tensorflow 1.X相比,tensorflow2.0的文件夹组织形式发生重构,具体对比如下:
1.X目录结构组织如下:
2.0开始,如下:
2.0为了跟之前兼容,使用了隐藏模块调用的方法。
具体来说,一般模块的名称是按照目录结构组织的,即:
‘tensorflow.python.platform’, 那么会在tensorflow下面有一个python文件夹,在python文件夹下有一个platfow。
而在2.0中这个python被放在了tensorflow.core中,而tensorflow文件夹下空空如也。
为了兼容之前1.X的模块调用方式,在2.0的tensorflow文件夹下有一个__init__.py文件,在其中进行了偷梁换柱。将所有以前tensorflow.XXX的模块名称,实际加载的模块变成了tensorflow_core.XXX,具体的可以去分析下这个文件。
那么问题就来了,在pyinstaller分析时,根本分析不到这一层,他是按照目录结构那种方式去找模块的,于是就出现了数十个无法找到的情况。
解决方法,在spec文件的hiddenimports中加入,一开始我也是这么加的,但发现这样根本不可能完成。因为有很多个,你需要一遍遍按照完了才知道缺啥,这是一个非常费力费时的事情。
为此,本人又使用了spec中的hook,将为tensorflow加了一个hook,具体的hook用法参见另一篇文章:https://blog.csdn.net/kevinshift/article/details/104880101
这个hook文件在其中给大家分享了。
另外,我把hook-tensorflow.core.framework.py也给使用了hook。
但是,由于时间仓促,加上边研究边做,在hook中我是把tensorflow中许多模块都引入了,虽然这样能运行成功,但是由于可能打包了多余的模块,会使得打包程序比较大。这个以后有机会了再细究吧。
另外,本人的两个hook文件,及spec文件中有很多冗余重复的。大家可以自己挑挑。
3 tensorflow的二进制文件
tensorflow中的多个二进制文件也没有被包含就去,我手动使用了binaries:
binaries=[(r'C:\ProgramData\Anaconda3\envs\tensorflow4\Lib\site-packages\tensorflow_core\lite\experimental\microfrontend\python\ops\_audio_microfrontend_op.so',r'.\tensorflow_core\lite\experimental\microfrontend\python\ops')
]
4 调用栈超过最大限制
中间报过错误:RecursionError: maximum recursion depth exceeded
解决方法为在spec文件头中加入以下代码:
#下面这个设置了查找的栈深度,作者遇到了报RecursionError: maximum recursion depth exceeded情况,靠这个解决的。默认1000深度。见https://blog.csdn.net/ljt350740378/article/details/96134208
import sys
sys.setrecursionlimit(1000000) #例如这里设置为一百万
以上参考:https://blog.csdn.net/ljt350740378/article/details/96134208
5 UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xce in position 问题
解决方法:
在运行pyinstaller -F xxx.py或pyinstaller yyy.spec前,先运行
chcp 65001 。
然后再运行pyinstaller -F xxx.py或pyinstaller yyy.spec。
如下图所示就可以了:
感谢这里的分享:https://blog.csdn.net/qq_38343111/article/details/91362920
6 打包完后,发现缺少一个python文件问题
自己写了2个python文件A、B,其中A引用另一个B(B为库文件用),在打包A时,自动的去发现A中有import B.pytho,于是就可以自动的把B也打包进去。
但是,没注意,忘了把B和A放在同一个文件夹下,于是在打包生成Exe,运行A时,报缺少B文件库。于是赶紧把B文件拷贝到A同文件夹下,之后继续使用打包。最后发现还是刚才的问题。。。
这个问题是由于打包程序使用了缓存的问题,方法是清除和Spec文件中指定的build文件夹下的同一个工程的文件夹。默认和spec文件夹在同一个文件夹下有一个build,其中有一个和python文件名相同的文件夹,是用来存打包过程中的文件缓存的。删除后将使他重新生成!
7 tensorflow打包汇总
本人打包时使用了一个spec文件,两个hook文件。具体的样子在另一篇文章中都分享出来了,具体见:https://blog.csdn.net/kevinshift/article/details/104880101
后注 202201
最近安装了新版本的tensorflow 2.7,没有了本文中所述的问题了。他的目录结构又改回跟1.X版本类似的了。不知道是不是官方因为这个问题又改回去了。但具体从那个版本开始改的,没有细查。大家在使用的时候可以留意一下。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)