一、实 验 目 的: 

  1.  理解感知器算法原理,能实现感知器算法;
  2. 掌握机器学习算法的度量指标;
  3. 掌握最小二乘法进行参数估计基本原理;
  4. 针对特定应用场景及数据,能构建感知器模型并进行预测。

二、实 验 原 理

假设我们有一个包含n个特征的输入向量x(x1, x2, ..., xn),以及一个目标输出y(1或0,表示两个类别之一)。感知机的实验原理如下:

1. 初始化权重: 首先,我们随机初始化权重向量w(w1, w2, ..., wn)和偏置b。

2. 输入传递和加权求和:** 将输入向量x传递给感知机的输入节点,然后将每个输入与对应的权重相乘并求和,得到处理单元的输入。这可以表示为:

3. 激活函数: 将加权求和的结果z输入到激活函数中。最常见的激活函数是阶跃函数,它将处理单元的输出限制在0和1之间,表示两个类别的概率。阶跃函数的定义如下:

4. 更新权重:如果感知机对输入的分类错误,就需要调整权重以改善分类效果。假设真实输出为y,预测输出为output。误差可以定义为真实输出与预测输出之间的差异:error=y−output  然后,我们使用误差来更新权重。常见的更新规则是:

​

   其中,α是学习率,控制每次权重更新的步长。

5. 迭代训练: 重复以上步骤,直到达到停止条件,例如达到最大迭代次数或误差小于某个阈值。通过迭代训练和权重更新,感知机会逐渐调整权重,直到能够正确分类输入数据。这就是感知机的基本实验原理。需要注意的是,感知机只能处理线性可分的数据集,对于线性不可分的数据集,感知机无法收敛。

三、实  验  设  备 与  器  件

PC机、 MATLAB软件。

四、实 验 内 容 与 参 数 分 析

第 0 步:生成半月形数据

1.参数设置:首先,代码设置了一些参数,包括半月形的半径(rad)、宽度(width)和两个半月形之间的距离(dist)。此外,还设置了训练集的数量(num_tr)、测试集的数量(num_te)、样本总数(num_samp)和训练周期数(epochs)。

2.打印实验信息:代码使用fprintf函数打印了一些实验信息,包括生成的点数、半月形的半径、宽度、距离以及训练周期数。

3.生成半月形数据:代码调用了halfmoon函数来生成半月形数据。这个函数接收半月形的半径、宽度、距离以及样本总数作为输入,返回生成的数据(data)和打乱顺序后的数据(data_shuffled)。

这段代码是感知器实验的第一步,即数据生成。在这个步骤中,生成了一个半月形数据集,并对数据进行了预处理,包括打乱数据的顺序,以便在后续的训练和测试中使用。

第 1 步:初始化感知机网络

这段代码是初始化感知器的参数。

1.num_in = 2;:输入神经元的数量。在这个例子中,我有两个输入特征,所以输入神经元的数量是2。

2.b = dist/2;:偏置项。在这个例子中,偏置项被设置为两个半月形之间的距离的一半。

3.err = 0;:一个计数器,用于表示错误输出的数量。在训练开始时,它被初始化为0。

4.eta = annealing(0.9,1E-5,num_tr);:学习率参数。这里使用了模拟退火算法来动态调整学习率。模拟退火算法是一种优化算法,它会随着时间的推移逐渐降低学习率,以帮助算法收敛。

5.w = [b;zeros(num_in,1)];:初始权重。在这个例子中,权重被初始化为零,偏置项被添加到权重向量的开始。

这些参数是感知器学习算法的关键部分,它们决定了感知器如何学习和适应数据

第 2 步和第 3 步:激活和实际响应

1.开始计时:st = cputime; 这行代码记录了训练开始时的CPU时间,用于后续计算训练所需的总时间。

2.训练开始:使用fprintf函数打印出训练开始的信息。

3.训练周期:for epoch = 1:epochs, 这行代码表示训练将进行epochs次。每一次都会遍历整个训练集。

4.数据洗牌:shuffle_seq = randperm(num_tr); 和 data_shuffled_tr = data_shuffled(:,shuffle_seq); 这两行代码将训练数据随机打乱,这是防止模型过拟合的常用技巧。

5.单个样本的处理:在每个训练周期中,代码会遍历训练集中的每一个样本,并进行以下操作:

x = [1 ; data_shuffled_tr(1:2,i)];:获取输入数据。

d = data_shuffled_tr(3,i);:获取期望的输出。

