İmdb.load_data () işlevi için allow_pickle = False olduğunda nesne dizileri yüklenemiyor nasıl düzeltilir?


113

Google Colab'daki IMDb veri kümesini kullanarak ikili sınıflandırma örneğini uygulamaya çalışıyorum . Bu modeli daha önce uyguladım. Ancak birkaç gün sonra tekrar yapmaya çalıştığımda, bir değer hatası döndürdü: load_data () işlevi için allow_pickle = False olduğunda nesne dizileri yüklenemiyor.

Bunu zaten çözmeyi denedim, benzer bir problem için mevcut bir yanıta atıfta bulunarak: sketch_rnn algoritmasında 'nesne dizileri allow_pickle = False olduğunda yüklenemez' nasıl düzeltilebilir Ancak sadece bir allow_pickle argümanı eklemenin yeterli olmadığı ortaya çıktı.

Kodum:

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

Hata:

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

1
bu hata ne anlama geliyor?
Charlie Parker

3
@CharlieParker Görünüşe göre numpy.load () fonksiyonuna bir parametre eklenmiş. Daha önce öyleydi np.load(path)şimdi bu, np.load(path, boolean)varsayılan olarak, boole (allow_pickle) yanlıştır
Kanad

Teşekkürler! ama bu uyuşukluğun artık benim iznim olmadan benim için bir şeyler topladığı anlamına mı geliyor ?! tuhaf! np.savezDokümanlara baktım ama dekapajla ilgili hiçbir referans yoktu, bu yüzden ilk başta kurtardığım şeylerin Pytorch işi olduğunu ve sadece uyuşuk değil ... tuhaf olduğunu nasıl bildiğini bile bilmiyorum! Eğer neler olup bittiğini bizimle paylaşırsanız :)
Charlie Parker

Aynı problemle karşılaştıktan sonra inancım tamamen bir .npz'ye ne kaydettiğinize bağlı. Yerleşik türleri kaydediyorsanız, asitleme yok. Ancak, eğer bir nesne yazarsanız python / numpy onu seçer (yani serileştirir). Bunun bir güvenlik riski yarattığını hayal ediyorum, bu yüzden numpy'nin sonraki sürümleri bunun varsayılan olmasına izin vermeyi bıraktı ... sadece bir önsezi.
Robert Lugg

Yanıtlar:


123

İşte imdb.load_data, dizüstü bilgisayarınızda bu satırı değiştirerek turşuya izin vermeye zorlamanız gereken bir numara :

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

bundan:

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

Başta "np olarak içe aktar" eklemenizi öneririm. Numpy farklı bir isim altında içe aktarılabilir veya hiç içe aktarılmayabilir ...
Kristóf

Bana çok yardımcı oluyor
staticor

7
Hata almaTypeError: <lambda>() got multiple values for keyword argument 'allow_pickle'
Hayat

1
Anahtar kelime bağımsız değişkeni için birden fazla değer sorunu, stackoverflow.com/a/58586450/5214998
Sajad Norouzi

91

Bu sorun hala keras git üzerinde. Umarım en kısa sürede çözülür. O zamana kadar, numpy sürümünüzü 1.16.2'ye düşürmeyi deneyin. Sorunu çözüyor gibi görünüyor.

!pip install numpy==1.16.1
import numpy as np

Bu numpy sürümünün varsayılan değeri allow_pickleas True.


4
Uyuşmuş versiyonu düşürmek yerine MappaGnosis çözümünü kullanırdım: Benim için dans versiyonuyla uğraşmak son çare!
eric

2
1.16.4'te de sorun var
kensai

Teşekkürler @kensai. Bunun numpy 1.17'de çözülüp çözülmediğini bilen var mı?
nsheff

Numpy 1.18'de hala bu problem mevcuttur. Uyuşmuş 1.16.1'e geçmek zorunda kaldım ve şimdi çözüldü. teşekkür ederim.
BC Smith

55

