我正在尝试使用 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
np.load(path)
,现在是 np.load(path, boolean)
默认情况下,布尔值 (allow_pickle) 为 false
np.savez
文档,但没有提到酸洗,所以我不知道它是如何一开始就知道我保存的东西是 Pytorch 的东西,而不仅仅是 numpy...奇怪!如果您知道发生了什么,请与我们分享 :)
这是强制 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
这个问题仍然存在于 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 上的这个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)。
在我的情况下,与:
np.load(path, 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)
您可以尝试更改标志的值
np.load(training_image_names_array,allow_pickle=True)
上面列出的解决方案都不适合我:我用 python 3.7.3 运行 anaconda。对我有用的是
从 Anaconda powershell 运行“conda install numpy==1.16.1”
关闭并重新打开笔记本
allow_pickle=True
是默认值。
在 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 解决了这个问题:
找到 imdb.py 的路径,然后将标志添加到 np.load(path,...flag...)
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_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 版本的不兼容造成的更大问题,并且可能导致许多其他隐藏的错误或问题。
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
我降落在这里,尝试了您的方法,但无法弄清楚。
我实际上正在研究一个预先给定的代码,其中
pickle.load(path)
被使用了,所以我用
np.load(path, allow_pickle=True)
如果您尝试使用 np.save 保存 numpy 数组的 python 列表并使用 np.load 加载,也会发生该错误。我只是为了让 googler 看看这不是问题所在。如果列表确实是您要保存和加载的内容,也可以使用 allow_pickle=True
解决问题。
当您使用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 将解决它
[快速解决方案] 我通过在调用 np.load 时修改“allow_pickle”来实现它:
标签 = np.load("标签",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 中序列化了字典,
现在只是尝试用 np.load 替换行:
data = np.load('/content/123.npz',allow_pickle=True)
它有效!示例来源:fix object arrays cannot be loaded when allow_pickle=False
是的,安装以前版本的 numpy 解决了这个问题。
对于那些使用 PyCharm IDE 的人:
在我的 IDE(Pycharm)中,File->Settings->Project Interpreter:我发现我的 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
引发错误的那一行将 imdb.py
设置 allow_pickle=True
更改为 np.load
。
我遇到了同样的问题,这是错误的行
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
代替
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”。
如果您正在加载像 npz 格式这样的压缩存储文件,那么下面的代码会很好
np.load(path, allow_pickle=True)
确保在指定路径时,用单引号将其括起来,并且 allow_pickle = True
不应出现在任何引号中。
更改这行代码对我有用并解决了错误。
data_dict = np.load(data_path, encoding='latin1', allow_pickle=True).item()
请检查您的 numpy 模块是否正确导入。它将取代已弃用的版本。
不定期副业成功案例分享
TypeError: <lambda>() got multiple values for keyword argument 'allow_pickle'