实验目的
- 了解神经网络的概念
- 掌握单层感知器人工神经网络的设计
实验内容
设计一个简单的单层感知器人工神经网络,理解并编程实现网络的学习算法,通过下面表所示的样本训练网络,最终能使用训练成熟的网络对样本数据进行分类。
实验过程
感知器及其学习举例
感知器(perceptron)最初是指仅有一个神经元的最简单的神经网络,由Frank Rosenblatt于1957年提出。这种感知器与MP模型并无本质区别,只是它已经有了学习算法。一般将感知器图示为如图11-5的形式。
感知器的激活函数通常取阶跃函数或符号函数(也可以取其它函数)。感知器的输出y与输入x之间的关系为
感知器学习算法
(1) 给权向量w赋初值,并设置一个合适的学习率hÎ(0,1];
(2) 对训练样例(xi, yi) (i=1,2,…,n):
计算yi’= f(wTxi );
计算误差e= yi-yi’;
更新权值:w= w+exi (11-13)
(3) 直到对所有训练样例都有e=0,则当前权向量w即为所求,训练结束。
否则转(2);
用下面表所示的样例数据训练一个感知器。
由样例数据知,所训练的感知器为一个二输入、单输出感知器。0首先取阶跃函数为该网络的激活函数,并令x0=-1,于是所求函数的模型为y=step(w1x1+w2x2-w0);然后置初值:w0=0.6,w1=0.4,w2=0.8;取学习率h=0.4;执行学习算法,该感知器的训练过程如表11-3所示。
可以看出,网络训练结束于第三轮,最终的权值为:w0=1, w1=0.8,w2=0.4。于是,相应的激活函数表达式就是
y = step(0.8X1+0.4X2-1) (11-14)
该函数的图像(切块)大致如图11-6所示。
由图可以看出,直线0.8X1+0.4 X2-1=0将X1-X2平面分为两部分,所以,函数
g(X1,X2)=0.8 X1+0.4X2-1
也就是X1X2平面上点集的一个分类判别函数。于是,阶跃函数y=step(0.8X1+0.4X2-1)则直接就是一个分类器;而且从效果看,这个分类器还是线性分类器。那么,一般地,函数y=step(wTxi ) 就直接构成一个n维线性分类器。
可以看到的是、如果把输入的0,1 看作逻辑真值, 则这个样本数据就是AND运算的真值表。
代码
单层感知器人工神经网络的定义:
#include<iostream>
using namespace std;
class Perceptron{
private:
double learning_rate;
double weights[3];
double x0;
double error;
public:
Perceptron(double rate){
learning_rate = rate;
weights[0] = 0.6;
weights[1] = 0.4;
weights[2] = 0.8;
x0=-1;
}
void printfw(){
cout<<"w0="<<weights[0]<<endl;
cout<<"w1="<<weights[1]<<endl;
cout<<"w2="<<weights[2]<<endl;
}
double predict(double x1,double x2){
double net = x1*weights[1] + x2*weights[2] - weights[0];
return (net>=0)?1:0;
}
double predict(double net){
return (net>=0)?1:0;
}
double train(double x1,double x2,double label){
double net = x1*weights[1] + x2*weights[2] - weights[0];
error = label-predict(net);
weights[0] += learning_rate*error*x0;
weights[1] += learning_rate*error*x1;
weights[2] += learning_rate*error*x2;
cout<<"x1\tx2\terror\tw0\tw1\tw2"<<endl;
cout<<x1<<"\t"<<x2<<"\t"<<error<<"\t"<<weights[0]<<"\t"<<weights[1]<<"\t"<<weights[2]<<"\t"<<endl;
return error;
}
};
主函数:
int main(){
double x1[] = {0,0,1,1};
double x2[] = {0,1,0,1};
double y[] = {0,0,0,1};
double error[4];
int n=4;
Perceptron perceptron(0.4);
while(1){
for (int i=0;i<n;i++){
error[i] = perceptron.train(x1[i],x2[i],y[i]);
}
if (error[0]==0&&error[1]==0&&error[2]==0&&error[3]==0){
break;
}
}
cout<<"训练完成!"<<endl;
perceptron.printfw();
double y2[4];
for (int i=0;i<n;i++){
y2[i] = perceptron.predict(x1[i],x2[i]);
if(y2[i]==0){
cout<<"第"<<i<<"组数据经过分类,属于第一类数据,为假"<<endl;
}
if(y2[i]==1){
cout<<"第"<<i<<"组数据经过分类,属于第二类数据,为真"<<endl;
}
}
return 0;
}
实验结论
在本次实验中,我们成功地实现了一个简单的单层感知器人工神经网络,通过样本训练网络,最终能够使用训练成熟的网络对实验数据进行分类。
经过训练后,我们的单层感知器网络在训练集上取得了较高的分类准确率。实验结果表明,单层感知器人工神经网络能够有效地对样本数据进行分类。