このプログラムを使用して、リンクされたMNISTデータセットをロードしようとしています here in 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)
ただし、以前と同じエラーが発生しました。これを機能させるにはどうすればよいですか?
これはある種の非互換性のようです。 ASCIIと想定される「binstring」オブジェクトをロードしようとしていますが、この場合はバイナリデータです。これが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でそれをunpickleしてから再びickickすると同じ問題が再び発生するだけなので、別の形式で保存する必要があります。
Python3でこのエラーが発生した場合、python 2とpython 3の間の非互換性の問題である可能性があります。私にとっては、load
とlattin1
エンコード:
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で機能しました
互換性の問題がある のように見えます。Unicodeへの移行により、2.xと3.xの間にピクルスがあります。ファイルはpython 2.xで漬けられているように見え、3.xでデコードするのは面倒です。
python 2.xでそれを選択解除し、使用している2つのバージョンでより適切に再生される形式に保存することをお勧めします。
このスニペットを見つけました。これが互換性の問題を明らかにするのに役立つことを願っています。
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)
試してください:
l = list(pickle.load(f, encoding='bytes')) #if you are loading image data or
l = list(pickle.load(f, encoding='latin1')) #if you are loading text data
pickle.load
メソッドのドキュメントから:
オプションのキーワード引数はfix_imports、encoding、errorsであり、Python 2によって生成されたpickleストリームの互換性サポートを制御するために使用されます。
Fix_importsがTrueの場合、pickleは古いPython 2の名前をPython 3で使用されている新しい名前にマッピングしようとします。
エンコードとエラーは、Python 2によってピクルされた8ビット文字列インスタンスをデコードする方法をpickleに指示します。これらはそれぞれ「ASCII」と「strict」にデフォルト設定されています。これらの8ビット文字列インスタンスをバイトオブジェクトとして読み取るために、エンコーディングを「バイト」にすることができます。
ピクルスよりも速くて簡単なヒクルがあります。私はそれをピクルスダンプに保存して読んでみましたが、読んでいる間に多くの問題があり、1時間を無駄にし、チャットボットを作成するために自分のデータに取り組んでいたにもかかわらず解決策が見つかりませんでした。
vec_x
とvec_y
はnumpy配列です:
data=[vec_x,vec_y]
hkl.dump( data, 'new_data_file.hkl' )
次に、それを読んで操作を実行します。
data2 = hkl.load( 'new_data_file.hkl' )