Bagaimana cara memperbaiki 'Larik objek tidak dapat dimuat ketika allow_pickle = False' untuk fungsi imdb.load_data ()?

113

Saya mencoba menerapkan contoh klasifikasi biner menggunakan kumpulan data IMDb di Google Colab . Saya telah menerapkan model ini sebelumnya. Tetapi ketika saya mencoba melakukannya lagi setelah beberapa hari, itu mengembalikan kesalahan nilai: 'Larik objek tidak dapat dimuat ketika allow_pickle = False' untuk fungsi load_data ().

Saya sudah mencoba memecahkan ini, mengacu pada jawaban yang ada untuk masalah serupa: Bagaimana memperbaiki 'Larik objek tidak dapat dimuat ketika allow_pickle = False' dalam algoritma sketch_rnn Tetapi ternyata hanya menambahkan argumen allow_pickle saja tidak cukup.

Kode saya:

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

Kesalahannya:

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
Kanad
sumber
1
apa kesalahan ini artinya?
Charlie Parker
3
@CharlieParker Rupanya telah terjadi penambahan parameter pada fungsi numpy.load (). Sebelumnya np.load(path), sekarang secara np.load(path, boolean)default, boolean (allow_pickle) salah
Kanad
Terima kasih! tetapi apakah itu berarti bahwa numpy sekarang acar untuk saya tanpa izin saya saat menyimpan ?! aneh! Saya melihat np.savezdokumen tetapi tidak ada referensi untuk pengawetan jadi saya tidak tahu bagaimana bahkan tahu di tempat pertama bahwa hal-hal yang saya simpan adalah barang Pytorch dan tidak hanya numpy ... aneh! Jika Anda tahu apa yang terjadi, bagikan dengan kami :)
Charlie Parker
Keyakinan saya setelah mengalami masalah yang sama adalah bahwa itu sepenuhnya bergantung pada apa yang Anda simpan ke .npz. Jika Anda menyimpan tipe bawaan, maka tidak ada pengawetan. Namun, jika Anda menulis sebuah objek python / numpy akan membuat acar itu (yaitu membuat serialnya). Ini yang saya bayangkan membuka risiko keamanan, jadi versi numpy yang lebih baru berhenti mengizinkannya menjadi default ... meskipun hanya sebuah firasat.
Robert Lugg

Jawaban:

123

Berikut adalah trik untuk memaksa imdb.load_dataagar acar masuk, di buku catatan Anda, mengganti baris ini:

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

dengan ini:

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
cheez
sumber
Saya sarankan untuk menambahkan "import numpy as np" di awal. Numpy dapat diimpor dengan nama yang berbeda, atau tidak diimpor sama sekali ...
Kristóf
Ini sangat membantu saya
statis atau
7
Mendapatkan kesalahanTypeError: <lambda>() got multiple values for keyword argument 'allow_pickle'
Hayat
1
Masalah beberapa nilai untuk argumen kata kunci telah diatasi di stackoverflow.com/a/58586450/5214998
Sajad Norouzi
91

Masalah ini masih menjadi masalah keras git. Saya berharap ini diselesaikan secepat mungkin. Sementara itu, coba turunkan versi numpy Anda ke 1.16.2. Tampaknya menyelesaikan masalah.

!pip install numpy==1.16.1
import numpy as np

Versi numpy ini memiliki nilai default allow_picklesebagai True.

Tirth Patel
sumber
4
Saya akan menggunakan solusi dari MappaGnosis daripada menurunkan versi numpy: bagi saya bermain-main dengan versi dance adalah pilihan terakhir!
eric
2
1.16.4 juga memiliki masalah
kensai
Terima kasih @kensai. Adakah yang tahu jika ini diselesaikan di numpy 1,17?
nsheff
Di numpy 1,18 masih masalah ini ada. Saya harus beralih ke numpy 1.16.1 dan itu diselesaikan sekarang. Terima kasih.
BC Smith
55

