如何修复imdb.load_data()函数的'Object arrays cannot be loaded when allow_pickle=False'?



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

我已经尝试解决这个问题,参考类似问题的现有答案:如何修复sketch_rnn算法中的"当 allow_pickle=False 时无法加载对象数组"。但事实证明,仅仅添加一个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

这里有一个技巧,可以强制imdb.load_data在笔记本中允许泡菜,替换此行:

(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

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

!pip install numpy==1.16.1
import numpy as np

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

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

np.load(path, allow_pickle=True)

在 GitHub 上出现此问题后,官方解决方案是编辑 imdb.py 文件。 此修复程序对我来说效果很好,无需降级 numpy。 在 tensorflow/python/keras/datasets/imdb.py 处找到 imdb.py 文件(我的完整路径是:C:AnacondaLibsite-packagestensorflowpythonkerasdatasetsimdb.py - 其他安装会有所不同(并根据差异更改第 85 行:

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

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

在我的情况下,使用:

np.load(path, allow_pickle=True)

您可以尝试更改标志的值

np.load(training_image_names_array,allow_pickle=True)

我认为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)

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

  • 从 Anaconda Powershell 运行"conda install numpy==1.16.1">

  • 关闭并重新打开笔记本

在 Jupyter notebook 上使用

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中使用此方法时会出现问题(您必须每次重新启动内核,否则会出现如下错误:

类型错误 : (( 为关键字参数 'allow_pickle' 获取多个值

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

找到通往 imdb.py 的路径然后只需将标志添加到 np.load(path,...旗帜...

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

使用这个

 from tensorflow.keras.datasets import imdb

而不是这个

 from keras.datasets import imdb

如果您尝试使用 np.save 保存 numpy 数组的 python 列表并使用 np.load 加载,也可能发生此错误。我只是为了谷歌用户而说,看看这不是问题。如果列表确实是您要保存和加载的内容,则使用 allow_pickle=True 修复了该问题。

它对我的工作

        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列表,看起来像这样:

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版本的不兼容而出现,并可能导致许多其他隐藏的错误或问题。

@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

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

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

pickle.load(path)

被使用了,所以我用

np.load(path, allow_pickle=True)

当您拥有以前版本的火炬(如 1.6.0(和火炬视觉==0.7.0 时,会出现此错误,您可以通过以下命令检查您的火炬版本:

import tensorflow
print(tensorflow.__version__)

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

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

np.load(somepath, allow_pickle=True)

allow_pickle=True 将解决它

[快速解决方案] 我在调用 np.load 时通过修改"allow_pickle"来工作:

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

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

现在 jus ttry 将行替换为 np.load

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

它有效!示例来源:当 allow_pickle=False

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

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

在我的IDE(Pycharm(中,文件>设置>项目解释器:我发现我的numpy是1.16.3,所以我恢复到1.16.1。单击+并在搜索中键入numpy,勾选"指定版本":1.16.1并选择-->安装包。

我通常不会发布这些东西,但这非常烦人。混乱来自一些 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)

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

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

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

所以我通过更新"npyio.py"文件来解决问题。在第 196 行 npyio.py 将值分配给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)

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

!pip install tf-nightly

当前版本为"2.0.0-dev20190511"。

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

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

请检查您的 NUMPY 模块是否正确导入。它将替换已弃用的版本。

最新更新