Сочетание несовместимости массивов numpy между Python 2 и 3
Я пытаюсь загрузить набор данных MNIST, связанный здесь в Python 3.2 с помощью этой программы:
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 и перекодировать его. Итак, я запускал эту программу в 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.
Ответы
Ответ 1
Это похоже на несовместимость. Он пытается загрузить объект "binstring", который предполагается ASCII, тогда как в этом случае это двоичные данные. Если это ошибка в Pickon 3 unpickler или "неправильное использование" pickler numpy, я не знаю.
Вот что-то обходное решение, но я не знаю, насколько значимы данные на данный момент:
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, а затем перепишивая, он снова создаст ту же проблему, поэтому вам нужно сохранить его в другом формате.
Ответ 2
Если вы получаете эту ошибку в python3, то это может быть проблема несовместимости между python 2 и python 3, для меня решение было load
с lattin1
кодировкой:
pickle.load(file, encoding='latin1')
Ответ 3
Кажется, проблема несовместимости между Python 2 и Python 3. Я попробовал загрузить набор данных MNIST с помощью
train_set, valid_set, test_set = pickle.load(file, encoding='iso-8859-1')
и он работал для Python 3.5.2
Ответ 4
Похоже, есть некоторые проблемы с compatablility в pickle между 2.x и 3.x из-за перехода в unicode. Ваш файл, кажется, маринован с python 2.x и декодирует его в 3.x может быть неприятным.
Я бы предложил раскрыть его с помощью python 2.x и сохранить в формате, который будет более хорошо воспроизводиться в двух версиях, которые вы используете.
Ответ 5
Я просто наткнулся на этот фрагмент. Надеемся, что это поможет прояснить проблему совместимости.
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)