pickle Python 2和3之间的numpy数组的不兼容性

我正在尝试使用这个程序加载Python 3.2中链接的MNIST数据集:

import pickle import gzip import numpy with gzip.open('mnist.pkl.gz', 'rb') as f: l = list(pickle.load(f)) print(l) 

不幸的是,它给了我错误:

 Traceback (most recent call last): File "mnist.py", line 7, in <module> train_set, valid_set, test_set = pickle.load(f) UnicodeDecodeError: 'ascii' codec can't decode byte 0x90 in position 614: ordinal not in range(128) 

然后我尝试在Python 2.7中解码pickle文件,并对其进行重新编码。 所以,我用Python 2.7运行这个程序:

 import pickle import gzip import numpy with gzip.open('mnist.pkl.gz', 'rb') as f: train_set, valid_set, test_set = pickle.load(f) # Printing out the three objects reveals that they are # all pairs containing numpy arrays. with gzip.open('mnistx.pkl.gz', 'wb') as g: pickle.dump( (train_set, valid_set, test_set), g, protocol=2) # I also tried protocol 0. 

它运行没有错误,所以我在Python 3.2中重新运行这个程序:

 import pickle import gzip import numpy # note the filename change with gzip.open('mnistx.pkl.gz', 'rb') as f: l = list(pickle.load(f)) print(l) 

但是,它给了我和以前一样的错误。 我如何得到这个工作?


这是加载MNIST数据集的更好方法。

这似乎是某种不相容性。 它试图加载一个“binstring”对象,它被假定为ASCII,而在这种情况下,它是二进制数据。 如果这是Python 3 unpickler中的错误,或者是numpy对pickler的“误用”,我不知道。

这是一个解决方法,但是我不知道这个数据有多么有意义:

 import pickle import gzip import numpy with open('mnist.pkl', 'rb') as f: u = pickle._Unpickler(f) u.encoding = 'latin1' p = u.load() print(p) 

在Python 2中取消select,然后重新打开它只会再次创build相同的问题,所以你需要保存在另一种格式。

如果你在python3中得到这个错误,那么它可能是python 2和python 3之间的不兼容问题,对于我来说,解决方法是使用lattin1编码load

 pickle.load(file, encoding='latin1') 

这似乎是Python 2和Python 3之间的不兼容问题。我尝试加载MNIST数据集

  train_set, valid_set, test_set = pickle.load(file, encoding='iso-8859-1') 

它适用于Python 3.5.2

看起来在2.x和3.x之间有一些兼容性问题 ,因为移动到unicode。 你的文件似乎用python 2.x腌制,并在3.x解码可能是麻烦的。

我build议使用python 2.x来取消它,并保存到在你使用的两个版本中播放更好的格式。

我只是偶然发现了这个片段。 希望这有助于澄清兼容性问题。

 import sys with gzip.open('mnist.pkl.gz', 'rb') as f: if sys.version_info.major > 2: train_set, valid_set, test_set = pickle.load(f, encoding='latin1') else: train_set, valid_set, test_set = pickle.load(f)