Я пытаюсь реализовать пример бинарной классификации, используя набор данных 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
@CharlieParker Очевидно, в функцию numpy.load() был добавлен параметр. Раньше было np.load(path) , теперь np.load(path, boolean) По умолчанию логическое значение (allow_pickle) равно false
Спасибо! но значит ли это, что numpy теперь собирает вещи для меня без моего разрешения при сохранении?! странный! Я просмотрел np.savez документы, но там не было упоминания о травлении, поэтому я понятия не имею, как он вообще знал, что вещи, которые я сохранял, были вещами Pytorch, а не только numpy ... странно! Если вы знаете, что происходит, поделитесь с нами :)
Я считаю, что после того, как столкнулся с той же проблемой, это полностью зависит от какие, который вы сохраняете в .npz. Если вы сохраняете встроенные типы, то никакого травления. Однако, если вы напишете объект, python/numpy его замаринует (т.е. сериализует). Я предполагаю, что это создает угрозу безопасности, поэтому более поздние версии numpy перестали разрешать его использовать по умолчанию... хотя это просто догадка.






Эта проблема все еще находится на 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. Это самый полезный ответ.
Да, установка предыдущей версии 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?
Это не проблема Colab, поскольку IMDB загружается локально при первом обращении к нему. Итак, где-то на вашем компьютере будет локальная копия (попробуйте предложенные выше пути — или, если вы задали каталог для Colab, попробуйте сначала там) и просто откройте файл imdb.py в любой IDE или даже текстовом редакторе, чтобы внесите изменения (я использовал Notepad ++ для редактирования файла imdb.py, который был загружен при работе в Jupyter, поэтому среда очень похожа на Colab!).
решение, которое работает для меня, это > np.load(data_path, encoding='latin1',allow_pickle=True)
Это решение, которое я использую, так как возиться с версиями (особенно с numpy), как в принятом ответе, я стараюсь избегать. Это также более питонично, поскольку явно просто устраняет проблему. (Обратите внимание, что новейшие версии Keras на github фактически включают это исправление)
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
Вот трюк, чтобы заставить 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 может быть импортирован под другим именем или вообще не импортирован...
Это мне очень помогает
Получение ошибки TypeError: <lambda>() got multiple values for keyword argument 'allow_pickle'
Проблема множественных значений аргумента ключевого слова была решена в stackoverflow.com/a/58586450/5214998.
Я думаю, что ответ от 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)
Можете ли вы объяснить больше о том, что здесь происходит?
Я не смог загрузить наборы данных Keras. Я искал в Интернете и нашел решение, в котором говорилось, что я должен отредактировать файл imdb.py, другие указывали на изменения в установке numpy (например, здесь) или изменение Tensorflow на версию для разработки. Я наткнулся на сырное решение. ИМХО это было самое простое и эффективное.
@Kanad - лямбда - анонимная функция. Густаво создал функцию-дополнение к np.load, использовал расширенную версию, а затем вернул значение по умолчанию.
Вы можете попробовать изменить значение флага
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:
на ноутбуке 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
И некоторый контекст, объясняющий, почему ваше решение работает. (Из обзора).
Я обнаружил, что 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 — значение по умолчанию.
ответ @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 не должно быть ни в каких кавычках.
Что означает эта ошибка?