Mengikuti masalah ini di GitHub, solusi resminya adalah mengedit file imdb.py. Perbaikan ini bekerja dengan baik untuk saya tanpa perlu menurunkan versi numpy. Temukan file imdb.py di tensorflow/python/keras/datasets/imdb.py(jalur lengkap untuk saya adalah: C:\Anaconda\Lib\site-packages\tensorflow\python\keras\datasets\imdb.py- pemasangan lain akan berbeda) dan ubah baris 85 sesuai perbedaannya:

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

Alasan perubahan tersebut adalah keamanan untuk mencegah Python yang setara dengan injeksi SQL dalam file acar. Perubahan di atas HANYA akan mempengaruhi data imdb dan oleh karena itu Anda mempertahankan keamanan di tempat lain (dengan tidak menurunkan numpy).

MappaGnosis
sumber
1
Seperti yang saya katakan, saya menggunakan Colab, bagaimana cara membuat perubahan pada file imdb.py?
Kanad
Ini bukan masalah Colab karena IMDB diunduh secara lokal saat pertama kali Anda mereferensikannya. Jadi, akan ada salinan lokal di suatu tempat di komputer Anda (coba jalur yang disarankan di atas - atau, jika Anda menyetel direktori untuk Colab, coba di sana terlebih dahulu) dan cukup buka file imdb.py di IDE mana pun atau bahkan editor teks ke buat perubahan (saya menggunakan Notepad ++ untuk mengedit file imdb.py yang diunduh saat bekerja di Jupyter - lingkungan yang sangat mirip dengan Colab!).
MappaGnosis
solusi yang berhasil untuk saya adalah> np.load (data_path, encoding = 'latin1', allow_pickle = True)
Jorge Santos Neill
Ini adalah solusi yang saya gunakan, karena mengotak-atik versi (terutama numpy), seperti dalam jawaban yang diterima, adalah sesuatu yang saya coba hindari. Ini juga lebih pythonic karena secara eksplisit hanya memperbaiki masalah. (Perhatikan juga versi terbaru Keras, di github, sebenarnya menyertakan perbaikan ini)
eric
35

Saya baru saja menggunakan allow_pickle = True sebagai argumen untuk np.load () dan itu berhasil untuk saya.

Madhuparna Bhowmik
sumber
Saya mengamati bahwa membiarkan acar mengubah array. Array .npy sebelum menyimpan dan setelah memuat memunculkan pengecualian saat mencoba menegaskan kesetaraan menggunakan np.array_equal
yasht
18

Dalam kasus saya bekerja dengan:

np.load(path, allow_pickle=True)
travs15
sumber
12

Saya pikir jawaban dari cheez ( https://stackoverflow.com/users/122933/cheez ) adalah yang termudah dan paling efektif. Saya akan menguraikan sedikit di atasnya sehingga tidak akan mengubah fungsi numpy untuk seluruh periode sesi.

Saran saya ada di bawah. Saya menggunakannya untuk mengunduh set data komputer dari keras yang menunjukkan jenis kesalahan yang sama:

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)
Gustavo Mirapalheta
sumber
Bisakah Anda menjelaskan lebih lanjut tentang apa yang terjadi di sini?
Kanad
1
Saya tidak dapat memuat set data Keras. Saya mencari di internet dan menemukan solusi yang mengatakan bahwa saya harus mengedit file de imdb.py, yang lain menunjuk ke perubahan dalam instalasi numpy (seperti di sini) atau mengubah Tensorflow ke versi pengembangan. Saya menemukan solusi cheez. IMHO itu yang paling mudah dan efektif.
Gustavo Mirapalheta
1
@Kanad - lambda adalah fungsi anonim. Gustavo membuat sebuah fungsi-augment ke np.load, menggunakan versi augmented, lalu mengatur kembali ke nilai default.
EngrStudent
9

Anda dapat mencoba mengubah nilai bendera

np.load(training_image_names_array,allow_pickle=True)
Brayan Armando Yaquian Gonzale
sumber
Bagus. Bekerja. Ini harus menjadi jawaban yang diterima.
Biranchi
4

tidak ada solusi yang tercantum di atas yang berhasil untuk saya: saya menjalankan anaconda dengan python 3.7.3. Apa yang berhasil bagi saya adalah

  • jalankan "conda install numpy == 1.16.1" dari Anaconda PowerShell

  • tutup dan buka kembali buku catatan

