模式识别课程做一个数字识别的小组作业,采用MNIST数据集,方法是PCA+BP和CNN的对比实验,环境是Matlab。这里先贴上读图片和PCA降维部分。
参考:https://blog.csdn.net/tracer9/article/details/51253604
https://blog.csdn.net/wangyuquanliuli/article/details/17378317
关于数据集网址:http://yann.lecun.com/exdb/mnist/
数据集信息:
4个压缩包:
train-images-idx3-ubyte: training set images
train-labels-idx1-ubyte: training set labels
t10k-images-idx3-ubyte: test set images
t10k-labels-idx1-ubyte: test set labels
训练集60000个样例,测试集10000个样例。
把安装包下载下来解压,把文件复制到matlab工作区。
贴上读取程序:
读取图片:
function images = readpicture(filename)
%读二进制文件,filename为文件名
%filename='t10k-images.idx3-ubyte';(测试)
%或者filename='train-images.idx3-ubyte';(训练)
%输出images矩阵的行与列为784*10000(测试)或784*60000(训练)
fp = fopen(filename, 'rb');
assert(fp ~= -1, ['Could not open ', filename, '']);
magic = fread(fp, 1, 'int32', 0, 'ieee-be');
assert(magic == 2051, ['Bad magic number in ', filename, '']);
numImages = fread(fp, 1, 'int32', 0, 'ieee-be');
numRows = fread(fp, 1, 'int32', 0, 'ieee-be');
numCols = fread(fp, 1, 'int32', 0, 'ieee-be');
images = fread(fp, inf, 'unsigned char');
images = reshape(images, numCols, numRows, numImages);
images = permute(images,[2 1 3]);
fclose(fp);
% Reshape to #pixels x #examples
images = reshape(images, size(images, 1) * size(images, 2), size(images, 3));
% Convert to double and rescale to [0,1] (归一化可选)
%images = double(images) / 255;
end
读取标签:
function labels = readlabel(filename)
%filename='t10k-labels.idx1-ubyte';(测试)
%或者filename='train-labels.idx1-ubyte';(训练)
%矩阵label的行列为10000*1(测试)或60000*1(训练)
%即label为列向量,需要行向量的话需要转置一下
fp = fopen(filename, 'rb');
assert(fp ~= -1, ['Could not open ', filename, '']);
magic = fread(fp, 1, 'int32', 0, 'ieee-be');
assert(magic == 2049, ['Bad magic number in ', filename, '']);
numLabels = fread(fp, 1, 'int32', 0, 'ieee-be');
labels = fread(fp, inf, 'unsigned char');
assert(size(labels,1) == numLabels, 'Mismatch in label count');
fclose(fp);
end
PCA程序为:
function [ A ] = pca( B )
%pca功能实现
%输入矩阵B的行列为784*10000(测试)或784*60000(训练)
%输出A的行列为20*10000(测试)或20*60000(训练)
ave=B-ones(size(B,1),1)*mean(B);
C=1/(size(B,2))*(ave*ave');
[V,D]=eigs(C,20);
A=V'*B;
end
主测试程序:
%主测试程序,两步,读图片、标签;将图片pca降维
%这里需要改动的只有文件名
images = readpicture('t10k-images.idx3-ubyte');
labels = readlabel('t10k-labels.idx1-ubyte');
A=pca(images);
%%以下是测试图片矩阵和标签一一对应,主程序中不必考虑
%C=images(:,1); %读取图像第一列(当然也可以是第n列)
%C=reshape(C,28,28);
%imshow(C,[]); %显示图像,可以看到数字与标签中的第1个(或第n个)相同
关于PCA算法:
其中,B的行数为原图片的维数,列数为样本个数。算法中的B为40张图片,每张图片10304维,最后降到20维。