Làm cách nào để sửa lỗi 'Không thể tải mảng đối tượng khi allow_pickle = False' cho hàm imdb.load_data ()?


113

Tôi đang cố gắng triển khai ví dụ phân loại nhị phân bằng cách sử dụng tập dữ liệu IMDb trong Google Colab . Tôi đã thực hiện mô hình này trước đây. Nhưng khi tôi cố gắng thực hiện lại sau một vài ngày, nó trả về lỗi giá trị: 'Không thể tải mảng đối tượng khi allow_pickle = False' cho hàm load_data ().

Tôi đã thử giải quyết vấn đề này, đề cập đến câu trả lời hiện có cho một vấn đề tương tự: Cách sửa lỗi 'Mảng đối tượng không thể tải khi allow_pickle = False' trong thuật toán sketch_rnn. Nhưng hóa ra chỉ thêm đối số allow_pickle là không đủ.

Mã của tôi:

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

Lỗi:

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
Lỗi này nghĩa là gì?
Charlie Parker

3
@CharlieParker Rõ ràng đã có thêm một tham số trong hàm numpy.load (). Trước đây nó là np.load(path), bây giờ nó np.load(path, boolean)Theo mặc định, boolean (allow_pickle) là sai
Kanad

cảm ơn! nhưng điều đó có nghĩa là bây giờ numpy lấy đồ cho tôi mà không có sự cho phép của tôi khi tiết kiệm ?! kỳ dị! Tôi đã xem các np.saveztài liệu nhưng không có tài liệu tham khảo nào về việc tẩy rửa nên tôi không biết làm thế nào mà ngay từ đầu nó đã biết rằng những thứ tôi đang tiết kiệm là đồ của Pytorch và không chỉ numpy ... kỳ lạ! Nếu bạn biết whats going on chia sẻ với chúng tôi :)
Charlie Parker

Niềm tin của tôi sau khi gặp phải vấn đề tương tự là nó hoàn toàn phụ thuộc vào những gì bạn đang lưu vào .npz. Nếu bạn đang tiết kiệm các loại tích hợp, thì không có hiện tượng kén chọn. Tuy nhiên, nếu bạn viết một đối tượng thì python / numpy sẽ làm hỏng nó (tức là tuần tự hóa nó). Điều này tôi tưởng tượng sẽ mở ra một nguy cơ bảo mật, vì vậy các phiên bản sau của numpy đã ngừng cho phép nó mặc định ... mặc dù chỉ là linh cảm.
Robert Lugg

Câu trả lời:


123

Đây là một mẹo để buộc imdb.load_datacho phép dưa chua, trong sổ tay của bạn, thay thế dòng này:

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

bởi cái này:

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

Tôi đề nghị thêm "import numpy as np" vào đầu. NumPy thể được nhập khẩu dưới một cái tên khác nhau, hoặc không được nhập vào tất cả các ...
Kristóf

Nó giúp tôi rất nhiều
staticor

7
Bắt lỗiTypeError: <lambda>() got multiple values for keyword argument 'allow_pickle'
Hayat

1
Các vấn đề của nhiều giá trị cho tham số từ khóa đã được đề cập đến trong stackoverflow.com/a/58586450/5214998
Sajad Norouzi

91

Vấn đề này vẫn còn trên keras git. Tôi hy vọng nó sẽ được giải quyết càng sớm càng tốt. Cho đến lúc đó, hãy thử hạ cấp phiên bản numpy của bạn xuống 1.16.2. Nó dường như để giải quyết vấn đề.

!pip install numpy==1.16.1
import numpy as np

Phiên bản numpy này có giá trị mặc định allow_pickleTrue.


4
Tôi sẽ sử dụng giải pháp từ MappaGnosis chứ không phải hạ cấp phiên bản numpy: đối với tôi, sử dụng phiên bản dance là phương sách cuối cùng!
eric

2
1.16.4 cũng có vấn đề
kensai 13:19

Cảm ơn @kensai. Có ai biết nếu điều này đã được giải quyết trong numpy 1.17?
nsheff

Trong numpy 1.18 vẫn còn vấn đề này. Tôi đã phải chuyển sang numpy 1.16.1 và nó đã được giải quyết ngay bây giờ. cảm ơn bạn.
BC Smith

55

