2016-09-19 5 views
2

내가 링크어떻게하면 MATLAB에서 MNIST 숫자 및 레이블 데이터를로드 할 수 있습니까?

https://github.com/bd622/DiscretHashing

이산 해싱에 주어진 코드를 실행하려고하면 대략 가까운 이웃 검색에 사용되는 차원 축소 방법이다. http://yann.lecun.com/exdb/mnist/에서 사용할 수있는 MNIST 데이터베이스의 구현에로드하려고합니다. 압축 된 gz 형식의 파일을 추출했습니다. MNIST 데이터베이스가 나는 다음과 같은 오류가 무엇입니까 Reading MNIST Image Database binary file in MATLAB

에서 제공 읽을 수있는 솔루션을 사용

:

문제 1

clear all; 
close all; 

%//Open file 
fid = fopen('t10k-images-idx3-ubyte', 'r'); 

A = fread(fid, 1, 'uint32'); 
magicNumber = 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); 
다음은

Error using fread 
Invalid file identifier. Use fopen to generate a valid file identifier. 

Error in Reading (line 7) 
A = fread(fid, 1, 'uint32'); 

코드입니다

업데이트 : 문제 하나 해결하고 수정 된 코드는

clear all; 
close all; 

%//Open file 
fid = fopen('t10k-images.idx3-ubyte', 'r'); 

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

문제 2 : 내가 코드에 MNIST의 4 개 파일을 적용하는 방법을 이해할 수 없다

. 코드에 변수가 포함되어 있습니다.

traindata = double(traindata); 
testdata = double(testdata); 

구현에 적용 할 수 있도록 MNIST 데이터베이스를 어떻게 준비합니까?

UPDATE : 나는 솔루션을 구현하지만 이러한 파일

demo.m퍼센트이가 MNIST 데이터에 읽을 수있는 함수를 호출하는 주요 파일입니다이 오류

Error using fread 
Invalid file identifier. Use fopen to generate a valid file identifier. 

Error in mnist_parse (line 11) 
A = fread(fid1, 1, 'uint32'); 

가 계속

clear all 
clc 
[Trainimages, Trainlabels] = mnist_parse('C:\Users\Desktop\MNIST\train-images-idx3-ubyte', 'C:\Users\Desktop\MNIST\train-labels-idx1-ubyte'); 

[Testimages, Testlabels] = mnist_parse('t10k-images-idx3-ubyte', 't10k-labels-idx1-ubyte'); 

k=5; 
digit = images(:,:,k); 
lbl = label(k); 

function [images, labels] = mnist_parse(path_to_digits, path_to_labels) 

% Open files 
fid1 = fopen(path_to_digits, 'r'); 

% The labels file 
fid2 = fopen(path_to_labels, 'r'); 

% Read in magic numbers for both files 
A = fread(fid1, 1, 'uint32'); 
magicNumber1 = swapbytes(uint32(A)); % Should be 2051 
fprintf('Magic Number - Images: %d\n', magicNumber1); 

A = fread(fid2, 1, 'uint32'); 
magicNumber2 = swapbytes(uint32(A)); % Should be 2049 
fprintf('Magic Number - Labels: %d\n', magicNumber2); 

% Read in total number of images 
% Ensure that this number matches with the labels file 
A = fread(fid1, 1, 'uint32'); 
totalImages = swapbytes(uint32(A)); 
A = fread(fid2, 1, 'uint32'); 
if totalImages ~= swapbytes(uint32(A)) 
    error('Total number of images read from images and labels files are not the same'); 
end 
fprintf('Total number of images: %d\n', totalImages); 

% Read in number of rows 
A = fread(fid1, 1, 'uint32'); 
numRows = swapbytes(uint32(A)); 

% Read in number of columns 
A = fread(fid1, 1, 'uint32'); 
numCols = swapbytes(uint32(A)); 

fprintf('Dimensions of each digit: %d x %d\n', numRows, numCols); 

