我无法加载我的模型,因为我无法放置 PosixPath

问题描述 投票:0回答:8

我正在设置一个脚本,我需要使用

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的方法。我发现的唯一解决方案是更改模块中的内部包,但这不是解决此类问题的安全方法。


提前致谢。

python pytorch pickle pathlib fast-ai
8个回答
26
投票

只需将

PosixPath
重定向到
WindowsPath

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

我也在加载

fastai
模型,这个技巧有效。

重要:由于这可能会在以后引起问题,请记住在完成后设置

pathlib.PosixPath = temp


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


3
投票

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

from pathlib import Path

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

更新1

此解决方案仅适用于 Linux,在 Windows 上我仍然收到错误。



2
投票

这里的问题与 Python 根据操作系统处理路径的方式的差异有关:

  • PosixPath
    - 在 Linux / Unix 上

  • WindowsPath
    - 在 Windows 上

当在一个操作系统上使用

pickle
持久化对象时(例如 Linux - 如本例所示),有关类型/类的信息也会被持久化(此处:
PosixPath
)。

现在,当加载 pickle 文件时,Python 假设它将能够根据之前保存的类型信息重新创建对象。在这种情况下,它尝试重新创建

PosixPath
类型的对象,该对象被
pathlib
库阻止并且无法在 Windows 上实例化。在 Windows 上,应该使用
WindowsPath
来代替,但是
pickle
模块不能很好地处理这种依赖于操作系统的逻辑,因此它只能无奈地抛出错误。

理论上,您可以干扰

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

还有另一种可能性 - 对路径对象使用独立于平台的

PurePosixPath
类。


1
投票

根据提供的错误消息,您正在使用

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()
。它会自动为您的操作系统选择正确的格式。


1
投票

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

只需将

PosixPath
重定向到
WindowsPath
:

import pathlib

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

0
投票

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

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

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


0
投票

当您在 Google Colab 中训练了模型并尝试在 Windows 上访问时,通常会发生这种情况。 要解决这个问题,您只需将以下代码粘贴到 yolov5 的 detector.py 中

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

祝你有美好的一天!

© www.soinside.com 2019 - 2024. All rights reserved.