Sau này vấn đề trên GitHub, giải pháp chính thức là để chỉnh sửa các tập tin imdb.py. Bản sửa lỗi này hoạt động tốt đối với tôi mà không cần phải hạ cấp numpy. Tìm tệp imdb.py tại tensorflow/python/keras/datasets/imdb.py(đường dẫn đầy đủ đối với tôi là: C:\Anaconda\Lib\site-packages\tensorflow\python\keras\datasets\imdb.py- các cài đặt khác sẽ khác) và thay đổi dòng 85 theo sự khác biệt:

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

Lý do cho sự thay đổi là bảo mật để ngăn chặn Python tương đương với việc chèn SQL trong một tệp được ngâm. Thay đổi ở trên sẽ CHỈ ảnh hưởng đến dữ liệu imdb và do đó bạn vẫn giữ được tính bảo mật ở nơi khác (bằng cách không hạ cấp numpy).


1
Như tôi đã nói, tôi đang sử dụng Colab, làm cách nào để thực hiện các thay đổi trong tệp imdb.py?
Kanad

Đây không phải là vấn đề Colab vì IMDB được tải xuống cục bộ trong lần đầu tiên bạn tham khảo. Vì vậy, sẽ có một bản sao cục bộ ở đâu đó trên máy tính của bạn (hãy thử các đường dẫn được đề xuất ở trên - hoặc, nếu bạn đặt thư mục cho Colab, hãy thử ở đó trước) và chỉ cần mở tệp imdb.py trong bất kỳ IDE nào hoặc thậm chí là một trình soạn thảo văn bản để thực hiện thay đổi (Tôi đã sử dụng Notepad ++ để chỉnh sửa tệp imdb.py được tải xuống khi làm việc trong Jupyter - vì vậy một môi trường rất giống với Colab!).
MappaGnosis

giải pháp phù hợp với tôi là> np.load (data_path, encoding = 'latin1', allow_pickle = True)
Jorge Santos Neill

Đây là giải pháp tôi sử dụng, vì việc lộn xộn với các phiên bản (đặc biệt là của numpy), như trong câu trả lời được chấp nhận, là điều tôi cố gắng tránh. Điều này cũng khó hiểu hơn vì nó chỉ khắc phục sự cố một cách rõ ràng. (Cũng lưu ý rằng các phiên bản mới nhất của Keras, tại github, thực sự kết hợp bản sửa lỗi này)
eric

35

Tôi vừa sử dụng allow_pickle = True làm đối số cho np.load () và nó phù hợp với tôi.


Tôi đang quan sát rằng việc cho phép pickle sẽ thay đổi mảng. Mảng .npy trước khi lưu và sau khi tải có ngoại lệ khi cố gắng khẳng định sự bình đẳng bằng cách sử dụng np.array_equal
yasht 11/11/19

18

Trong trường hợp của tôi đã làm việc với:

np.load(path, allow_pickle=True)

12

Tôi nghĩ câu trả lời từ cheez ( https://stackoverflow.com/users/122933/cheez ) là câu trả lời dễ nhất và hiệu quả nhất. Tôi sẽ giải thích kỹ lưỡng một chút về nó để nó không sửa đổi một hàm phức tạp trong toàn bộ thời gian của phiên.

Gợi ý của tôi là dưới đây. Tôi đang sử dụng nó để tải xuống bộ dữ liệu bộ định tuyến từ keras đang hiển thị cùng một loại lỗi:

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)

Bạn có thể giải thích thêm về những gì đang xảy ra ở đây?
Kanad

1
Tôi không thể tải tập dữ liệu Keras. Tôi đã tìm kiếm trên internet và tìm thấy một giải pháp nói rằng tôi nên chỉnh sửa tệp de imdb.py, những người khác chỉ ra những thay đổi trong cài đặt numpy (như ở đây) hoặc thay đổi Tensorflow thành phiên bản phát triển. Tôi đã xem qua giải pháp cheez. IMHO đó là cách dễ nhất và hiệu quả nhất.
Gustavo Mirapalheta

1
@Kanad - lambda là một hàm ẩn danh. Gustavo đã tạo một hàm tăng cường cho np.load, sử dụng phiên bản tăng cường, sau đó đặt trở lại giá trị mặc định.
EngrStudent

9

Bạn có thể thử thay đổi giá trị của cờ

np.load(training_image_names_array,allow_pickle=True)

Tuyệt quá. Nó đang hoạt động. Đây phải là câu trả lời được chấp nhận.
Biranchi

4

