2016-10-11 5 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은 두 번째 인수를 두 개의 4 바이트 정수로 구성된 빅 엔디안 바이트 문자열로 해석합니다 (here 참조). 실제로 bytes의 값을 인쇄 할 때,하지만, 내가 얻을 : 처음 두 바이트는 다음 0입니다

b'\x00\x00\x08\x01' 

데이터가 나타냅니다

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

첫 번째 4 바이트 정수는 의미가 있습니다 부호없는 바이트. 0x01은 레이블의 1 차원 벡터를 나타냅니다. (? 네) 다음의 세 가지로 무슨 일이 일어나고 있는지, 나의 이해는 지금까지 올바른 가정 바이트 :

...\x00\x00\xea` 

방법이 60,000에 번역 하는가?

+0

질문 제목을 변경 하시겠습니까?IMO 오해의 소지가 있습니다. 문제는 MNIST 데이터 세트를 파싱하는 방법이 아니라 파일에서 바이트 시퀀스가 ​​정수가되는 방식을 이해하는 것입니다. –

+1

MNIST 데이터 세트의 이미 디코딩 된 버전은 http://mnist-decoded.000webhostapp.com/에서 찾을 수 있습니다. – SomethingSomething

답변

4

작동 원리를 이해하려면 이진 표현으로 변환해야합니다. 당신이 언급 한 바와 같이

, 파이썬은 제대로 올바른 정보 추출됩니다 : 문자열의 헤더에서

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

을, 두 개의 4 바이트 정수가 있습니다.

이 쉬운 부분은
>>> 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 바이트는 두 번째입니다 : 우리가 data을 반복하면 우리는 그들의 바이너리와 소수점 표현을 볼 수 있습니다 정수 (항목 수).

그러면 마지막 4 바이트가 주어지면 이들이 나타내는 정수 값을 구성 할 수있는 두 가지 방법이 있습니다.

첫 번째 옵션 (MNIST에서 사용되는 옵션)은 크거나 높은 엔디안입니다. 어떤이 가장 중요한 바이트가 먼저 발견되는 것을 의미한다 :

00000000 00000000 11101010 01100000 

이 진수의 소수점 값을 확인하면, 60,000의 MNIST 데이터 세트에있는 항목의 수입니다.

또한 리틀 엔디안으로 해석 할 수 있습니다. 이 경우, 덜 중요한 바이트 먼저 찾을 수 있습니다 진수 표현, 숫자 1625948160입니다

01100000 11101010 00000000 00000000 

.

\x00\x00\xea`의 각 바이트를 이진수로 간단히 변환하고 전체 이진수의 10 진수 표현 (리틀 엔디안 인 경우 바이트 순서를 되 돌리면)이 나타내는 정수 값을가집니다.