2016-10-11 3 views
2

this version of the MNIST data setを開く方法を理解したいと思います。例えば、トレーニングセットのラベルファイルtrain-labels-idx1-ubyteは次のように定義されていますYann LeCunのMNIST IDXファイル形式の解析

TRAINING SET LABEL FILE (train-labels-idx1-ubyte): 
[offset] [type]   [value]   [description] 
0000  32 bit integer 0x00000801(2049) magic number (MSB first) 
0004  32 bit integer 60000   number of items 
0008  unsigned byte ??    label 
0009  unsigned byte ??    label 
........ 
xxxx  unsigned byte ??    label 

そして私は動作するようですいくつかのコードをオンラインで見つけましたが、それがどのように動作するか理解していない:

with open('train-labels-idx1-ubyte', 'rb') as f: 
    bytes = f.read(8) 
    magic, size = struct.unpack(">II", bytes) 

print(magic) # 2049 
print(size) # 60000 

私の理解では、ということですstruct.unpackは、2番目の引数を2つの4バイト整数のビッグエンディアンのバイト文字列として解釈します(hereを参照)。私は実際bytesの値を印刷するとき、しかし、私は得る:

b'\x00\x00\x08\x01\x00\x00\xea`' 

最初の4バイトの整数を意味なる:

b'\x00\x00\x08\x01' 

を最初の2つのバイトは0であり、次のデータがあることを示し符号なしバイト。 0x01は、ラベルの1次元ベクトルを示します。 (?4)次の3つで何が起こっているのか、私の理解では、これまで正しいと仮定するとバイト:

...\x00\x00\xea` 

どのようにこれが60,000に翻訳していますか?

+0

質問のタイトルを変更することをお勧めしますか?IMOそれは誤解を招く。問題は、MNISTデータセットを解析する方法ではなく、ファイルからのバイトシーケンスがどのように整数になるかを理解することです。 –

+1

既にデコードされたMNISTデータセットのバージョンは、http://mnist-decoded.000webhostapp.com/で確認できます。 – SomethingSomething

答えて

4

どのように動作するかを理解するには、バイナリ形式に変換する必要があります。

あなたが述べたように、Pythonが正しく権利情報抽出される:文字列のヘッダに

>>> import struct 
>>> with open('train-labels-idx1-ubyte', 'rb') as f: 
...  data = f.read(8) 
... 
>>> print(data) 
b'\x00\x00\x08\x01\x00\x00\xea`' 
>>> print(struct.unpack('>II', data)) 
(2049, 60000) 

を、2つの4バイトの整数です。我々はdataを反復処理する場合我々は彼らのバイナリと10進数表現を見ることができます:

>>> for char in data: 
...  print('{0:08b} - {0:3d} - {1:s}'.format(char, str(bytes([char])))) 
... 
00000000 - 0 - b'\x00' 
00000000 - 0 - b'\x00' 
00001000 - 8 - b'\x08' 
00000001 - 1 - b'\x01' 
00000000 - 0 - b'\x00' 
00000000 - 0 - b'\x00' 
11101010 - 234 - b'\xea' 
01100000 - 96 - b'`' 

簡単な部分は、最初の4つのバイトが最初の整数(マジックナンバー)であり、次の4つのバイトは秒であることを知っていることです整数(項目の数)。

これらの最後の4バイトが与えられると、それらが表す整数値を構成する方法が2つあります。

最初のオプション(MNISTで使用されるオプション)は、ビッグエンディアンまたはハイエンドエンディアンです。どちらが最上位バイトが最初に発見されていることを、意味:

00000000 00000000 11101010 01100000 

あなたはこの進数の10進値を確認した場合、それは60,000、MNISTデータセット内の項目の数です。

また、リトルエンディアンと解釈することもできます。この場合、下位バイトが最初に発見された:その10進表現で、番号1625948160です

01100000 11101010 00000000 00000000 

\x00\x00\xea`の各バイトをバイナリに変換するだけで、リトルエンディアンの場合はバイトの順序を元に戻して、そのバイナリ番号全体の10進数表現を見つけると、それらの整数値があります。

関連する問題