私たちのコメントによると、MATLAB が一度に 4 つの整数を読み取る方法は inlittle-endian
形式であり、MNIST データベース ファイルのファイル形式は ですbig-endian
。そのため、ファイルの最初の 4 バイトを読み取ると、バイトは0x00, 0x00, 0x08, 0x03
期待どおりになります。ただし、MATLAB はこれを として読み取ります0x03, 0x08, 0x00, 0x00
。これを整数に変換すると、実際には50855936
必要でないものが得られます。
これを解決するためのハックは、一度に数バイトを読み取る必要がある場合uint8
です。データ型を確実に指定する必要があります。これにより、各バイトが配列内の個別の要素に格納されます。次に、各バイトを指定された量だけビットシフトし、結果を合計することで、必要な数を計算できます。これは、データ ファイルの最初の数バイトに対して行う必要があります。
swapbytes
または、コメントで述べた方法を使用することもできます。これにより、まったく同じことが得られます。タイプの1バイトを読み取るだけで、バイトがフォーマットuint32
されるようにバイトの順序を入れ替えることができます。big-endian
としてデータを読み込む場合でもuint32
、数値は MATLAB as に格納されるdouble
ため、 に入る前に数値をキャストする必要があることに注意してくださいswapbytes
。
実際の画像データを取得したら、一度にnumRows x numCols
バイト単位で読み取り、配列を変形して画像にすることができます。各画像を cell 配列に格納できます。これ以上苦労することなく、これがコードです。
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
と等しくなるはずです。このコードの後に、 の要素が数字を MNIST データベースに格納します。を実行すると、はから までの任意の整数で、数字が表示されるはずです。2051, 28, 28
10000
kth
imageCellArray
kth
imshow(imageCellArray{k});
k
1
10000
また、最後に 1 つ注意してください。行列データの読み込みは で行われるdouble
ため、これをキャストしuint8
て、画像がデータベースからのそのタイプのものになるようにする必要があります。
幸運を!