GitHub'daki bu sorunu takiben , resmi çözüm imdb.py dosyasını düzenlemektir. Bu düzeltme, numpy'yi düşürmeye gerek kalmadan benim için iyi çalıştı. İmdb.py dosyasını şu adreste bulun tensorflow/python/keras/datasets/imdb.py(benim için tam yol: C:\Anaconda\Lib\site-packages\tensorflow\python\keras\datasets\imdb.py- diğer yüklemeler farklı olacak) ve farka göre 85. satırı değiştirin:

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

Değişikliğin nedeni, turşu dosyasında SQL enjeksiyonunun Python eşdeğerini engelleyecek güvenliktir. Yukarıdaki değişiklik YALNIZCA imdb verilerini etkileyecektir ve bu nedenle başka yerde güvenliği koruyabilirsiniz (numpy'yi düşürmeyerek).


1
Dediğim gibi, Colab kullanıyorum, imdb.py dosyasında nasıl değişiklik yapabilirim?
Kanad

IMDB ilk başvurduğunuzda yerel olarak indirildiği için bu bir Colab sorunu değildir. Böylece, bilgisayarınızda bir yerde yerel bir kopya olacaktır (yukarıdaki önerilen yolları deneyin - veya Colab için bir dizin ayarlarsanız, önce orayı deneyin) ve imdb.py dosyasını herhangi bir IDE'de veya hatta bir metin düzenleyicide açın. değişikliği yapın (Jupyter'da çalışırken indirilen imdb.py dosyasını düzenlemek için Notepad ++ kullandım - bu nedenle Colab'a çok benzer bir ortam!).
MappaGnosis

benim için çalışan çözüm> np.load (data_path, encoding = 'latin1', allow_pickle = True)
Jorge Santos Neill

Bu benim kullandığım çözüm, kabul edilen yanıtta olduğu gibi sürümlerle (özellikle uyuşukluk) uğraşmaktan kaçınmaya çalıştığım bir şey. Bu aynı zamanda sorunu açıkça çözdüğü için daha pitoniktir. (Ayrıca Keras'ın en yeni sürümlerinin github'da bu düzeltmeyi içerdiğine de dikkat edin)
eric

35

Np.load () için bir argüman olarak allow_pickle = True kullandım ve benim için çalıştı.


Turşuya izin vermenin diziyi değiştirdiğini gözlemliyorum. Kaydetmeden önce ve yüklemeden sonra .npy dizisi, np.array_equal kullanarak eşitlik iddiasında bulunmaya çalışırken bir istisna oluşturuyor
yasht

18

Benim durumumda çalıştı:

np.load(path, allow_pickle=True)

12

Cheez'den ( https://stackoverflow.com/users/122933/cheez ) gelen cevabın en kolay ve en etkili cevap olduğunu düşünüyorum . Bütün oturum süresi boyunca uyuşmuş bir işlevi değiştirmemesi için biraz daha ayrıntılı olarak açıklardım.

Benim önerim aşağıda. Reuters veri setini keras'tan indirmek için kullanıyorum, bu da aynı tür bir hatayı gösteriyor:

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)

Burada neler olduğunu biraz daha açıklayabilir misin?
Kanad

1
Keras veri kümelerini yükleyemiyordum. İnterneti araştırdım ve de imdb.py dosyasını düzenlemem gerektiğini söyleyen bir çözüm buldum, diğerleri numpy kurulumundaki değişikliklere (burada olduğu gibi) veya Tensorflow'u bir geliştirme sürümüne değiştirmeye işaret etti. Cheez çözümüyle karşılaştım. IMHO bu en kolay ve en etkili olanıydı.
Gustavo Mirapalheta

1
@Kanad - lambda anonim bir işlevdir. Gustavo np.load için bir işlev artırımı oluşturdu, artırılmış sürümü kullandı ve ardından varsayılan değere geri döndü.
EngrStudent


4

Yukarıda listelenen çözümlerden hiçbiri benim için işe yaramadı: anaconda'yı python 3.7.3 ile çalıştırıyorum. Benim için işe yarayan şey

  • Anaconda powershell'den "conda install numpy == 1.16.1" komutunu çalıştırın

  • defteri kapat ve yeniden aç