y = mysign(w'*x);:计算感知器的实际输出。

ee(i) = d-y;:计算期望输出和实际输出之间的误差。

这段代码是感知器学习算法的关键部分,它决定了感知器如何根据训练数据进行学习

第 4 步:更新权重

这是权重更新的公式。它将当前的权重w加上一个根据误差和输入计算出的调整量。这个调整量是学习率eta(i)、期望输出和实际输出之间的差d-y,以及输入x的乘积。这个公式实现了感知器的学习规则,即如果一个样本被错误分类,那么就调整权重以减小这个样本的误差。

运行结果截图

五、实 验 总 结:

在实验中,成功地训练了感知器,并使用测试数据集对其进行了测试。通过可视化结果,可以看到感知器成功地对半月形数据进行了分类。这说明感知器能够有效地学习并分类数据。通过这个实验,理解了感知器的工作原理,并学习了如何使用MATLAB实现感知器。此外,还掌握了如何使用感知器进行二元分类。这个实验对理解人工神经网络的工作原理非常有帮助

实验代码:

function NN_Perceptron(dist)

% Exp 1: Rosenblatt's Perceptron

% Copyright

% Yanbo Xue

% Adaptive Systems Laboratory

% McMaster University

% yxue@soma.mcmaster.ca

% Feb. 22, 2007

close all

%%================== Step 0: Generating halfmoon data =====================

%clear;

%load data_shuffled1.mat; % shuffled data for half-moon with distance d = 1

rad    = 10;   % central radius of the half moon

width  = 6;    % width of the half moon

dist   = 1;   % distance between two half moons

num_tr = 1000; % number of training sets

num_te = 2000;  % number of testing sets

num_samp = num_tr+num_te;% number of samples

epochs = 50;

fprintf('Perceptron for Classification\n');

fprintf('_________________________________________\n');

fprintf('Generating halfmoon data ...\n');

fprintf('  ------------------------------------\n');

fprintf('  Points generated: %d\n',num_samp);

fprintf('  Halfmoon radius : %2.1f\n',rad);

fprintf('  Halfmoon width  : %2.1f\n',width);

fprintf('      Distance    : %2.1f\n',dist);

fprintf('  Number of epochs: %d\n',epochs);

fprintf('  ------------------------------------\n');

[data, data_shuffled] = halfmoon(rad,width,dist,num_samp);

%%============= Step 1: Initialization of Perceptron network ==============

num_in = 2;    % number of input neuron

b    = dist/2;  % bias

err    = 0;    % a counter to denote the number of error outputs

%eta  = 0.95; % learning rate parameter

eta = annealing(0.9,1E-5,num_tr);

w    = [b;zeros(num_in,1)];% initial weights

%%=========================== Main Loop ===================================

%% Step 2,3: activation and actual response

st = cputime;

fprintf('Training the perceptron using LMS ...\n');

fprintf('  ------------------------------------\n');

for epoch = 1:epochs,

    shuffle_seq = randperm(num_tr);

    data_shuffled_tr = data_shuffled(:,shuffle_seq);

    for i = 1:num_tr,

        x = [1 ; data_shuffled_tr(1:2,i)]; % fetching data from database

        d = data_shuffled_tr(3,i);         % fetching desired response from database

        y = mysign(w'*x);

        ee(i) = d-y;

        %% Step 4: update of weight

        w_new = w + eta(i)*(d-y)*x;

        %     if w_new == w, % Stop criteria

        %         break;

        %     end

        w = w_new;

    end

    mse(epoch) = mean(ee.^2);

end

fprintf('  Points trained : %d\n',num_tr);

fprintf('       Time cost : %4.2f seconds\n',cputime - st);

fprintf('  ------------------------------------\n');

%%=============== Plotting Learning Curve =================================

figure;

plot(mse,'k');

title('Learning curve');

xlabel('Number of epochs');ylabel('MSE');

%%================= Colormaping the figure here ===========================

%%=== In order to avoid the display problem of eps file in LaTeX. =========

figure;

hold on;

xmin = min(data_shuffled(1,:));

xmax = max(data_shuffled(1,:));

ymin = min(data_shuffled(2,:));

ymax = max(data_shuffled(2,:));

[x_b,y_b]= meshgrid(xmin:(xmax-xmin)/100:xmax,ymin:(ymax-ymin)/100:ymax);

z_b  = 0*ones(size(x_b));

%wh = waitbar(0,'Plotting testing result...');

for x1 = 1 : size(x_b,1)

    for y1 = 1 : size(x_b,2)

        input = [1; x_b(x1,y1); y_b(x1,y1)];

        z_b(x1,y1) = w'*input;

    end

        %waitbar((x1)/size(x,1),wh)

    %set(wh,'name',['Progress = ' sprintf('%2.1f',(x1)/size(x,1)*100) '%']);

end

 [a b]=size(w')

         [a1 b1]=size(input)

%% Adding colormap to the final figure

%figure;

sp = pcolor(x_b,y_b,z_b);

% load red_black_colmap;

%colormap(myhot_light);

% colormap(red_black);

shading flat;

%%============================== Testing ==================================

fprintf('Testing the perceptron using LMS ...\n');

for i = 1 : num_te,

%for i = num_tr+1:num_samp,

    x = [1 ; data_shuffled(1:2,i+num_tr)]; % fetching data for testing

    y(i) = mysign(w'*x);

    %y(i) = w'*x;

    if y(i) == 1 ,

        plot(x(2),x(3),'rx');

    end

    if y(i) == -1,

        plot(x(2),x(3),'k+');

    end

end

xlabel('x');ylabel('y');

title(['Classification using Perceptron with dist = ',num2str(dist), ...

       ', radius = ', num2str(rad), ' and width = ',num2str(width)]);

fprintf('Mission accomplished!\n');

% Calculate testing error rate

for i = 1:num_te,

    if abs(y(i) - data_shuffled(3,i+num_tr)) > 1E-6,

        err = err + 1;

    end

end

fprintf('  ------------------------------------\n');

fprintf('   Points tested : %d\n',num_te);

fprintf('    Error points : %d (%5.2f%%)\n',err,(err/num_te)*100);

fprintf('  ------------------------------------\n');

fprintf('_________________________________________\n');

%%======================= Plot decision boundary ==========================

set(gca,'XLim',[xmin xmax],'YLim',[ymin ymax]);

%% Adding contour to show the boundary

contour(x_b,y_b,z_b,[0 0],'k','Linewidth',1);

%contour(x_b,y_b,z_b,[-1 -1],'k:','Linewidth',2);

%contour(x_b,y_b,z_b,[1 1],'k:','Linewidth',2);

set(gca,'XLim',[xmin xmax],'YLim',[ymin ymax]);

grid on;

%% That's all, folks

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