【问题标题】:I can't load my model because I can't put a PosixPath我无法加载我的模型,因为我无法放置 PosixPath
【发布时间】:2019-07-31 08:33:10
【问题描述】:

我正在设置一个脚本,我需要使用fast-ai 包中的一些函数。事实是我在 Windows 上,当我定义路径时,来自 fast-ai 的名为 load_learner 的函数无法加载模型。

我已经尝试将函数更改为:

state = pickle.load(open(str(path) + '/' + str(fname), 'rb'))

代替:

state = pickle.load(open(path/fname, 'rb'))

但我收到此错误:

 File "lib\site-packages\fastai\basic_train.py", line 462, in load_learner
    state = pickle.load(open(path/fname, 'rb'))
  File "\lib\pathlib.py", line 1006, in __new__
    % (cls.__name__,))
NotImplementedError: cannot instantiate 'PosixPath' on your system

我的路径定义为:

folder_path = './models/model1'
fname = 'model.pkl'

我将函数称为: model = load_learner(folder_path, fname)

如何在此函数中使用 Windows 路径?


更新 1

发布的答案仅在 Linux 上是正确的。我在 Windows 上仍然有这个问题。我没有找到在 Windows 上通过 PosixPath 的方法。我找到的唯一解决方案是从我的模块中更改内部包,但这不是解决此类问题的安全方法。


提前致谢。

【问题讨论】:

  • 这可能是windows分隔符的问题,它是路径的双反斜杠\\,您可以使用os.sepsee轻松获得所有系统的正确分隔符。尝试用windows格式分隔符替换所有/
  • 请发布异常的整个堆栈跟踪。
  • 首先尝试将您的包更新到最新版本。有问题的代码不存在,因此它可能会解决您遇到的问题。

标签: python pytorch pickle pathlib fast-ai


【解决方案1】:

只需将PosixPath 重定向到WindowsPath

import pathlib
temp = pathlib.PosixPath
pathlib.PosixPath = pathlib.WindowsPath

我也在加载fastai 模型,这个技巧很有效。

【讨论】:

  • 因为这可能会导致以后出现问题,请记住在完成后设置pathlib.PosixPath = temp
  • 您还可以看到我的自动还原PosixPath 的建议(特别是如果您在导入时出错):stackoverflow.com/a/68796747/1603480
【解决方案2】:

根据我自己的问题,我找到了一种使用方法:

from pathlib import Path

folder_path = Path('./models/model1')

更新 1

此解决方案仅适用于 Linux,在 Windows 上仍然出现错误。


【讨论】:

  • 您好,有人提出了适用于 Windows 的解决方案。请更改接受的答案。谢谢
  • @Jean-FrancoisT。完成:)
【解决方案3】:

对于 posix 路径错误: 当你在 colab/gradient 上训练你的模型并下载它时, 然后在 Windows 上进行推理。

只需将PosixPath 重定向到WindowsPath

import pathlib

temp = pathlib.PosixPath
pathlib.PosixPath = pathlib.WindowsPath

【讨论】:

  • 欢迎来到stackoverflow。这应该作为对 KumaTea 答案的评论发布。
【解决方案4】:

根据提供的错误消息,您正在使用pathlib。所以你不需要在这里使用+ '/' +str(path) + '/' + str(fname)

/ 作为路径分隔符适用于 Linux/Unix:

state = pickle.load(open(path / fname, 'rb'))

在 Windows 上使用 .joinpath() 代替:

state = pickle.load(open(path.joinpath(fname), 'rb'))

如果您不打算使用pathlib,请使用os.path.join()。它会自动为您的操作系统选择正确的格式。

【讨论】:

  • 即使我在 Windows 上使用os.path.join(),我仍然会收到以下错误:state = pickle.load(open(path/fname, 'rb')) !! TypeError: unsupported operand type(s) for /: 'str' and 'str'。我正在尝试搜索一种不更改我的包脚本的方法。
【解决方案5】:

这里的问题与 Python 处理路径的方式不同有关,具体取决于操作系统:

  • PosixPath - 在 Linux / Unix 上

  • WindowsPath - 在 Windows 上

当使用pickle 在一个操作系统上持久化对象时(比如Linux - 在这种情况下),关于类型/类的信息也会被持久化(这里:PosixPath)。

现在,当 pickle 文件被加载时,Python 假设它能够根据之前保存的类型信息重新创建对象。在这种情况下,它会尝试重新创建 PosixPath 类型的对象,该对象被 pathlib 库阻止并且无法在 Windows 上实例化。在 Windows 上应该使用 WindowsPath 来代替,但 pickle 模块不能很好地处理这种依赖于操作系统的逻辑,因此它会无助地抛出错误。

理论上,您可以干预pathlib 的代码以删除操作系统检查,但没有简单的解决方法,但要避免对依赖于操作系统的对象进行酸洗(例如,将路径存储为字符串 - 正如 os.path 所做的那样 - 肯定会解决这个问题问题)。

There is also another possibility - 为路径对象使用独立于平台的PurePosixPath 类。

【讨论】:

    【解决方案6】:

    我正在研究同样的问题——将 fastai 模型部署为 Web 服务器并遇到了同样的问题,这就是我所做的...... 导出模型时使用 joblib 或 pickle 来腌制模型,而不是使用 learn.export() 并在服务器中使用以下代码。

     __model = pickle.load(open(os.path.join('./artifacts/saved_model.pkl'), 'rb'))
    

    通过这样做,它能够解决路径问题,但由于模型是使用 GPU 训练的,因此会出现要求将存储映射到 CPU 的错误

    【讨论】:

      【解决方案7】:

      在 Windows 上工作时,您可以临时将 pathlib.PosixPath 设置为 WindowsPath。恢复到原始值很重要,尤其是在pickle加载过程中出现异常时。

      一个简单的方法是做一个try / finally:

      posix_backup = pathlib.PosixPath
      try:
          pathlib.PosixPath = pathlib.WindowsPath
          learn_inf = load_learner(EXPORT_PATH)
      finally:
          pathlib.PosixPath = posix_backup
      

      如果你经常这样做,你可以让流程更顺畅,如下所示:

      1. 定义一个可以临时进行更改的函数
      2. with 块中使用它

      您可以将其添加到某处(如果您使用 Jupyter,则添加到脚本或专用单元格的顶部)。

      from contextlib import contextmanager
      import pathlib
      
      @contextmanager
      def set_posix_windows():
          posix_backup = pathlib.PosixPath
          try:
              pathlib.PosixPath = pathlib.WindowsPath
              yield
          finally:
              pathlib.PosixPath = posix_backup
      

      然后,像这样使用它:

      EXPORT_PATH = pathlib.Path("model.pkl")
      
      with set_posix_windows():
          learn_inf = load_learner(EXPORT_PATH)
      

      ...另外,请查看 sophros 的答案:https://stackoverflow.com/a/62836990/1603480

      【讨论】:

        猜你喜欢
        • 2011-11-18
        • 1970-01-01
        • 2013-12-20
        • 2020-11-22
        • 2022-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多