farid khafizov
sumber
Terima kasih, itulah yang saya cari. Ngomong-ngomong, sepertinya 1.16.2 adalah versi terbaru dengan allow_pickle=Truenilai default.
Matěj Račinský
3

pada notebook jupyter menggunakan

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)

berfungsi dengan baik, tetapi masalah muncul ketika Anda menggunakan metode ini di spyder (Anda harus me-restart kernel setiap saat atau Anda akan mendapatkan kesalahan seperti:

TypeError: () mendapat beberapa nilai untuk argumen kata kunci 'allow_pickle'

Saya memecahkan masalah ini menggunakan solusi di sini :

Yasser Albarbay
sumber
3

Saya mendarat di sini, mencoba cara Anda dan tidak tahu.

Saya sebenarnya sedang mengerjakan kode yang telah diberikan sebelumnya

pickle.load(path)

digunakan jadi saya menggantinya dengan

np.load(path, allow_pickle=True)
Shristi Gupta
sumber
2

Ya, menginstal versi sebelumnya dari numpy menyelesaikan masalah.

Bagi mereka yang menggunakan PyCharm IDE:

di IDE saya (Pycharm), File-> Settings-> Project Interpreter: Saya menemukan numpy saya menjadi 1.16.3, jadi saya kembali ke 1.16.1. Klik + dan ketik numpy di pencarian, centang "tentukan versi": 1.16.1 dan pilih -> instal paket.

Wissam
sumber
2

temukan jalur ke imdb.py lalu tambahkan saja bendera ke np.load (jalur, ... bendera ...)

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

Ini berhasil untuk saya

        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
ReimuChan
sumber
4
Dan beberapa konteks yang menjelaskan mengapa solusi Anda berhasil. (Dari Ulasan).
ZF007
1

Apa yang saya temukan adalah bahwa TensorFlow 2.0 (saya menggunakan 2.0.0-alpha0) tidak kompatibel dengan versi terbaru Numpy yaitu v1.17.0 (dan mungkin v1.16.5 +). Segera setelah TF2 diimpor, itu melontarkan daftar besar FutureWarning, yang terlihat seperti ini:

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

Ini juga mengakibatkan error allow_pickle saat mencoba memuat set data imdb dari keras

Saya mencoba menggunakan solusi berikut yang berfungsi dengan baik, tetapi saya harus melakukannya setiap proyek di mana saya mengimpor TF2 atau tf.keras.

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

Solusi termudah yang saya temukan adalah menginstal numpy 1.16.1 secara global, atau menggunakan versi tensorflow dan numpy yang kompatibel di lingkungan virtual.

Tujuan saya dengan jawaban ini adalah untuk menunjukkan bahwa ini bukan hanya masalah dengan imdb.load_data, tetapi masalah yang lebih besar disebabkan oleh ketidakcocokan versi TF2 dan Numpy dan dapat mengakibatkan banyak bug atau masalah tersembunyi lainnya.

sidk
sumber
0

Tensorflow memiliki perbaikan dalam versi tf-nightly.

!pip install tf-nightly

Versi saat ini adalah '2.0.0-dev20190511'.

Joocheol Kim
sumber
0

The jawaban @cheez kadang-kadang tidak bekerja dan rekursif memanggil fungsi lagi dan lagi. Untuk mengatasi masalah ini Anda harus menyalin fungsinya secara mendalam. Anda dapat melakukan ini dengan menggunakan fungsi tersebut partial, jadi kode akhirnya adalah:

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
Sajad Norouzi
sumber
0

Saya biasanya tidak memposting ke hal-hal ini tetapi ini sangat mengganggu. Kebingungan berasal dari fakta bahwa beberapa imdb.pyfile Keras telah diperbarui:

with np.load(path) as f:

ke versi dengan allow_pickle=True. Pastikan periksa file imdb.py untuk melihat apakah perubahan ini sudah diterapkan. Jika sudah disesuaikan, berikut ini berfungsi dengan baik:

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

Cara termudah adalah dengan mengubah imdb.pypengaturan allow_pickle=Trueke np.loadbaris di mana imdb.pykesalahan melempar.

Nasif Imtiaz Ohi
sumber