【问题标题】:Pyinstaller, tensorflow.contrib lazy loader error at runtimePyinstaller,运行时 tensorflow.contrib 延迟加载程序错误
【发布时间】:2018-05-31 16:32:15
【问题描述】:

在 python 3.5 32bit 中使用 3.3.1 pyinstaller,我将一个 .py 应用程序转换为 .exe

应用程序使用 tensorflow 并在某些时候抛出

Traceback (most recent call last):
  File "face_classify.py", line 140, in <module>
    loaded_model = load_c3d.c3d_model_obj(user_case)
  File "load_c3d.py", line 80, in __init__
    'wc1': _variable_with_weight_decay('wc1', [3, 3, 3, 3, 64], 0.0005),
  File "load_c3d.py", line 47, in _variable_with_weight_decay
    var = _variable_on_cpu(name, shape, tf.contrib.layers.xavier_initializer())
  File "site-packages\tensorflow\__init__.py", line 35, in __getattr__
  File "importlib\__init__.py", line 126, in import_module
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 956, in _find_and_load_unlocked
ImportError: No module named 'tensorflow.contrib'

运行 .exe 时会发生这种情况。看起来像文件路径问题。 tensorflow 的__init__.py 就是这样做的

# Lazily import the `tf.contrib` module. This avoids loading all of the
# dependencies of `tf.contrib` at `import tensorflow` time.
  def __getattr__(self, item):
    global contrib
    # Replace the lazy loader with the imported module itself.
    import importlib  # pylint: disable=g-import-not-at-top
    contrib = importlib.import_module('tensorflow.contrib')
    return getattr(contrib, item)

在我看来,这种延迟加载似乎无法被 pyinstaller 跟踪。但是 contrib 文件夹正确放置在我的 python 安装中:C:\Python35\Lib\site-packages\tensorflow\contrib我该如何解决这个问题?

【问题讨论】:

    标签: python tensorflow pyinstaller


    【解决方案1】:

    在我的例子中,您可以在 .spec 文件中的 hiddenimport 中添加“tensorflow.contrib”。但是,我修复导入后遇到了另一个问题,但您至少可以先尝试一下。

    【讨论】:

    • 我们最终删除了代码中 tensorflow.contrib 的使用(它用于提供随机初始化)。但是你的评论很有用。升级 Tensorflow(尝试升级到 1.3 版)并没有解决问题。
    • 我最终手动将所有 .so 文件添加到 .spec 文件中,它终于可以工作了。就我而言,问题在于 tensorflow contrib 使用了大量的惰性加载器和相对路径,因此如果您不手动添加所有文件,pyinstaller 将无法找到它们。
    【解决方案2】:

    希望这可以帮助任何人

    `ModuleNotFoundError: No module named 'sklearn.*'`
    
    `ModuleNotFoundError: No module named 'h5py.*'`
    

    在构建 pyinstaller 期间或之后

    如果您收到h5py 错误的示例

    运行pyinstaller myscript.py 后会生成myscript.spec

    进去myscript.spec

    # -*- mode: python ; coding: utf-8 -*-
    
    block_cipher = None
    
    a = Analysis(['myscript.py'],
             binaries=None,
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=None)
    # ... rest of a file untouched
    

    添加

    from PyInstaller.utils.hooks import collect_submodules
    
    hidden_imports = collect_submodules('h5py')
    

    hiddenimports=hidden_imports,
    

    这样

    # -*- mode: python ; coding: utf-8 -*-
    
    block_cipher = None
    
    from PyInstaller.utils.hooks import collect_submodules
    
    hidden_imports = collect_submodules('h5py')
    
    a = Analysis(['myscript.py'],
             binaries=None,
             datas=[],
             hiddenimports=hidden_imports,
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=None)
    # ... rest of a file untouched
    

    然后保存myscript.spec并运行命令pyinstaller myscript.spec

    归功于9dogs Pyinstaller created exe file can not load a keras nn model

    【讨论】:

      【解决方案3】:

      您可以将“tensorflow.contrib”添加到 --hidden-import

      pyinstaller -F face_classify.py --hidden-import tensorflow.contrib

      【讨论】:

        【解决方案4】:

        即使是 pyinstaller 4.0(今天最新的稳定版本)也有这个错误。 但是,如果您不使用 --one_file,则有一种解决方法。 使用 --hiddenimports="tensorflow.contrib" 编译您的程序,然后将所有 .so 从 tensorflow.contrib 复制到可执行文件查找它们的位置。所以,你需要在 tensorflow 中创建 contrib 文件夹,然后复制库。

        mkdir path_to_dist/app_name/tensorflow/contrib
        
        cd /usr/local/lib/python3.6/dist-packages/tensorflow/contrib && find ./ -name *.so |xargs -i cp --parents {} path_to_dist/app_name/tensorflow/contrib/
        

        如果您不使用 python 3.6,请更改 python 版本。

        我不知道如何使用 --one_file 来制作它。

        来自 github 的 andrewjong 和 aodiwei 的致谢。解决方案在this 问题上。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-05-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-04
          相关资源
          最近更新 更多