ChatGPT解决这个技术问题 Extra ChatGPT

如何修复 imdb.load_data() 函数的“allow_pickle=False 时无法加载对象数组”?

我正在尝试使用 Google Colab 中的 IMDb 数据集来实现二进制分类示例。我以前实现过这个模型。但是几天后我再次尝试执行此操作时,它为 load_data() 函数返回了 value error: 'Object arrays cannot be loaded when allow_pickle=False'

我已经尝试解决这个问题,参考类似问题的现有答案:How to fix 'Object arrays cannot be loaded when allow_pickle=False' in the sketch_rnn algorithm。但事实证明,仅仅添加一个 allow_pickle 参数是不够的。

我的代码:

from keras.datasets import imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)

错误:

ValueError                                Traceback (most recent call last)
<ipython-input-1-2ab3902db485> in <module>()
      1 from keras.datasets import imdb
----> 2 (train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)

2 frames
/usr/local/lib/python3.6/dist-packages/keras/datasets/imdb.py in load_data(path, num_words, skip_top, maxlen, seed, start_char, oov_char, index_from, **kwargs)
     57                     file_hash='599dadb1135973df5b59232a0e9a887c')
     58     with np.load(path) as f:
---> 59         x_train, labels_train = f['x_train'], f['y_train']
     60         x_test, labels_test = f['x_test'], f['y_test']
     61 

/usr/local/lib/python3.6/dist-packages/numpy/lib/npyio.py in __getitem__(self, key)
    260                 return format.read_array(bytes,
    261                                          allow_pickle=self.allow_pickle,
--> 262                                          pickle_kwargs=self.pickle_kwargs)
    263             else:
    264                 return self.zip.read(key)

/usr/local/lib/python3.6/dist-packages/numpy/lib/format.py in read_array(fp, allow_pickle, pickle_kwargs)
    690         # The array contained Python objects. We need to unpickle the data.
    691         if not allow_pickle:
--> 692             raise ValueError("Object arrays cannot be loaded when "
    693                              "allow_pickle=False")
    694         if pickle_kwargs is None:

ValueError: Object arrays cannot be loaded when allow_pickle=False
这个错误是什么意思?
@CharlieParker 显然在 numpy.load() 函数中添加了一个参数。以前是 np.load(path) ,现在是 np.load(path, boolean) 默认情况下,布尔值 (allow_pickle) 为 false
谢谢!但这是否意味着 numpy 现在在保存时未经我的许可为我腌制东西?!诡异的!我查看了 np.savez 文档,但没有提到酸洗,所以我不知道它是如何一开始就知道我保存的东西是 Pytorch 的东西,而不仅仅是 numpy...奇怪!如果您知道发生了什么,请与我们分享 :)
在遇到同样的问题后,我相信这完全取决于你保存到 .npz 的内容。如果您要保存内置类型,则无需酸洗。但是,如果您编写一个对象,python/numpy 将腌制它(即序列化它)。我想这会带来安全风险,因此后来的 numpy 版本不再允许它成为默认值……不过只是一种预感。

M
Matthew Kerian

这是强制 imdb.load_data 允许 pickle 的技巧,方法是在您的笔记本中替换此行:

(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)

这样:

import numpy as np
# save np.load
np_load_old = np.load

# modify the default parameters of np.load
np.load = lambda *a,**k: np_load_old(*a, allow_pickle=True, **k)

# call load_data with allow_pickle implicitly set to true
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)

# restore np.load for future normal usage
np.load = np_load_old

我建议在开头添加“import numpy as np”。 Numpy 可能以不同的名称导入,或者根本不导入......
它对我有很大帮助
出现错误 TypeError: <lambda>() got multiple values for keyword argument 'allow_pickle'
关键字参数的多个值的问题已在 stackoverflow.com/a/58586450/5214998 中解决
T
Tirth Patel

这个问题仍然存在于 keras git 上。我希望它尽快得到解决。在此之前,请尝试将您的 numpy 版本降级到 1.16.2。它似乎解决了这个问题。

