2012-07-03 18 views
83

Estoy intentando cargar el conjunto de datos MNIST vinculado here en Python 3.2 utilizando este programa:salmuera incompatibilidad de matrices numpy entre Python 2 y 3

import pickle 
import gzip 
import numpy 


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

Por desgracia, me da el error:

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) 

Intenté decodificar el archivo escalado en Python 2.7 y volver a codificarlo. Por lo tanto, me encontré con este programa en 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. 

Se corrió sin error, por lo que volvió a ejecutar este programa en 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) 

Sin embargo, me dio el mismo error que antes. ¿Cómo hago que esto funcione?


This is a better approach for loading the MNIST dataset.

+0

hay cortes de compatibilidad entre 2.7 y 3.x. especialmente cadena vs unicode. Y elegir un objeto numpy requiere que ambos sistemas carguen el módulo numpy pero esos módulos son diferentes. Lo siento, no tengo una respuesta, pero esto podría no ser posible y probablemente no sea aconsejable. Si esto es algo grande (gzip), ¿tal vez hdf5 con las piquetas? –

+0

@PhilCooper: Gracias, su comentario (¿publicar esto como una respuesta?) Me indicó la respuesta correcta. Podría haber usado hdf5, pero me pareció complicado de aprender, así que me fui con numpy.guardar/cargar y esto funcionó. –

+0

h5py es muy simple de usar, casi con toda seguridad mucho más fácil que resolver problemas de compatibilidad nebulosos con matrices numpy de decapado. – DaveP

Respuesta

50

Parece una especie de incompatibilidad. Está intentando cargar un objeto "binstring", que se supone que es ASCII, mientras que en este caso se trata de datos binarios. Si esto es un error en el Python 3 unpickler, o un "mal uso" del pickler por numpy, no lo sé.

Aquí es algo así como una solución, pero no saben cómo significativa los datos es en este punto:

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) 

deserialiación en Python 2 y luego repickling que sólo va a crear el mismo problema nuevamente, por lo que debe guardarlo en otro formato.

+1

¡Gracias por mirar esto! –

+119

Puede usar 'pickle.load (file_obj, encoding = 'latin1')' (al menos en Python 3.3). Esto parece funcionar. –

+4

Para aquellos que usan carga numpy y enfrentan el mismo problema: también es posible pasar la codificación: 'np.load ('./ bvlc_alexnet.npy', encoding = 'latin1')' –

5

Parece que there are some compatablility issues en salmuera entre 2.xy 3.x debido al movimiento para Unicode. Su archivo parece estar en escabeche con python 2.x y decodificarlo en 3.x podría ser problemático.

Sugiero desmantelarlo con python 2.x y guardarlo en un formato que se reproduzca de forma más agradable en las dos versiones que está utilizando.

+1

Eso es lo que estaba tratando de hacer. ¿Qué formato recomiendas? –

+5

Creo que el problema podría haber sido la codificación numpy dtype, que podría ser una cadena. En cualquier caso, terminé usando numpy.save/load para cerrar la brecha entre python 2 y 3, y funcionó. –

40

Si usted está recibiendo este error en python3, a continuación, podría ser un problema de incompatibilidad entre Python 2 y Python 3, para mí la solución era load con lattin1 codificación:

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

Exactamente lo que necesitaba. ¡Gracias! – misterkugelblitz

7

Parece ser un problema de incompatibilidad entre Python 2 y Python 3. me trató de cargar el conjunto de datos MNIST con

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

y funcionó para Python 3.5.2

0

Acabo de tropezar con este fragmento. Espero que esto ayude a aclarar el problema de compatibilidad.

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) 
+0

Considere agregar más información de amplificación. ¿Cómo soluciona esto el problema? –

Cuestiones relacionadas