课程作业记录7:MNIST数据集数据读取成cell格式/double格式/Matlab仿真

MNIST数据集在他们官网上可以下载,同时下面他们其实是有讲怎么读他们的数据的,就是具体讲了他们的格式。
官网地址-> http://yann.lecun.com/exdb/mnist/
从这上面你可以下载下来四个文件,分别是训练集,训练集标签,测试集和测试集标签。训练集有60000个图像,测试集10000个图像。

下面这个readDATA代码来自 -> https://github.com/jervisfm/Digit-Recognizer,感恩感恩,感恩的心,感谢有大佬。
我把注释都翻译过来了,值得注意的是,这个代码运行出来的数据为cell格式。
跑的时候大家记得改文件地址!

% 本函数功能为:
% 读取MNIST数据集的值

% 本函数涉及的参数为: 
% train_data -> 训练图像数据
% train_labels -> 训练图像数据的标签
% images -> 图像
% test_data -> 测试图像数据
% test_labels -> 测试图像数据的标签

% 参考资料:https://github.com/jervisfm/Digit-Recognizer

function [train_data, train_labels, test_data, test_labels] = readDATA()

path = 'C:\Users\Teacher\Desktop\Lzu\课程设计\数据库\train-images.idx3-ubyte';
file = fopen(path, 'r', 'b'); 
%打开文件,path为文件路径,r为读出,b为高位编址。

%{
训练图像文件格式如下所示 :
[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
%}

magicNumber = fread(file,1,'int32'); %以有符号32位整数的形式读取文件的幻数
if(magicNumber ~= 2051)
    disp('错误:未查找到幻数为2051的文件,请确认文件是否为IDX格式。');
    return; %停止运行
end

imagesNo = fread(file,1,'int32'); %图像数
rowSize = fread(file,1,'int32'); %行数
colSize = fread(file,1,'int32'); %列数

% Lessons learnt
% 1) giving a matrix size as an argument when using matlab fread, what you get is a image
% matrix that has been tranposed. To undo this, we simply tranpose it once
% AND then it is the same format and it would have been if we had read 
% in the data manually one byte at a time.
%
% 2) the other choice is of course to read in the image pixel
% values of the 28x28 image, one byte at a time, to an array. 
% 
% 3) there is NO difference in matlab between how uint8 and ubit8 are
% interpretted in the context of this data.  


%读取训练数据
for i = 1: imagesNo
    
    img_sample = fread(file, [rowSize colSize], 'uint8') ;  % 像素值储存形式为一个无符号字节
    img_sample =  img_sample'; % 转置像素值
    
    img_sample = double(img_sample); %将像素值形式转换为double
    img_sample = img_sample / max(img_sample(:)); %归一化像素值
    
    train_data{i} = img_sample; 
    
end

fclose(file); %释放文件相关缓冲区

%{
训练标记的二进制文件格式如下所示: 
[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
The labels values are 0 to 9.
%}

%% 读取训练数据标签

path = 'C:\Users\Teacher\Desktop\Lzu\课程设计\数据库\train-labels.idx1-ubyte';
file = fopen(path, 'r', 'b'); %打开文件,path为文件路径,r为读出,b为高位编址。

magicNumber = fread(file,1,'int32'); 
if(magicNumber ~= 2049)
    disp('错误:未查找到幻数为2049的文件,请确认文件是否为IDX格式。');
    return; % 停止运行
end

itemsNo = fread(file,1,'int32'); %已被标记的样本数量

for j = 1:itemsNo
   train_labels{j} = fread(file, 1, 'uint8');
end

fclose(file); 

%% 读取测试数据
path = 'C:\Users\Teacher\Desktop\Lzu\课程设计\数据库\t10k-images.idx3-ubyte';
file = fopen(path, 'r', 'b'); %打开文件,path为文件路径,r为读出,b为高位编址。

magicNumber = fread(file,1,'int32'); 
if(magicNumber ~= 2051)
    disp('错误:未查找到幻数为2051的文件,请确认文件是否为IDX格式。');
    return; %停止运行
end

testImagesNo = fread(file,1,'int32'); % 图像样本数
rowSize = fread(file,1,'int32'); % 行数
colSize = fread(file,1,'int32'); % 列数

%读取实际数据
for i = 1: testImagesNo
    img = fread(file, [rowSize colSize], 'uint8') ;  % 像素值储存形式为一个无符号字节
    img =  img'; % 转置像素值 
   
    img = double(img); %将像素值形式转换为double
    img = img / max(img(:)); %归一化像素值
   
    test_data{i} = img; 
end

fclose(file); 

%% 读取测试数据标签

path = 'C:\Users\Teacher\Desktop\Lzu\课程设计\数据库\t10k-labels.idx1-ubyte';
file = fopen(path, 'r', 'b'); %打开文件,path为文件路径,r为读出,b为高位编址。

magicNumber = fread(file,1,'int32'); 
if(magicNumber ~= 2049)
    disp('错误:未查找到幻数为2049的文件,请确认文件是否为IDX格式。');
    return; % 停止运行
end

itemsNo = fread(file,1,'int32'); % 已被标记的样本数
for j = 1:itemsNo
   test_labels{j} = fread(file, 1, 'uint8');
end

disp('MNIST数据成功读取');

end

如果大家想要cell格式的数据现在就可以停了,不过我当时做CNN仿真时想要的是28x28x60000double的图像数据和10x60000的标签数据,然后自己写了个函数转数据。
当然,其实也可以直接读出来就是double数据,很明显我根本不敢改上面readDATA函数,还是老老实实从cell格式转吧,嘿嘿。

% 本函数功能为:
% 将MNIST数据值读出来的cell格式转换为其他数据格式
% 便于我们下一步的数据处理

% 本函数涉及的参数为: 
% train_x -> 训练图像数据
% train_y -> 训练图像数据标签
% test_x -> 测试图像数据
% test_y -> 测试图像数据标签

function [train_x, train_y, test_x, test_y] = transformDATA()

[train_data, train_labels,test_data,test_labels] = readDATA();% 读数据集
sizeTrain = size(train_data,2);% train_data的列数
sizeTest = size(test_data,2);% test_data的列数

% 转换图像数据为28x28xsize的格式
for i = 1:sizeTrain
    
    train_x(:,:,i)=train_data{i};
    train_yy(i)=train_labels{i};
    
end

for j = 1:sizeTest
    
    test_x(:,:,j)=test_data{j};
    test_yy(j)=test_labels{j};
    
end

% 继续转换label数据
% eg:label数据为0,该列第1个数字为1,其余数字均为0
% 以此类推

train_y = zeros(10,sizeTrain);
test_y = zeros(10,sizeTest);

for i = 1:sizeTrain
    
    train_y(train_yy(i)+1,i) = 1;
         
end

for i = 1:sizeTest
    
    test_y(test_yy(i)+1,i) = 1;
    
end

disp('MNIST数据成功转换');

end

具体跑出来数据是什么样子大家跑一跑看一看就知道了!

你可能感兴趣的:(课程作业记录7:MNIST数据集数据读取成cell格式/double格式/Matlab仿真)