118
votes

Comment réparer 'Les tableaux d'objets ne peuvent pas être chargés lorsque allow_pickle = False' pour la fonction imdb.load_data ()?

J'essaie d'implémenter l'exemple de classification binaire en utilisant l'ensemble de données IMDb dans Google Colab . J'ai déjà implémenté ce modèle. Mais quand j'ai essayé de le faire à nouveau après quelques jours, cela a renvoyé une value error: 'Object arrays cannot be loaded when allow_pickle=False' pour la fonction load_data ().

J'ai déjà essayé de résoudre cela, en me référant à une réponse existante pour un problème similaire: Comment réparer «Les tableaux d'objets ne peuvent pas être chargés lorsque allow_pickle = False» dans l'algorithme sketch_rnn . Mais il s'avère que simplement ajouter un argument allow_pickle n'est pas suffisant.

Mon code:

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

L'erreur:

from keras.datasets import imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)


4 commentaires

Que signifie cette erreur?


@CharlieParker Apparemment, il y a eu un ajout d'un paramètre dans la fonction numpy.load (). Auparavant, c'était np.load(path) , maintenant c'est np.load(path, boolean) Par défaut, le booléen (allow_pickle) est faux


Merci! mais cela signifie-t-il que numpy maintenant des choses pour moi sans ma permission lors de l'enregistrement?! bizarre! J'ai regardé les documents de np.savez mais il n'y avait aucune référence au décapage, donc je ne sais pas comment il savait même en premier lieu que les choses que je sauvegardais étaient des trucs de Pytorch et pas seulement stupides ... bizarres! Si vous savez ce qui se passe, partagez avec nous :)


Ma conviction après avoir rencontré le même problème est que cela dépend totalement de ce que vous enregistrez dans un fichier .npz. Si vous enregistrez des types intégrés, pas de décapage. Cependant, si vous écrivez un objet, python / numpy le décapera (c'est-à-dire le sérialisera). J'imagine que cela ouvre un risque de sécurité, donc les versions ultérieures de numpy ont cessé de l'autoriser par défaut ... juste une intuition cependant.


20 Réponses :


94
votes

Ce problème est toujours d'actualité sur keras git. J'espère que cela sera résolu le plus rapidement possible. Jusque-là, essayez de rétrograder votre version numpy à 1.16.2. Cela semble résoudre le problème.

!pip install numpy==1.16.1
import numpy as np

Cette version de numpy a la valeur par défaut de allow_pickle comme True .


5 commentaires

J'utiliserais la solution de MappaGnosis plutôt que de rétrograder la version numpy: pour moi, jouer avec la version dance est un dernier recours!


1.16.4 a aussi le problème


Merci @kensai. Est-ce que quelqu'un sait si cela a été résolu dans numpy 1.17?


Dans numpy 1.18, ce problème est toujours présent. J'ai dû passer à numpy 1.16.1 et c'est résolu maintenant. Merci.


rien de trop changé de 1.16 à 1.17. C'est la réponse la plus utile.



1
votes

Oui, l'installation d'une version précédente de numpy a résolu le problème.

Pour ceux qui utilisent PyCharm IDE:

dans mon IDE (Pycharm), File-> Settings-> Project Interpreter: j'ai trouvé que mon numpy était 1.16.3, donc je reviens à 1.16.1. Cliquez sur + et tapez numpy dans la recherche, cochez "spécifier la version": 1.16.1 et choisissez -> installer le package.


0 commentaires

56
votes

Suite à ce problème sur GitHub, la solution officielle consiste à éditer le fichier imdb.py. Ce correctif a bien fonctionné pour moi sans qu'il soit nécessaire de rétrograder numpy. Trouvez le fichier imdb.py sur tensorflow/python/keras/datasets/imdb.py (le chemin complet pour moi était: C:\Anaconda\Lib\site-packages\tensorflow\python\keras\datasets\imdb.py - autres installations sera différent) et changez la ligne 85 selon le diff:

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

La raison du changement est la sécurité pour empêcher l'équivalent Python d'une injection SQL dans un fichier pickled. Le changement ci-dessus affectera UNIQUEMENT les données imdb et vous conservez donc la sécurité ailleurs (en ne rétrogradant pas numpy).


4 commentaires

Comme je l'ai dit, j'utilise Colab, comment puis-je apporter des modifications au fichier imdb.py?


Ce n'est pas un problème Colab car IMDB est téléchargé localement la première fois que vous le référencez. Donc, il y aura une copie locale quelque part sur votre ordinateur (essayez les chemins suggérés ci-dessus - ou, si vous définissez un répertoire pour Colab, essayez-le d'abord) et ouvrez simplement le fichier imdb.py dans n'importe quel IDE ou même un éditeur de texte pour faire le changement (j'ai utilisé Notepad ++ pour éditer le fichier imdb.py qui a été téléchargé lors de l'utilisation de Jupyter - donc un environnement très similaire à Colab!).