không có giải pháp nào được liệt kê ở trên phù hợp với tôi: tôi chạy anaconda với python 3.7.3. Điều làm việc cho tôi là

  • chạy "conda install numpy == 1.16.1" từ Anaconda powershell

  • đóng và mở lại sổ tay


Cảm ơn, đó là những gì tôi đã tìm kiếm. Nhân tiện, có vẻ như 1.16.2 là phiên bản mới nhất với allow_pickle=Truegiá trị mặc định.
Matěj Račinský

3

trên máy tính xách tay jupyter bằng cách sử dụng

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)

hoạt động tốt, nhưng sự cố xuất hiện khi bạn sử dụng phương pháp này trong spyder (bạn phải khởi động lại hạt nhân mỗi lần hoặc bạn sẽ gặp lỗi như:

TypeError: () có nhiều giá trị cho đối số từ khóa 'allow_pickle'

Tôi đã giải quyết vấn đề này bằng giải pháp ở đây :


3

Tôi đã hạ cánh ở đây, đã thử cách của bạn và không thể tìm ra.

Tôi thực sự đang làm việc trên một mã pregiven, nơi

pickle.load(path)

đã được sử dụng nên tôi đã thay thế nó bằng

np.load(path, allow_pickle=True)

2

Có, cài đặt phiên bản numpy trước đó đã giải quyết được vấn đề.

Đối với những người sử dụng PyCharm IDE:

trong IDE (Pycharm) của tôi, Tệp-> Cài đặt-> Trình thông dịch dự án: Tôi thấy rằng numpy của mình là 1.16.3, vì vậy tôi hoàn nguyên về 1.16.1. Nhấp vào + và gõ numpy trong tìm kiếm, đánh dấu vào "chỉ định phiên bản": 1.16.1 và chọn -> cài đặt gói.


2

tìm đường dẫn đến imdb.py sau đó chỉ cần thêm cờ vào np.load (đường dẫn, ... cờ ...)

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

1

Nó làm việc cho tô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
Và một số ngữ cảnh giải thích tại sao giải pháp của bạn hoạt động. (Từ Đánh giá).
ZF007

1

Những gì tôi nhận thấy là TensorFlow 2.0 (tôi đang sử dụng 2.0.0-alpha0) không tương thích với phiên bản mới nhất của Numpy tức là v1.17.0 (và có thể là v1.16.5 +). Ngay sau khi TF2 được nhập, nó sẽ ném ra một danh sách lớn các FutureWarning, trông giống như sau:

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

Điều này cũng dẫn đến lỗi allow_pickle khi cố gắng tải tập dữ liệu imdb từ keras

Tôi đã cố gắng sử dụng giải pháp sau đây hoạt động tốt, nhưng tôi phải thực hiện nó cho từng dự án mà tôi đang nhập TF2 hoặc tf.keras.

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

Giải pháp dễ nhất mà tôi tìm thấy là cài đặt numpy 1.16.1 trên toàn cầu hoặc sử dụng các phiên bản tương thích của tensorflow và numpy trong môi trường ảo.

Mục tiêu của tôi với câu trả lời này là chỉ ra rằng nó không chỉ là vấn đề với imdb.load_data mà còn là một vấn đề lớn hơn do sự không tương thích của các phiên bản TF2 và Numpy và có thể dẫn đến nhiều lỗi hoặc sự cố ẩn khác.


0

Tensorflow có một bản sửa lỗi trong phiên bản tf-nightly.

!pip install tf-nightly

Phiên bản hiện tại là '2.0.0-dev20190511'.


0

Câu trả lời của @cheez đôi khi không hoạt động và gọi hàm lặp đi lặp lại một cách đệ quy. Để giải quyết vấn đề này, bạn nên sao chép hàm sâu. Bạn có thể làm điều này bằng cách sử dụng hàm partial, vì vậy mã cuối cùng là:

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

Tôi không thường đăng những thứ này nhưng điều này thật khó chịu. Sự nhầm lẫn đến từ thực tế là một số imdb.pytệp Keras đã được cập nhật:

with np.load(path) as f:

sang phiên bản với allow_pickle=True. Đảm bảo kiểm tra tệp imdb.py để xem liệu thay đổi này đã được triển khai chưa. Nếu nó đã được điều chỉnh, những điều sau đây hoạt động tốt:

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

0

Cách dễ nhất là thay đổi imdb.pycài đặt allow_pickle=Truethành np.loadtại dòng có imdb.pylỗi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.