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)
20 Réponses :
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
.
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.
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.
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).
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)
Tensorflow a un correctif dans la version tf-nightly.
!pip install tf-nightly
La version actuelle est «2.0.0-dev20190511».
Je viens d'utiliser allow_pickle = True comme argument de np.load () et cela a fonctionné pour moi.
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
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)
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
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)
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.
Vous pouvez essayer de changer la valeur de l'indicateur
np.load(training_image_names_array,allow_pickle=True)
Génial. Ça marche. Cela devrait être la réponse acceptée.
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:
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 :
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
Et un contexte expliquant pourquoi votre solution fonctionne. (De l'avis).
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.
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
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.
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
Dans mon cas, j'ai travaillé avec:
np.load(path, allow_pickle=True)
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:
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.
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)
Utilisez ceci
from keras.datasets import imdb
au lieu de cela
from tensorflow.keras.datasets import imdb
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.
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'estnp.load(path, boolean)
Par défaut, le booléen (allow_pickle) est fauxMerci! 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.