!pip install numpy==1.16.1
import numpy as np

此版本的 numpy 的默认值为 allow_pickle 作为 True


我会使用 MappaGnosis 的解决方案,而不是降级 numpy 版本:对我来说,使用版本 dance 是最后的手段!
1.16.4 也有这个问题
谢谢@kensai。有谁知道这是否在 numpy 1.17 中得到解决?
在 numpy 1.18 中仍然存在这个问题。我不得不切换到 numpy 1.16.1,现在它解决了。谢谢你。
从 1.16 到 1.17 并没有太大变化。这是最有帮助的答案。
M
Madhuparna Bhowmik

我只是使用 allow_pickle = True 作为 np.load() 的参数,它对我有用。

np.load(path, allow_pickle=True)


我观察到允许泡菜改变数组。尝试使用 np.array_equal 断言相等时,保存之前和加载之后的 .npy 数组会抛出异常
M
MappaGnosis

按照 GitHub 上的这个issue,官方的解决方案是编辑 imdb.py 文件。这个修复对我来说效果很好,不需要降级 numpy。在 tensorflow/python/keras/datasets/imdb.py 找到 imdb.py 文件(我的完整路径是:C:\Anaconda\Lib\site-packages\tensorflow\python\keras\datasets\imdb.py - 其他安装会有所不同)并根据差异更改第 85 行:

-  with np.load(path) as f:
+  with np.load(path, allow_pickle=True) as f:

更改的原因是为了防止 Python 等价于腌制文件中的 SQL 注入。上面的更改只会影响 imdb 数据,因此您可以在其他地方保留安全性(通过不降级 numpy)。


正如我所说,我正在使用 Colab,如何在 imdb.py 文件中进行更改?
这不是 Colab 问题,因为 IMDB 是在您第一次引用它时在本地下载的。因此,您的计算机上的某处将有一个本地副本(尝试上面建议的路径 - 或者,如果您为 Colab 设置目录,请先尝试那里),然后只需在任何 IDE 甚至文本编辑器中打开 imdb.py 文件即可进行更改(我使用 Notepad ++ 编辑了在 Jupyter 中工作时下载的 imdb.py 文件 - 所以环境与 Colab 非常相似!)。
对我有用的解决方案是 > np.load(data_path, encoding='latin1',allow_pickle=True)
这是我使用的解决方案,因为在接受的答案中弄乱版本(尤其是 numpy)是我试图避免的。这也更加pythonic,因为它明确地解决了问题。 (还要注意最新版本的 Keras,在 github,实际上包含了这个修复)
H
Hossein

在我的情况下,与:

np.load(path, allow_pickle=True)

G
Gustavo Mirapalheta

