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
具体跑出来数据是什么样子大家跑一跑看一看就知道了!