la solution qui fonctionne pour moi est> np.load (data_path, encoding = 'latin1', allow_pickle = True)


C'est la solution que j'utilise, car déconner avec les versions (en particulier de numpy), comme dans la réponse acceptée, est quelque chose que j'essaie d'éviter. Ceci est également plus pythonique car il résout explicitement le problème. (Notez également que les dernières versions de Keras, sur github, incorporent en fait ce correctif)



0
votes

Tensorflow a un correctif dans la version tf-nightly.

!pip install tf-nightly

La version actuelle est «2.0.0-dev20190511».


0 commentaires

36
votes

Je viens d'utiliser allow_pickle = True comme argument de np.load () et cela a fonctionné pour moi.


1 commentaires

J'observe que permettre au pickle change le tableau. Le tableau .npy avant l'enregistrement et après le chargement émet une exception lors de la tentative d'affirmation de l'égalité à l'aide de np.array_equal



132
votes

Voici une astuce pour forcer imdb.load_data à autoriser pickle en remplaçant cette ligne dans votre notebook:

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

par ça:

(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)


4 commentaires

Je suggère d'ajouter "import numpy as np" au début. Numpy peut être importé sous un nom différent, ou pas du tout importé ...


Cela m'aide beaucoup


Obtention de l'erreur TypeError: <lambda>() got multiple values for keyword argument 'allow_pickle'


Le problème des valeurs multiples pour l'argument de mot-clé a été résolu dans stackoverflow.com/a/58586450/5214998



11
votes

Je pense que la réponse de cheez ( https://stackoverflow.com/users/122933/cheez ) est la plus simple et la plus efficace. Je développerais un peu plus dessus pour ne pas modifier une fonction numpy pendant toute la période de session.

Ma suggestion est ci-dessous. Je l'utilise pour télécharger le jeu de données reuters de keras qui montre le même type d'erreur:

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)


3 commentaires

Pouvez-vous expliquer plus sur ce qui se passe ici?


Je ne pouvais pas charger les ensembles de données Keras. J'ai cherché sur Internet et j'ai trouvé une solution qui disait que je devais éditer le fichier de imdb.py, d'autres ont signalé des changements dans l'installation de numpy (comme ici) ou le changement de Tensorflow vers une version de développement. Je suis tombé sur une solution cheez. IMHO qui était le plus simple et le plus efficace.


@Kanad - lambda est une fonction anonyme. Gustavo a créé une fonction-augment pour le np.load, utilisé la version augmentée, puis remis à la valeur par défaut.



8
votes

Vous pouvez essayer de changer la valeur de l'indicateur

np.load(training_image_names_array,allow_pickle=True)


1 commentaires

Génial. Ça marche. Cela devrait être la réponse acceptée.



2
votes

trouvez le chemin vers imdb.py puis ajoutez simplement le drapeau à np.load (chemin, ... drapeau ...)

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


0 commentaires

3
votes

sur le notebook jupyter en utilisant

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)