Teşekkürler, aradığım şey buydu. Bu arada, 1.16.2 allow_pickle=Truevarsayılan değerin olduğu en yeni sürüm gibi görünüyor .
Matěj Račinský

3

kullanarak jupyter dizüstü bilgisayarda

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)

iyi çalıştı, ancak bu yöntemi casus yazılımda kullandığınızda sorun ortaya çıkıyor (her seferinde çekirdeği yeniden başlatmanız gerekiyor, aksi takdirde aşağıdaki gibi bir hata alırsınız:

TypeError: () 'allow_pickle' anahtar kelime bağımsız değişkeni için birden fazla değer aldı

Buradaki çözümü kullanarak bu sorunu çözdüm :


3

Buraya indim, yollarınızı denedim ve anlayamadım.

Aslında önceden verilmiş bir kod üzerinde çalışıyordum.

pickle.load(path)

kullanıldı, bu yüzden onu değiştirdim

np.load(path, allow_pickle=True)

2

Evet, numpy'nin önceki bir sürümünü yüklemek sorunu çözdü.

PyCharm IDE kullananlar için:

IDE (Pycharm), File-> Settings-> Project Interpreter: numpy'imi 1.16.3 olarak buldum, bu yüzden 1.16.1'e geri dönüyorum. + Seçeneğine tıklayın ve aramaya numpy yazın, "sürümü belirtin": 1.16.1'i işaretleyin ve -> paketi yükle'yi seçin.


2

imdb.py yolunu bulun ve np.load'a (yol, ... bayrak ...) bayrağı ekleyin

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

1

Benim için iş

        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

4
Ve çözümünüzün neden işe yaradığını açıklayan bir bağlam. (İncelemeden).
ZF007

1

Bulduğum şey, TensorFlow 2.0'ın (2.0.0-alpha0 kullanıyorum) Numpy'nin en son sürümüyle yani v1.17.0 (ve muhtemelen v1.16.5 +) ile uyumlu olmadığıdır. TF2 içe aktarılır aktarılmaz, aşağıdaki gibi görünen büyük bir FutureWarning listesi atar:

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

Bu ayrıca keras'tan imdb veri kümesi yüklenmeye çalışıldığında allow_pickle hatasıyla sonuçlandı.

Gayet iyi çalışan aşağıdaki çözümü kullanmaya çalıştım, ancak TF2 veya tf.keras'ı içe aktardığım her projede yapmak zorunda kaldım.

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

Bulduğum en kolay çözüm ya global olarak numpy 1.16.1 yüklemek ya da sanal ortamda tensorflow ve numpy'nin uyumlu sürümlerini kullanmaktı.

Bu cevapla amacım, bunun sadece imdb.load_data ile ilgili bir sorun değil, TF2 ve Numpy sürümlerinin uyumsuzluğundan kaynaklanan daha büyük bir problem olduğunu ve diğer birçok gizli hata veya sorunla sonuçlanabileceğini belirtmektir.


0

Tensorflow'un tf-nightly versiyonunda bir düzeltmesi var.

!pip install tf-nightly

Mevcut sürüm "2.0.0-dev20190511" dir.


0

@Cheez cevabı bir ara işi yapmaz ve yinelemeli tekrar tekrar işlevini çağırın. Bu sorunu çözmek için işlevi derinlemesine kopyalamalısınız. Bunu işlevi kullanarak yapabilirsiniz partial, bu nedenle son kod:

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

Genelde bu tür şeyleri yayınlamam ama bu çok can sıkıcıydı. Karışıklık, bazı Keras imdb.pydosyalarının zaten güncellenmiş olmasından kaynaklanıyor :

with np.load(path) as f:

ile sürüme allow_pickle=True. Bu değişikliğin zaten uygulanıp uygulanmadığını görmek için imdb.py dosyasını kontrol ettiğinizden emin olun. Ayarlanmışsa, aşağıdakiler iyi çalışır:

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

0

En kolay yolu değiştirmektir imdb.pyayarı allow_pickle=Trueiçin np.loadsatırında imdb.pyhata atar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.