入门机器学习之——感知机实验
一、实 验 目 的:
- 理解感知器算法原理,能实现感知器算法;
- 掌握机器学习算法的度量指标;
- 掌握最小二乘法进行参数估计基本原理;
- 针对特定应用场景及数据,能构建感知器模型并进行预测。
二、实 验 原 理
假设我们有一个包含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
更多推荐



所有评论(0)