Как исправить «Массивы объектов не могут быть загружены, когда allow_pickle = False» для функции imdb.load_data ()?

Я пытаюсь реализовать пример бинарной классификации, используя набор данных IMDb в Google Колаб. Я реализовал эту модель раньше. Но когда я попытался сделать это снова через несколько дней, он вернул value error: 'Object arrays cannot be loaded when allow_pickle=False' для функции load_data().

Я уже пытался решить эту проблему, ссылаясь на существующий ответ на аналогичную проблему: Как исправить «Массивы объектов не могут быть загружены, когда allow_pickle=False» в алгоритме sketch_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

Что означает эта ошибка?

Charlie Parker 16.07.2019 19:52

@CharlieParker Очевидно, в функцию numpy.load() был добавлен параметр. Раньше было np.load(path) , теперь np.load(path, boolean) По умолчанию логическое значение (allow_pickle) равно false

Kanad 17.07.2019 15:02

Спасибо! но значит ли это, что numpy теперь собирает вещи для меня без моего разрешения при сохранении?! странный! Я просмотрел np.savez документы, но там не было упоминания о травлении, поэтому я понятия не имею, как он вообще знал, что вещи, которые я сохранял, были вещами Pytorch, а не только numpy ... странно! Если вы знаете, что происходит, поделитесь с нами :)

Charlie Parker 18.07.2019 18:21

Я считаю, что после того, как столкнулся с той же проблемой, это полностью зависит от какие, который вы сохраняете в .npz. Если вы сохраняете встроенные типы, то никакого травления. Однако, если вы напишете объект, python/numpy его замаринует (т.е. сериализует). Я предполагаю, что это создает угрозу безопасности, поэтому более поздние версии numpy перестали разрешать его использовать по умолчанию... хотя это просто догадка.

Robert Lugg 05.05.2020 18:45
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
140
4
207 206
26
Перейти к ответу Данный вопрос помечен как решенный

Ответы 26

Эта проблема все еще находится на keras git. Я надеюсь, что это будет решено как можно скорее. А пока попробуйте понизить версию numpy до 1.16.2. Кажется, это решает проблему.

!pip install numpy==1.16.1
import numpy as np

Эта версия numpy имеет значение по умолчанию allow_pickle как True.

Я бы использовал решение от MappaGnosis, а не понизить версию numpy: для меня возиться с версией dance - это последнее средство!

eric 07.06.2019 16:06

1.16.4 тоже проблема

kensai 13.06.2019 15:03

Спасибо @kensai. Кто-нибудь знает, решена ли эта проблема в numpy 1.17?

nsheff 15.08.2019 15:17

В numpy 1.18 эта проблема все еще присутствует. Мне пришлось переключиться на numpy 1.16.1, и теперь это решено. Спасибо.

BC Smith 24.12.2019 17:03

ничего особенного не изменилось с 1.16 на 1.17. Это самый полезный ответ.

ArtificiallyIntelligence 15.10.2020 19:32

Да, установка предыдущей версии 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. Это исправление хорошо сработало для меня без необходимости понижать версию numpy. Найдите файл imdb.py в tensorflow/python/keras/datasets/imdb.py (полный путь для меня был: C:\Anaconda\Lib\site-packages\tensorflow\python\keras\datasets\imdb.py - другие установки будут другими) и измените строку 85 в соответствии с diff:

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

Причиной изменения является безопасность, чтобы предотвратить эквивалент Python-инъекции SQL в маринованном файле. Вышеупомянутое изменение повлияет ТОЛЬКО на данные imdb, и поэтому вы сохраните безопасность в другом месте (не понижая numpy).

Как я уже сказал, я использую Colab, как я могу внести изменения в файл imdb.py?

Kanad 16.05.2019 03:43

Это не проблема Colab, поскольку IMDB загружается локально при первом обращении к нему. Итак, где-то на вашем компьютере будет локальная копия (попробуйте предложенные выше пути — или, если вы задали каталог для Colab, попробуйте сначала там) и просто откройте файл imdb.py в любой IDE или даже текстовом редакторе, чтобы внесите изменения (я использовал Notepad ++ для редактирования файла imdb.py, который был загружен при работе в Jupyter, поэтому среда очень похожа на Colab!).

MappaGnosis 16.05.2019 16:41

решение, которое работает для меня, это > np.load(data_path, encoding='latin1',allow_pickle=True)

Jorge Santos Neill 17.05.2019 06:59

Это решение, которое я использую, так как возиться с версиями (особенно с numpy), как в принятом ответе, я стараюсь избегать. Это также более питонично, поскольку явно просто устраняет проблему. (Обратите внимание, что новейшие версии Keras на github фактически включают это исправление)

eric 07.06.2019 16:07

Tensorflow имеет исправление в версии tf-nightly.

!pip install tf-nightly

