5

我正在设置一个脚本,我需要使用 package.json 中的一些函数fast-ai。事实是我在 Windows 上,当我定义路径时,fast-ainamed的函数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 的方法。我发现的唯一解决方案是从我的模块中更改内部包,但这不是解决此类问题的安全方法。


提前致谢。

4

7 回答 7

13

只需重定向PosixPathWindowsPath.

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

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

于 2020-10-04T21:50:37.627 回答
2

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

from pathlib import Path

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

更新 1

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


于 2019-07-31T13:34:47.340 回答
1

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

只需重定向PosixPathWindowsPath

import pathlib

temp = pathlib.PosixPath
pathlib.PosixPath = pathlib.WindowsPath
于 2020-10-16T17:12:37.943 回答
0

根据您正在使用的提供的错误消息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()。它会自动为您的操作系统选择正确的格式。

于 2019-07-31T11:30:05.863 回答
0

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

  • PosixPath- 在 Linux / Unix 上

  • WindowsPath- 在 Windows 上

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

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

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

还有另一种可能性PurePosixPath-为路径对象使用与平台无关的类。

于 2020-07-10T14:58:29.603 回答
0

我正在开发相同的-将fastai模型部署为Web服务器并遇到相同的问题,这就是我所做的......导出模型时使用joblib或pickle来腌制模型而不是使用learn.export()和服务器使用下面的代码。

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

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

于 2020-07-20T08:27:51.607 回答
0

在 Windows 上工作时,您可以临时设置pathlib.PosixPathWindowsPath. 恢复到原始值很重要,尤其是在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

于 2021-08-16T02:14:45.380 回答