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 lorsque j'ai essayé de le faire à nouveau après quelques jours, il a renvoyé une erreur de valeur: "Les tableaux d'objets ne peuvent pas être chargés lorsque allow_pickle = False" pour la fonction load_data ().
J'ai déjà essayé de résoudre ce problème, en me référant à une réponse existante pour un problème similaire: Comment résoudre '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 l'ajout d'un allow_pickle l'argument n'est pas suffisant.
Mon code:
from keras.datasets import imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
L'erreur:
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
Voici une astuce pour forcer imdb.load_data
pour autoriser le cornichon en remplaçant cette ligne dans votre cahier:
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
par ça:
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
Ce problème est toujours d'actualité sur keras git. J'espère que cela sera résolu dès que possible. D'ici là, essayez de rétrograder votre version numpy vers 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
.
Suite à cela issue sur GitHub, la solution officielle consiste à éditer le fichier imdb.py. Cette correction a bien fonctionné pour moi sans avoir besoin de rétrograder numpy. Recherchez le fichier imdb.py dans tensorflow/python/keras/datasets/imdb.py
(le chemin complet pour moi était: C:\Anaconda\Lib\site-packages\tensorflow\python\keras\datasets\imdb.py
- les autres installations seront différentes) 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 de la modification est la sécurité pour empêcher l'équivalent Python d'une injection SQL dans un fichier mariné. La modification ci-dessus affectera UNIQUEMENT les données imdb et vous conservez donc la sécurité ailleurs (en ne rétrogradant pas engourdi).
J'ai juste utilisé allow_pickle = True comme argument pour np.load () et cela a fonctionné pour moi.
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 dessus pour qu'il ne modifie pas une fonction numpy pour toute la période de session.
Ma suggestion est ci-dessous. Je l'utilise pour télécharger le jeu de données Reuters à partir de keras, ce 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)
Vous pouvez essayer de changer la valeur du drapeau
np.load(training_image_names_array,allow_pickle=True)
Dans mon cas, j'ai travaillé avec:
np.load(path, allow_pickle=True)
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" à partir d'Anaconda powershell
fermer et rouvrir le cahier
Oui, l'installation d'une précédente version 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é mon numpy à 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.
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 cahier 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 :
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, c'est-à-dire v1.17.0 (et éventuellement v1.16.5 +). Dès que TF2 est importé, il lance une énorme liste de FutureWarning, qui ressemble à ceci:
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'.
Cela a également entraîné l'erreur allow_pickle lors de la tentative de chargement de l'ensemble de données imdb à partir des keras
J'ai essayé d'utiliser la solution suivante qui fonctionnait très bien, mais je devais le faire à chaque projet où j'importais TF2 ou tf.keras.
np.load = lambda *a,**k: np_load_old(*a, allow_pickle=True, **k)
La solution la plus simple que j'ai trouvée était d'installer numpy 1.16.1 à l'échelle mondiale ou 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 causé par l'incompatibilité des versions TF2 et Numpy et peut entraîner de nombreux autres bugs ou problèmes cachés.
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
Le moyen le plus simple consiste à modifier imdb.py
réglage allow_pickle=True
à np.load
à la ligne où imdb.py
renvoie une erreur.
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
Tensorflow a un correctif dans la version tf-nightly.
!pip install tf-nightly
La version actuelle est '2.0.0-dev20190511'.
Je ne poste généralement pas sur ces choses mais c'était super ennuyeux. La confusion vient du fait que certains des Keras imdb.py
les fichiers ont déjà été mis à jour:
with np.load(path) as f:
vers la version avec allow_pickle=True
. Assurez-vous de vérifier le fichier imdb.py pour voir si cette modification a déjà été implémentée. S'il a été ajusté, ce qui suit fonctionne bien:
from keras.datasets import imdb
(train_text, train_labels), (test_text, test_labels) = imdb.load_data(num_words=10000)