我认为 cheez (https://stackoverflow.com/users/122933/cheez) 的答案是最简单、最有效的答案。我会详细说明一下,这样它就不会在整个会话期间修改 numpy 函数。

我的建议如下。我正在使用它从 keras 下载路透社数据集,该数据集显示相同类型的错误:

old = np.load
np.load = lambda *a,**k: old(*a,**k,allow_pickle=True)

from keras.datasets import reuters
(train_data, train_labels), (test_data, test_labels) = reuters.load_data(num_words=10000)

np.load = old
del(old)

你能解释一下这里发生了什么吗?
我无法加载 Keras 数据集。我在互联网上搜索并找到了一个解决方案,说我应该编辑 de imdb.py 文件,其他人指出 numpy 安装的更改(如这里)或将 Tensorflow 更改为开发版本。我遇到了奶酪解决方案。恕我直言,这是最简单和最有效的一种。
@Kanad - lambda 是一个匿名函数。 Gustavo 为 np.load 创建了一个函数增强,使用增强版本,然后设置回默认值。
B
Brayan Armando Yaquian Gonzale

您可以尝试更改标志的值

np.load(training_image_names_array,allow_pickle=True)

伟大的。它的工作。这应该是公认的答案。
F
Farid Khafizov

上面列出的解决方案都不适合我:我用 python 3.7.3 运行 anaconda。对我有用的是

从 Anaconda powershell 运行“conda install numpy==1.16.1”

关闭并重新打开笔记本


谢谢,这就是我搜索的。顺便说一句,看起来 1.16.2 是最新版本,其中 allow_pickle=True 是默认值。
Y
Yasser Albarbay

在 jupyter 笔记本上使用

np_load_old = np.load

# modify the default parameters of np.load
np.load = lambda *a,**k: np_load_old(*a, allow_pickle=True, **k)

工作正常,但是当您在 spyder 中使用此方法时会出现问题(您必须每次都重新启动内核,否则您将收到如下错误:

TypeError : () 为关键字参数“allow_pickle”获得了多个值

我使用解决方案 here 解决了这个问题:


L
Leonhard Rathnak

找到 imdb.py 的路径,然后将标志添加到 np.load(path,...flag...)

    def load_data(.......):
    .......................................
    .......................................
    - with np.load(path) as f:
    + with np.load(path,allow_pickle=True) as f:

O
Otabek

用这个

 from tensorflow.keras.datasets import imdb

而不是这个

 from keras.datasets import imdb

R
ReimuChan

它为我工作

        np_load_old = np.load
        np.load = lambda *a: np_load_old(*a, allow_pickle=True)
        (x_train, y_train), (x_test, y_test) = reuters.load_data(num_words=None, test_split=0.2)
        np.load = np_load_old

一些上下文解释了为什么您的解决方案有效。 (来自评论)。
S
SidK

我发现 TensorFlow 2.0(我使用的是 2.0.0-alpha0)与最新版本的 Numpy 不兼容,即 v1.17.0(可能还有 v1.16.5+)。一旦 TF2 被导入,它就会抛出一个巨大的 FutureWarning 列表,看起来像这样:

FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint8 = np.dtype([("qint8", np.int8, 1)])
/anaconda3/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:541: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint8 = np.dtype([("qint8", np.int8, 1)])
/anaconda3/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:542: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_quint8 = np.dtype([("quint8", np.uint8, 1)])
/anaconda3/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:543: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.

当尝试从 keras 加载 imdb 数据集时,这也导致了 allow_pickle 错误

我尝试使用以下解决方案,它工作得很好,但我必须在我导入 TF2 或 tf.keras 的每个项目中都这样做。

np.load = lambda *a,**k: np_load_old(*a, allow_pickle=True, **k)

我找到的最简单的解决方案是全局安装 numpy 1.16.1,或者在虚拟环境中使用兼容版本的 tensorflow 和 numpy。

我对这个答案的目标是指出这不仅仅是 imdb.load_data 的问题,而是由 TF2 和 Numpy 版本的不兼容造成的更大问题,并且可能导致许多其他隐藏的错误或问题。


S
Sajad Norouzi

answer of @cheez 有时不起作用并一次又一次地递归调用该函数。要解决此问题,您应该深入复制该功能。您可以使用函数 partial 来完成此操作,因此最终代码为:

import numpy as np
from functools import partial

# save np.load
np_load_old = partial(np.load)

# modify the default parameters of np.load
np.load = lambda *a,**k: np_load_old(*a, allow_pickle=True, **k)

# call load_data with allow_pickle implicitly set to true
(train_data, train_labels), (test_data, test_labels) = 
imdb.load_data(num_words=10000)

# restore np.load for future normal usage
np.load = np_load_old

P
Pmpr.ir

我降落在这里,尝试了您的方法,但无法弄清楚。

我实际上正在研究一个预先给定的代码,其中

pickle.load(path)

被使用了,所以我用

np.load(path, allow_pickle=True)

C
Carlos S Traynor

如果您尝试使用 np.save 保存 numpy 数组的 python 列表并使用 np.load 加载,也会发生该错误。我只是为了让 googler 看看这不是问题所在。如果列表确实是您要保存和加载的内容,也可以使用 allow_pickle=True 解决问题。


S
Shaina Raza

当您使用torchvision == 0.7.0 的以前版本的torch(如1.6.0)时会出现此错误,您可以通过以下命令检查您的torch 版本:

import tensorflow
print(tensorflow.__version__)

此错误已在较新版本的 Torch 中得到解决。

您可以通过在 np.load() 中进行以下更改来消除此错误

np.load(somepath, allow_pickle=True)

allow_pickle=True 将解决它


M
Mustafa Sakhai

[快速解决方案] 我通过在调用 np.load 时修改“allow_pickle”来实现它:

标签 = np.load("标签",allow_pickle=True)


I
Ivan Borshchov

有很多答案,但要真正理解这个问题,我建议您接下来尝试简单的示例:

a=np.array([[1, 2, 3], [4, 5, 6]])
# Object array
b={'data':'somet',
   'data_2':'defin'}
#Save arrays into file
np.savez('/content/123.npz', a=a, b=b)
#Load file into data variable
data = np.load('/content/123.npz')
print(data['b'])

这个简单的例子已经重现了这个错误。问题是你已经在 npz 中序列化了字典,

现在只是尝试用 np.load 替换行:

data = np.load('/content/123.npz',allow_pickle=True)

它有效!示例来源:fix object arrays cannot be loaded when allow_pickle=False


W
Wissam

是的,安装以前版本的 numpy 解决了这个问题。

对于那些使用 PyCharm IDE 的人:

在我的 IDE(Pycharm)中,File->Settings->Project Interpreter:我发现我的 numpy 是 1.16.3,所以我恢复到 1.16.1。单击 + 并在搜索中键入 numpy,勾选“指定版本”:1.16.1 并选择--> 安装包。


j
jww

我通常不发布这些东西,但这非常烦人。混淆来自一些 Keras imdb.py 文件已经更新的事实:

with np.load(path) as f:

到带有 allow_pickle=True 的版本。确保检查 imdb.py 文件以查看此更改是否已实施。如果它已被调整,以下工作正常:

from keras.datasets import imdb
(train_text, train_labels), (test_text, test_labels) = imdb.load_data(num_words=10000)

N
Nasif Imtiaz Ohi

最简单的方法是在 imdb.py 引发错误的那一行将 imdb.py 设置 allow_pickle=True 更改为 np.load


M
Mudasir Habib

我遇到了同样的问题,这是错误的行

File "/usr/lib/python3/dist-packages/numpy/lib/npyio.py", line 260, in __getitem__

所以我通过更新“npyio.py”文件来解决这个问题。在 npyio.py 第 196 行为 allow_pickle 赋值,所以我将此行更新为

self.allow_pickle = True

S
Sabito 錆兎 stands with Ukraine

代替

from keras.datasets import imdb

利用

from tensorflow.keras.datasets import imdb

top_words = 10000
((x_train, y_train), (x_test, y_test)) = imdb.load_data(num_words=top_words, seed=21)

J
Joocheol Kim

Tensorflow 在 tf-nightly 版本中有一个修复。

!pip install tf-nightly

当前版本是“2.0.0-dev20190511”。


P
Prometheus

如果您正在加载像 npz 格式这样的压缩存储文件,那么下面的代码会很好

np.load(path, allow_pickle=True)

确保在指定路径时,用单引号将其括起来,并且 allow_pickle = True 不应出现在任何引号中。


F
Fenil

更改这行代码对我有用并解决了错误。

data_dict = np.load(data_path, encoding='latin1', allow_pickle=True).item()

请检查您的 numpy 模块是否正确导入。它将取代已弃用的版本。


欢迎来到堆栈溢出。这个问题已有 3 年以上的历史,并且有许多现有答案,包括得分超过 150 分的公认答案。你完全确定这个答案引入了一些新的东西吗?如果是这样,您能edit澄清一下吗?应该修改哪一行,具体修改是什么(不仅仅是整行,而是具体你要改什么),为什么?见How to Answer
是的,基本上它是由于不推荐使用的 tenserflow 版本而发生的。因此,如果有人正在使用诸如 vs code 之类的编辑器而不是该流行答案中提到的笔记本,则替换我提供的 line 代码解决了 allow_pickled 问题。谢谢!

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