% For each image, store into an individual slice 
images = zeros(numRows, numCols, totalImages, 'uint8'); 
for k = 1 : totalImages 
    % Read in numRows*numCols pixels at a time 
    A = fread(fid1, 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 
    images(:,:,k) = reshape(uint8(A), numCols, numRows).'; 
end 

% Read in the labels 
labels = fread(fid2, totalImages, 'uint8'); 

% Close the files 
fclose(fid1); 
fclose(fid2); 

end 
+1

오류는 자명하지만, 잘못된 파일 이름에'fopen'을 사용했습니다. ''t10k-images-idx3-ubyte''가 파일의 * 전체 * 이름이고 현재 MATLAB 경로에 있는지 확인하십시오. 그렇지 않으면 열려고하는 파일의 * 절대 * 절대 경로인지 확인하십시오. – excaza

+0

@excaza : 파일 읽기 작업으로 인한 첫 번째 문제와 오류가 해결되었습니다. 실제로 파일 이름에 문제가있었습니다. 하지만 지금은 데이터베이스를 사용하는 방법에 대한 단서가 없으며 4 개의 파일을 사용하는 방법을 이해할 수 없습니다. traindata 변수에 train-images.idx3-ubyte 파일이 포함되어 있다고 생각합니다. 그러면 어느 것이 testdata가 될 것인가? 그리고 어떻게 2 레이블 데이터베이스 파일을 사용해야합니까? 도와주세요 – SKM

+0

@rayryeng : 답변을 구현할 때 파일 읽기 작업으로 인해 오류가 발생하는 이유를 알려주십시오. 질문에 새 업데이트를 올렸습니다. 시간과 노력에 감사드립니다. – SKM

답변

3

나는 당신이 한 Method # 1의 원작자입니다. 교육 데이터 및 테스트 라벨을 읽는 프로세스는 매우 간단합니다. 이미지 읽기 측면에서 위에서 보여준 코드는 파일을 완벽하게 읽고 셀 배열 형식으로되어 있습니다. 그러나 파일 내에있는 이미지, 행 및 열 수는 입니다.입니다. 이 파일에 대한 MNIST 형식은 다음과 같은 형식으로되어 있습니다. 왼쪽 열은 당신이 처음에 대하여 참조하는 바이트 오프셋 : 제대로 파일에 읽고있는 것을 확인하기 위해 2051 :

[offset] [type]   [value]   [description] 
0000  32 bit integer 0x00000803(2051) magic number 
0004  32 bit integer 60000   number of images 
0008  32 bit integer 28    number of rows 
0012  32 bit integer 28    number of columns 
0016  unsigned byte ??    pixel 
0017  unsigned byte ??    pixel 
........ 
xxxx  unsigned byte ??    pixel 

첫 번째 4 바이트는 매직 넘버이다. 다음 4 바이트는 총 이미지 수를 나타내며 그 다음 4 바이트는 행이고 다음 4 바이트는 열입니다. 크기가 28 행 28 열인 60000 개의 이미지가 있어야합니다. 이 후 픽셀은 행 주요 형식으로 인터리브되므로 일련의 28x28 픽셀을 반복하여 저장해야합니다.이 경우 셀 배열에 저장했으며 셀 배열의 각 요소는 한 자리 수입니다. 동일한 형식이 테스트 데이터 용이지만, 대신 10000 개의 이미지가 있습니다. 실제 라벨로

, 그것은 거의 같은 형식입니다하지만 약간의 차이가 있습니다

[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 

가 첫 번째 4 바이트는 매직 넘버 있습니다 : 2049, 다음 4 바이트의 두 번째 세트를 사용하는 방법을 알려줍니다 많은 레이블이 있으며 마지막으로 데이터 세트의 각 해당 숫자에 정확히 1 바이트가 있습니다. 테스트 데이터도 같은 형식이지만 10000 개의 레이블이 있습니다. 따라서 레이블 세트에서 필요한 데이터를 읽은 후에는 fread 호출이 하나만 필요하며 레이블의 나머지 부분을 읽으려면 데이터가 부호없는 8 비트 정수인지 확인해야합니다. MATLAB 바이트의 세트에서 최하위 바이트이 먼저 읽을 것을 의미 리틀 엔디안 형식의 데이터를 읽을 수 있기 때문에

은 이제 swapbytes을 사용해야하는 이유입니다. 완료되면 swapbytes을 사용하여이 순서를 재정렬하십시오.

마찬가지로이 코드는 두 개의 문자열 집합을 취하는 실제 함수가되도록 수정했습니다. 이미지 파일의 전체 경로와 숫자의 전체 경로. 또한 빠른 처리를 위해 이미지가 3D 숫자 행렬이되도록 셀 코드를 변경하여 코드를 변경했습니다. 실제 이미지 데이터를 읽을 때 각 픽셀은 부호없는 8 비트 정수이므로 바이트를 스와핑 할 필요가 없습니다.

function [images, labels] = mnist_parse(path_to_digits, path_to_labels) 

% Open files 
fid1 = fopen(path_to_digits, 'r'); 

% The labels file 
fid2 = fopen(path_to_labels, 'r'); 

% Read in magic numbers for both files 
A = fread(fid1, 1, 'uint32'); 
magicNumber1 = swapbytes(uint32(A)); % Should be 2051 
fprintf('Magic Number - Images: %d\n', magicNumber1); 

A = fread(fid2, 1, 'uint32'); 
magicNumber2 = swapbytes(uint32(A)); % Should be 2049 
fprintf('Magic Number - Labels: %d\n', magicNumber2); 

% Read in total number of images 
% Ensure that this number matches with the labels file 
A = fread(fid1, 1, 'uint32'); 
totalImages = swapbytes(uint32(A)); 
A = fread(fid2, 1, 'uint32'); 
if totalImages ~= swapbytes(uint32(A)) 
    error('Total number of images read from images and labels files are not the same'); 
end 
fprintf('Total number of images: %d\n', totalImages); 

% Read in number of rows 
A = fread(fid1, 1, 'uint32'); 
numRows = swapbytes(uint32(A)); 

% Read in number of columns 
A = fread(fid1, 1, 'uint32'); 
numCols = swapbytes(uint32(A)); 

fprintf('Dimensions of each digit: %d x %d\n', numRows, numCols); 

% For each image, store into an individual slice 
images = zeros(numRows, numCols, totalImages, 'uint8'); 
for k = 1 : totalImages 
    % Read in numRows*numCols pixels at a time 
    A = fread(fid1, 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 
    images(:,:,k) = reshape(uint8(A), numCols, numRows).'; 
end 

% Read in the labels 
labels = fread(fid2, totalImages, 'uint8'); 

% Close the files 
fclose(fid1); 
fclose(fid2); 

end 

단순히 이미지 파일과 라벨 파일 모두에 경로를 지정,이 함수를 호출하려면 하나 fread 호출에 여러 바이트 읽기 때에 만 필요했다.

또한
[images, labels] = mnist_parse('train-images-idx3-ubyte', 'train-labels-idx1-ubyte'); 

, 당신은 테스트 이미지에 대해 다음을 할 것이다 :

을 당신이 파일이있는 같은 디렉토리에이 파일을 실행하는 가정, 당신은 교육 이미지에 대해 다음 중 하나를 할 것

[images, labels] = mnist_parse('t10k-images-idx3-ubyte', 't10k-labels-idx1-ubyte'); 
k 번째 자리에 액세스하려면, 당신은 단순히 할 것 :

digit = images(:,:,k); 

k 번째 자리에 대한 대응 라벨은 다음과 같습니다

lbl = label(k); 

마침내 내가 Github에서에서 본 그 코드에 허용되는 형식으로이 데이터를 얻기 위해, 그들은 행이 훈련 예에 해당하고, 열이 기능에 해당한다고 가정합니다. 이 형식을 원한다면 단순히 의 모양을 바꿔서 데이터를 만들어 이미지 픽셀이 열 위에 펼쳐지도록하십시오.

따라서, 단지 이렇게 : 당신이 플러그 할 수 있어야하고 작동해야하므로

[trainingdata, traingnd] = mnist_parse('train-images-idx3-ubyte', 'train-labels-idx1-ubyte'); 
trainingdata = double(reshape(trainingdata, size(trainingdata,1)*size(trainingdata,2), []).'); 
traingnd = double(traingnd); 

[testdata, testgnd] = mnist_parse('t10k-images-idx3-ubyte', 't10k-labels-idx1-ubyte'); 
testdata = double(reshape(testdata, size(testdata,1)*size(testdata_data,2), []).'); 
testgnd = double(testgnd); 

위의 스크립트와 같은 변수를 사용합니다. 두 번째 줄은 행렬을 변형하여 각 자리가 한 열에 있지만 각 자리가 한 열에 있도록 조판해야합니다. 또한 Github 코드가 수행하는대로 double으로 캐스트해야합니다. 동일한 로직이 테스트 데이터에 적용됩니다.또한이 데이터에서 사용하기로 결정한 알고리즘의 호환성을 최대한 보장하려면 교육 및 테스트 라벨을 double으로 명시 적으로 캐스팅해야합니다.


해피 디지트 해킹!

+0

자세한 설명을 해주셔서 감사합니다. 내 결함을 이유로 내 Stackoverflow 계정에 로그인 할 수 없기 때문에 귀하의 답변을 확인할 수 없습니다. 그래서, 단계별로 귀하의 코드를 실행하지만 Matlab 오류가 throw됩니다 : 오류 fread 사용 잘못된 파일 식별자입니다. 유효한 파일 식별자를 생성하려면 fopen을 사용하십시오. mnist_parse (줄 11)의 오류 A = fread (fid1, 1, 'uint32'); 데모에서 오류가 발생했습니다 (줄 3) [Trainimages, Trainlabels] = mnist_parse ('C : \ Users \ Desktop \ MNIST \ train-images-idx3-ubyte', 'C : \ Users \ Desktop \ MNIST \ train-labels -idx – SKM

+0

totalImages, 행 및 열의 수를 읽지 못했다는 귀하의 관찰을 바탕으로, 나는 그 부분을 바로 잡았습니다. 나는 이것을 나의 문제에서 고쳤습니다. 그러나 구현했을 때 나타나는이 새로운 오류를 완화하기위한 노력을 기울였습니다. 귀하의 솔루션입니다. 나는 GitHub에서 프로그램에 적용해야하는 코드의 마지막 단락을 사용하지 않았습니다. 오류가 사라지도록 내가해야 할 일을 알려주십시오. – SKM

+0

경로가 올바르지 않아 작동하지 않습니다. 당신의 경로에있는 사용자와 데스크탑 사이에 사용자 이름이 있어야합니다.이 디렉토리는 존재하지 않습니다. 'fopen'은 파일의 유효한 경로가 제공되었지만 아직 완료하지 않았을 때 작동합니다. o 파일이 절대적으로 올바른지 ... 아니면 MNIST 데이터와 동일한 디렉토리에 스크립트를두고 로컬 경로를 사용하십시오. – rayryeng