a bien fonctionné, mais le problème apparaît lorsque vous utilisez cette méthode dans spyder (vous devez redémarrer le noyau à chaque fois ou vous obtiendrez une erreur comme:

TypeError: () a obtenu plusieurs valeurs pour l'argument de mot clé 'allow_pickle'

J'ai résolu ce problème en utilisant la solution ici :


0 commentaires

1
votes

Son travail pour moi

        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


1 commentaires

Et un contexte expliquant pourquoi votre solution fonctionne. (De l'avis).



1
votes

Ce que j'ai trouvé, c'est que TensorFlow 2.0 (j'utilise 2.0.0-alpha0) n'est pas compatible avec la dernière version de Numpy ie v1.17.0 (et peut-être v1.16.5 +). Dès que TF2 est importé, il lance une énorme liste de FutureWarning, qui ressemble à ceci:

np.load = lambda *a,**k: np_load_old(*a, allow_pickle=True, **k)

Cela a également entraîné l'erreur allow_pickle lors de la tentative de chargement du jeu de données imdb à partir de keras

J'ai essayé d'utiliser la solution suivante qui fonctionnait très bien, mais je devais le faire pour chaque projet où j'importais TF2 ou tf.keras.

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'.

La solution la plus simple que j'ai trouvée était soit d'installer numpy 1.16.1 globalement, soit d'utiliser des versions compatibles de tensorflow et numpy dans un environnement virtuel.

Mon objectif avec cette réponse est de souligner que ce n'est pas seulement un problème avec imdb.load_data, mais un problème plus important provoqué par l'incompatibilité des versions TF2 et Numpy et peut entraîner de nombreux autres bogues ou problèmes cachés.


0 commentaires

4
votes

aucune des solutions énumérées ci-dessus n'a fonctionné pour moi: je lance anaconda avec python 3.7.3. Ce qui a fonctionné pour moi était

  • exécutez "conda install numpy == 1.16.1" depuis Anaconda powershell

  • fermez et rouvrez le notebook


1 commentaires

Merci, c'est ce que j'ai recherché. À propos, il semble que la 1.16.2 est la dernière version où allow_pickle=True est la valeur par défaut.



0
votes

La réponse de @cheez parfois ne fonctionne pas et appelle récursivement la fonction encore et encore. Pour résoudre ce problème, vous devez copier la fonction en profondeur. Vous pouvez le faire en utilisant la fonction partial , donc le code final est:

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


0 commentaires

19
votes

Dans mon cas, j'ai travaillé avec:

np.load(path, allow_pickle=True)


0 commentaires

0
votes

Je ne poste généralement pas sur ces choses mais c'était super ennuyeux. La confusion vient du fait que certains des fichiers Keras imdb.py ont déjà été mis à jour:

from keras.datasets import imdb
(train_text, train_labels), (test_text, test_labels) = imdb.load_data(num_words=10000)

à la version avec allow_pickle=True . Assurez-vous de vérifier le fichier imdb.py pour voir si ce changement a déjà été implémenté. S'il a été ajusté, ce qui suit fonctionne correctement:

with np.load(path) as f:


0 commentaires

0
votes

La façon la plus simple est de changer imdb.py paramètre allow_pickle=True à np.load à la ligne où imdb.py jette l' erreur.


0 commentaires

3
votes

J'ai atterri ici, j'ai essayé vos voies et je n'ai pas pu comprendre.

Je travaillais en fait sur un code prédéfini où

np.load(path, allow_pickle=True)

a été utilisé alors je l'ai remplacé par

pickle.load(path)


0 commentaires

1
votes

Utilisez ceci

 from keras.datasets import imdb

au lieu de cela

 from tensorflow.keras.datasets import imdb


0 commentaires

1
votes

L'erreur peut également se produire si vous essayez d'enregistrer une liste python de tableaux numpy avec np.save et de charger avec np.load. Je le dis uniquement pour le bien des googleurs pour vérifier que ce n'est pas le problème. L'utilisation de allow_pickle=True résolu le problème si une liste était effectivement ce que vous vouliez enregistrer et charger.


0 commentaires