🌀Jarson Cai's Blog
头脑是日用品,不是装饰品
《模式识别&机器学习》课后作业(1)
研究生课程课后小作业

《模式识别&机器学习》课后作业

作业一

写一个感知器算法,用来区分1到10里的任意两个数字,并与真实结果进行比较。

代码实现

  • Perceptron.m(主函数):
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
%Perceptron.m
clear variables
clc
% 读取数据
load ('test_images.mat');
load ('test_labels.mat');
 
% 设定数据量
train_num = 1000;
test_num =200;
% 临时变量以及各个感知器参数
j = 1;
lr = 0.1;%学习率
epoch = 70;%设定训练多少轮
number = [4,8];%要取的数字组合
 
% 提取数据中标签为任意组合的样本,共计200个
% 由于数据本身打乱过,因此可以直接取200个而不考虑样本不均衡问题
%提取数字4和8的样本
for i = 1:10000
    if test_labels1(i)==number(1)|| test_labels1(i)==number(2)
        data(:,:,j) = test_images(:,:,i);
        label(j) = test_labels1(i);%取相应标签
        j=j+1;
     if j>train_num+test_num
         break;
     end
    end
end
 
% 由于感知器输出结果仅为0、1,因此要将标签进行转换
% 本程序中,由于matlab计算不等式相对容易,因此没有对样本进行规范化
% 由于没有进行规范化,后面更新权值w需要借助标签,因此标签需要置-1和1
 
for k = 1:train_num+test_num
    if label(k)==number(1)
        label(k)=-1;
    end
    if label(k)==number(2)
        label(k)=1;
    end
end
 
data_ = liansuyun_mat2vector(data, train_num + test_num);%矩阵转向量

%数据归一化
%   [data_,PS]=mapminmax(data_);
%train_data =[data_(1:train_num,:) label1(1:train_num,1)];
test_data = [data_(train_num+1:train_num+test_num,:),ones(test_num,1)];%这里对测试数据也进行增广变换
% test_data = data_(train_num+1:train_num+test_num,:);
% 训练权值
 
w=perceptionLearn(data_(1:train_num,:),label(1:train_num),lr,epoch);
% 测试(预测)
for k = 1:test_num
    if test_data(k,:)*w'>0
        result(k) = 1;
    else
        result(k) = -1;
    end
end

% 输出预测的准确率
acc = 0;
sum=0;
sum1=0;
for sample = 1:test_num
    if result(sample)==label(train_num+sample)
        acc = acc+1;
    else
        fprintf('分类错误的序号为:%d\n',sample);
        sum=sum+1;
    end    
end
sum1=test_num-sum;
fprintf('分类错误的个数为:%d,分类正确的个数为:%d\n',sum,sum1);
fprintf('精确度为:%5.2f%%\n',(acc/test_num)*100);
  • perceptionLearn.m:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
%% perceptionLearn.m
% 函数输入:数据(行向量),标签,学习率,终止轮次
% 输出:训练得到的权值向量
% 训练方法:单样本修正,学习率(步长)采用了固定值

function [w]=perceptionLearn(x,y,learningRate,maxEpoch)
    [rows,cols]=size(x);
    x=[x,ones(rows,1)];%增广
    w=zeros(1,cols+1);%同上
    for epoch=1:maxEpoch%不可分情况下整体迭代轮次
        flag=true;%标志位真则训练完毕
        for sample=1:rows
            if sign(x(sample,:)*w')~=y(sample)%分类是否正确?错误则更新权值
                flag=false;
               %这里和教案稍有不同,不进行规范化,那么更新权值时需要标签来充当梯度方向的变量
                w=w+learningRate*y(sample)*x(sample,:);
            end
        end
        if flag==true
            break;
        end
    end
end
  • liansuyun_mat2vector.m:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
%% liansuyun_mat2vector.m
% 函数输入:数据(三维数据),数据个数
% 输出:数据(1200个一维向量)
% 功能:将每一个二维矩阵变为1维向量
function [w]=liansuyun_mat2vector(mat, maxCnt)
    w = [];
    for i = 1 : maxCnt
        mat1 = mat(:,:,i);
        [x, y] = size(mat1);
        mat2 = mat1';
        mat3 = reshape(mat2, 1, x * y);
        w = [w; mat3];
    end 
end

结果

  • 对4和8进行分类:
分类错误的序号为:166
分类错误的个数为:1,分类正确的个数为:199
精确度为:99.50%
  • 对1和9进行分类:
分类错误的个数为:0,分类正确的个数为:200
精确度为:100.00%
  • 对2和6进行分类:
分类错误的序号为:188
分类错误的个数为:1,分类正确的个数为:199
精确度为:99.50%

最后修改于 2022-03-31

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。