赞赏码 & 联系方式 & 个人闲话
配套课件可访问https://github.com/BIMK/MATLAB下载,是安徽大学Matlab本科教学课件,逻辑清晰,简洁明了,颇为实用,用来入门再好不过(机器学习方向)。
本系列博文是课后练习的个人解答,通过几个小实验展示matlab基本语法和技巧。接触Matlab也有几年了,略有心得,分享给大家。
【实验名称】图像识别
【实验目的】
1. 熟悉matlab图像识别的基础算法
2. 掌握基本的前馈神经网络算法
3. 掌握神经网络参数调优方法
【实验内容】
1. 采用面向对象编程实现简单的神经网络,并用于图像识别任务中;
2. 将神经网络用于ORL人脸数据库的分类任务中;
3. ORL数据库中含有40个人的黑白照片,其中每个人含有10幅照片,共400幅;
4. 每幅图像的大小为112*92*1,即每个样本的特征数为10304;
5. 共40个类别标签,即每个样本的标签数为40,且其中一个标签值为1、其它所有标签值为0;
6. 将每个人的前7幅图像作为训练样本(共280个),后3幅图像作为测试样本(共120个)
7. 寻找最优的网络超参数以尽可能降低误差
Main.m代码(详见注释)
-
function main()
-
clc; close all;
-
Num =
40; Train =
7; Test=
3;
-
%% 读取
-
Xtrain = []; Xtest = [];
-
for i =
1:Num
-
for j =
1:Train+Test
-
path = [
'ORL/s',num2str(i),
'/',num2str(j),
'.pgm'];
-
temp = imread(path);
-
if j<=Train
-
Xtrain = [Xtrain;double(reshape(temp,
1,size(temp,
1)*size(temp,
2)))];
-
else
-
Xtest = [Xtest ;double(reshape(temp,
1,size(temp,
1)*size(temp,
2)))];
-
end
-
end
-
end
-
%% pca
-
[~,X] = pca([Xtrain;Xtest]);
-
Xtrain = X(
1:size(Xtrain,
1),:);
-
Xtest = X(size(Xtrain,
1)+
1:
end,:);
-
%% 生成标签
-
temp = eye(Num)
';
-
Y1train = zeros(Num*Train,Num);
-
Y1test = zeros(Num*Test ,Num);
-
for i = 1:size(temp,1)
-
Y1train(i*Train-6:i*Train,:) = repmat(temp(i,:),Train,1);
-
Y1test (i*Test -2:i*Test ,:) = repmat(temp(i,:),Test ,1);
-
end
-
net = NN() ;
-
net.train(Xtrain, Y1train);
-
Ytrain = net.test(Xtrain) ;
-
[~, Ytrain ] = max(Ytrain, [],2);
-
[~, Y1train] = max(Y1train, [],2);
-
mean(Ytrain ~= Y1train)
-
Ytest = net.test(Xtest);
-
[~, Ytest ] = max(Ytest, [],2);
-
[~ ,Y1test] = max(Y1test, [],2);
-
mean(Ytest ~= Y1test)
-
end
-
NN.m代码(详见注释)
-
classdef NN < handle
-
properties
-
% 网络的超参数
-
nHidden =
51; % 隐层神经元数
-
epoch =
100; % 训练迭代次数
-
learning =
0.0006; % 学习率
-
momentum =
0.51; % 动量法参数
-
W = []; % 输入层与隐层之间权值
-
V = []; % 隐层与输出层之前权值
-
end
-
methods
-
function train(obj, X, Y1)
-
% 根据训练集X和真实标签集Y1来训练神经网络
-
obj.W = randn(size(X,
2)+
1, obj.nHidden)/
100;
-
obj.V = randn(obj.nHidden+
1,size(Y1,
2))/
100;
-
N = size(X,
1);
-
for i =
1:obj.epoch
-
clc; fprintf(
'ѵÁ·µÚ%d´Î',i);
-
% 前馈阶段
-
H =
1./(
1+exp(-[ones(N,
1),X]*obj.W));
-
Y = [ones(N,
1),H]*obj.V;
-
% 反馈阶段
-
DV = [ones(N,
1),H]
'*(Y-Y1);
-
DW = [ones(N,1),X]'*((Y-Y1)*obj.V(
2:
end,:)
'.*H.*(1-H));
-
% 动量更新权值
-
if i==1
-
MV = DV; MW= DW;
-
else
-
MV = (1-obj.momentum)*DV + obj.momentum*MV;
-
MW = (1-obj.momentum)*DW + obj.momentum*MW;
-
end
-
obj.V = obj.V - obj.learning*MV;
-
obj.W = obj.W - obj.learning*MW;
-
end
-
end
-
function Y = test (obj, X)
-
% 计算测试集X的预测标签集Y
-
N = size(X,1);
-
H = 1./(1+exp(-[ones(N,1),X]*obj.W));
-
Y = [ones(N,1),H]*obj.V;
-
end
-
function c = complexity(obj)
-
c = sum(sum(abs(obj.W))) + sum(sum(abs(obj.V)));
-
end
-
end
-
end
-
运行结果
总结
参数优化的结果不太满意,手动调参只调到了0.0833,是k近邻法近两倍。参数并不是很好调,毕竟有随机化因素所以即使相同参数,训练出的模型的预测误差也会相差很多。
我尝试用进化算法进行调参,效果也并不是特别理想,试了多次,最小的误差大约是0.047,还是大于0.0417。
转载:https://blog.csdn.net/qq_37672864/article/details/117392262
查看评论