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

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

我已经试图解决这个问题,参考了一个类似问题的现有答案: 如何修复对象数组不能加载时允许 _ pickle = False & # 39; 在素描 _ rnn 算法。 但事实证明,仅仅添加 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
240394 次浏览

这个问题还没有解决,希望能尽快得到解决。 在那之前,试着把你的麻木的版本降级到1.16.2。这似乎解决了问题。

!pip install numpy==1.16.1
import numpy as np

这个 numpy 版本的默认值为 allow_pickle,即 True

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

对于那些使用 PyCharm IDE 的用户:

在我的 IDE (Pycharm)中,File-> Settings-> Project Interpreter: 我发现我的 numpy 是1.16.3,所以我返回到1.16.1。 单击 + 并在搜索中键入 numpy,勾选“指定版本”: 1.16.1,然后选择—— > install package。

在 GitHub 上的 问题之后,官方解决方案是编辑 imdb.py 文件。这个修复对我很有效,不需要降级麻木。在 tensorflow/python/keras/datasets/imdb.py找到 imdb.py 文件(我的完整路径是: C:\Anaconda\Lib\site-packages\tensorflow\python\keras\datasets\imdb.py-其他安装将不同) ,然后根据 diff 更改第85行:

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

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

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

!pip install tf-nightly

当前版本是“2.0.0-dev20190511”。

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

np.load(path, allow_pickle=True)

下面是一个强制 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

我认为来自芝士(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)

您可以尝试更改标志的值

np.load(training_image_names_array,allow_pickle=True)

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

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

在木星笔记本上使用

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’的多个值

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

对我有用

        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

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

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 版本不兼容造成的一个更大的问题,可能会导致许多其他隐藏的错误或问题。

上面列出的所有解决方案都不适合我: 我用 python3.7.3运行 anaconda。 对我有用的是

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

  • 合上并重新打开笔记本

答案是: “奶酪”有时无法工作,递归地一次又一次地调用函数。要解决这个问题,您应该深度复制函数。您可以使用函数 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

在我的案例中:

np.load(path, allow_pickle=True)

我通常不发这些东西,但这是超级恼人的。令人困惑的是,一些 Kera 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)

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

我来到这里,尝试了你的方法,但是不明白。

我实际上在研究一个预设的密码

pickle.load(path)

所以我把它换成了

np.load(path, allow_pickle=True)

用这个

 from tensorflow.keras.datasets import imdb

而不是这样

 from keras.datasets import imdb

如果尝试使用 np.save 保存 numpy 数组的 python 列表,并使用 np.load 加载,也可能出现此错误。我这么说只是为了谷歌的检查,这不是问题所在。还使用 allow_pickle=True修复了问题,如果一个列表确实是你想要保存和加载的。

这个错误出现在你使用旧版本的 torchvision = = 0.7.0,比如1.6.0, 您可以通过以下命令检查您的手电筒版本:

import tensorflow
print(tensorflow.__version__)

这个错误已经在较新版本的焊枪中解决了。

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

np.load(somepath, allow_pickle=True)

Allow _ pickle = True 将解决这个问题

我当时也面临着同样的问题,这里有一行错误

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

所以我通过更新“ npyio.py”文件来解决这个问题。 在 npyio.py 行196中,将 value 赋给 allow _ pickle,因此我将这一行更新为

self.allow_pickle = True

而不是

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)

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

Label = np.load (“ Labels”,allow_pickle=True)

答案有很多,但要真正理解这个问题,我建议你试试下面这个简单的例子:

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'])

这个简单的例子已经重现了这个错误,

现在试着用 Np.load代替 line:

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

成功了! 例子来源: 在 allow _ pickle = False 时,不能加载 fix 对象数组

如果您正在加载压缩存储文件,如 npz 格式,那么下面的代码将做得很好

np.load(path, allow_pickle=True)

在指定 path 时,请确保它周围都是单引号,而且 allow_pickle = True不应该出现在任何引号中。

改变这行代码对我很有效,并解决了这个错误。

Data _ dict = np.load (data _ path,coding = ‘ latin1’,allow _ pickle = True) . item ()

检查你的 numpy 模块是否正确导入。 它将取代过时的版本。