Текущая версия — «2.0.0-dev20190511».

Я просто использовал allow_pickle = True в качестве аргумента для np.load(), и это сработало для меня.

np.load(path, allow_pickle=True)

Я наблюдаю, что разрешение pickle изменяет массив. Массив .npy перед сохранением и после загрузки создает исключение при попытке подтвердить равенство с помощью np.array_equal

yasht 11.11.2019 01:42
Ответ принят как подходящий

Вот трюк, чтобы заставить 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

Я предлагаю вначале добавить «import numpy as np». Numpy может быть импортирован под другим именем или вообще не импортирован...

Kristóf 03.07.2019 18:02

Это мне очень помогает

staticor 02.08.2019 16:34

Получение ошибки TypeError: <lambda>() got multiple values for keyword argument 'allow_pickle'

Hayat 16.10.2019 07:23

Проблема множественных значений аргумента ключевого слова была решена в stackoverflow.com/a/58586450/5214998.

Sajad Norouzi 28.10.2019 07:28

Я думаю, что ответ от cheez (https://stackoverflow.com/users/122933/cheez) самый простой и эффективный. Я бы немного уточнил, чтобы он не модифицировал функцию numpy в течение всего периода сеанса.

Мое предложение ниже. Я использую его для загрузки набора данных reuters из 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)

Можете ли вы объяснить больше о том, что здесь происходит?

Kanad 24.05.2019 11:49

Я не смог загрузить наборы данных Keras. Я искал в Интернете и нашел решение, в котором говорилось, что я должен отредактировать файл imdb.py, другие указывали на изменения в установке numpy (например, здесь) или изменение Tensorflow на версию для разработки. Я наткнулся на сырное решение. ИМХО это было самое простое и эффективное.

Gustavo Mirapalheta 24.05.2019 19:06

@Kanad - лямбда - анонимная функция. Густаво создал функцию-дополнение к np.load, использовал расширенную версию, а затем вернул значение по умолчанию.

EngrStudent 30.05.2019 19:44

Вы можете попробовать изменить значение флага

np.load(training_image_names_array,allow_pickle=True)

Здорово. Это работает. Это должен быть принятый ответ.

Biranchi 15.07.2020 11:23

найти путь к imdb.py затем просто добавьте флаг в np.load(path,...flag...)

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

на ноутбуке 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 : () got multiple values for keyword argument '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

И некоторый контекст, объясняющий, почему ваше решение работает. (Из обзора).

ZF007 19.08.2019 12:59

Я обнаружил, что 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'.

Это также привело к ошибке allow_pickle при попытке загрузить набор данных imdb из keras.

Я попытался использовать следующее решение, которое отлично сработало, но мне приходилось делать это в каждом отдельном проекте, где я импортировал 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, которая может привести ко многим другим скрытым ошибкам или проблемам.

ни одно из перечисленных выше решений не сработало для меня: я запускаю anaconda с python 3.7.3. Что сработало для меня, так это

  • запустите «conda install numpy == 1.16.1» из Anaconda powershell

  • закройте и снова откройте блокнот

Спасибо, это то, что я искал. Кстати, похоже, что 1.16.2 — самая новая версия, где allow_pickle=True — значение по умолчанию.

Matěj Račinský 31.03.2020 23:10

ответ @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

В моем случае работал с:

np.load(path, allow_pickle=True)

Я обычно не публикую такие вещи, но это было очень раздражающим. Путаница возникает из-за того, что некоторые файлы 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 выдает ошибку.

Я приземлился здесь, пробовал ваши способы и не мог понять.

На самом деле я работал над заранее заданным кодом, где

pickle.load(path)

был использован, поэтому я заменил его на

np.load(path, allow_pickle=True)

Использовать этот

 from tensorflow.keras.datasets import imdb

вместо этого

 from keras.datasets import imdb

Ошибка также может возникнуть, если вы попытаетесь сохранить список python массивов numpy с помощью np.save и загрузить с помощью np.load. Я говорю это только для того, чтобы гуглеры убедились, что это не проблема. Также использование allow_pickle=True устранило проблему, если список действительно был тем, что вы хотели сохранить и загрузить.

Эта ошибка возникает, если у вас установлена ​​предыдущая версия факела, например 1.6.0 с torchvision==0.7.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». В строке 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)

[Быстрое решение] У меня получилось, изменив "allow_pickle" при вызове np.load:

метки = 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)

И это работает! Источник примера: исправить массивы объектов не могут быть загружены, когда allow_pickle=False

Если вы загружаете файл сжатого хранилища, такой как формат npz, тогда приведенный ниже код будет полезен.

np.load(path, allow_pickle=True)

Убедитесь, что при указании пути вы заключаете его в одинарные кавычки, а allow_pickle = True не должно быть ни в каких кавычках.

Другие вопросы по теме