Сочетание несовместимости массивов 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)