MATLAB이 한 번에 4 개의 정수로 읽는 방법은 little-endian
형식이며 MNIST 데이터베이스 파일의 파일 형식은 big-endian
입니다. 따라서 파일의 처음 4 바이트를 읽을 때 바이트는 0x00, 0x00, 0x08, 0x03
으로 예상됩니다. 그러나 MATLAB은 이것을 0x03, 0x08, 0x00, 0x00
으로 읽을 것입니다. 이것을 정수로 변환 할 때 우리는 실제로 우리가 원하는 것이 아닌 50855936
을 얻을 것입니다.
이 문제를 해결하기위한 해킹은 한 번에 여러 바이트를 읽을 필요가있을 때 데이터 유형을 uint8
으로 지정해야합니다. 이렇게하면 각 바이트가 배열의 개별 요소로 저장됩니다. 그런 다음 각 바이트를 지정된 양만큼 비트 이동 한 다음 결과를 합산하여 필요한 수를 계산할 수 있습니다. 데이터 파일의 처음 몇 바이트에 대해이 작업을 수행해야합니다.
또는 의견에 명시된대로 swapbytes
메서드를 사용할 수 있습니다. 그러면 정확히 똑같은 결과가 나타납니다. uint32
유형의 1 바이트를 읽은 다음 바이트의 순서를 스왑하여 바이트가 big-endian
형식이되도록합니다. uint32
으로 데이터를 읽었을 때도 숫자는 double
으로 MATLAB에 저장되므로 swapbytes
으로 들어가기 전에 숫자를 캐스팅해야한다는 것을 명심해야합니다.
일단 실제 이미지 데이터에 도달하면 numRows x numCols
바이트 단위로 읽을 수 있고 어레이가 이미지가되도록 배열을 바꿀 수 있습니다. 각 이미지를 셀 배열에 저장할 수 있습니다. 더 이상 신경 쓰지 않고 여기에 코드가 있습니다.
clear all;
close all;
%//Open file
fid = fopen('t10k-images-idx3-ubyte', 'r');
%//Read in magic number
%//A = fread(fid, 4, 'uint8');
%//magicNumber = sum(bitshift(A', [24 16 8 0]));
%//OR
A = fread(fid, 1, 'uint32');
magicNumber = swapbytes(uint32(A));
%//Read in total number of images
%//A = fread(fid, 4, 'uint8');
%//totalImages = sum(bitshift(A', [24 16 8 0]));
%//OR
A = fread(fid, 1, 'uint32');
totalImages = swapbytes(uint32(A));
%//Read in number of rows
%//A = fread(fid, 4, 'uint8');
%//numRows = sum(bitshift(A', [24 16 8 0]));
%//OR
A = fread(fid, 1, 'uint32');
numRows = swapbytes(uint32(A));
%//Read in number of columns
%//A = fread(fid, 4, 'uint8');
%//numCols = sum(bitshift(A', [24 16 8 0]));
%// OR
A = fread(fid, 1, 'uint32');
numCols = swapbytes(uint32(A));
%//For each image, store into an individual cell
imageCellArray = cell(1, totalImages);
for k = 1 : totalImages
%//Read in numRows*numCols pixels at a time
A = fread(fid, numRows*numCols, 'uint8');
%//Reshape so that it becomes a matrix
%//We are actually reading this in column major format
%//so we need to transpose this at the end
imageCellArray{k} = reshape(uint8(A), numCols, numRows)';
end
%//Close the file
fclose(fid);
당신이 (numRows
, numCols
로 저장) 행과 열의 수 (magicNumber
로 저장) 마법 번호와 (totalImages
로 저장) 이미지의 총 수를 선택하면,이 2051, 28, 28
같아야한다 및 각각 10000
. 이 코드 다음에 kth
요소 인 imageCellArray
은 kth
자릿수를 MNIST 데이터베이스에 저장합니다. imshow(imageCellArray{k});
을 입력하는 경우 k
은 1
에서 10000
사이의 정수입니다. 숫자를 볼 수 있어야합니다.
또 하나의 마지막 참고 사항 : 행렬 데이터를 읽는 것이 double
일 때 이미지가 데이터베이스에서 해당 유형이므로 uint8
이되도록 캐스팅해야합니다.
행운을 빈다.
설명서를 보면 'int'한정자가 올바른 결과를 보장하지 않습니다. 'int32'로 지정하십시오. 또한 데이터를 표시 할 때 예상되는 모든 데이터가 있습니까? 모든 숫자가 정확합니까? 그렇다면, 진행하기 전에 단순히'int32'로 변환하면됩니다. – rayryeng
예, 저는 uint와 uint32와 함께 int32도 시도했습니다. 내가 아는 모두는 이진 파일이 32 비트 정수이지만, 직접 만들지는 않았다. 출력 데이터는 내가 예상했던대로는 아니며, 처음 몇 자리가 무엇인지 알아야합니다. – EddyJ
어딘가에 그 파일을 게시 할 수 있습니까? 우리는 추가로 – rayryeng