人工神经网络作业-单层感知器

合集下载

单层感知机模型和原理

单层感知机模型和原理

单层感知机模型和原理
在人工智能领域,感知机是一种最简单的神经网络模型,它由一层神经元组成,被称为单层感知机。

单层感知机模型的提出是由美国心理学家弗兰克·罗森布拉特在20世纪50年代提出的,它被认为是神经网络和机器学习领域的开山之作。

单层感知机模型的原理基于生物神经元的工作原理。

每个神经元接收来自其他神经元的输入信号,并通过一个激活函数处理这些输入,然后产生一个输出。

在单层感知机中,输入信号被赋予不同的权重,然后通过加权求和的方式得到输出。

如果这个输出超过了一个阈值,神经元就会被激活,否则它就保持不激活状态。

单层感知机模型的学习过程就是通过调整权重和阈值,使得神经元能够正确地对输入进行分类。

这个过程就是通过监督学习算法来完成的,最著名的就是罗森布拉特提出的感知机学习规则。

简单来说,就是当感知机对输入进行分类错误时,就调整权重和阈值,直到它能够正确地分类所有的输入。

然而,单层感知机模型存在一个严重的局限性,即它只能解决线性可分问题。

也就是说,如果输入数据不是线性可分的,单层感
知机就无法正确地对其进行分类。

这个问题在当时成为了人工智能领域的一个难题,直到后来出现了多层感知机模型和更加复杂的神经网络模型才得以解决。

总的来说,单层感知机模型虽然简单,但它为神经网络和机器学习的发展奠定了基础。

它的原理和学习规则为后来更加复杂的神经网络模型提供了重要的思想基础,因此在人工智能领域仍具有重要的意义。

单层感知器算法及其训练过程探究

单层感知器算法及其训练过程探究

单层感知器算法及其训练过程探究随着人工智能和机器学习技术的发展,单层感知器算法因为其简单和易于理解的特点成为了很多人学习和掌握机器学习初步知识的入门之路。

本文将介绍单层感知器算法及其训练过程探究。

一、单层感知器算法单层感知器是一种线性分类模型,也是神经网络的一种。

它通过一些列数值计算和激活函数的运用,将输入的向量映射到某个输出的标签值,用于相应的分类任务中。

单层感知器算法的基本流程是:输入向量 x 经过线性函数运算 h(x) = w*x+b 之后,再经过激活函数 g(h(x)) ,得到分类的输出 y。

其中,w 是权重,b 是偏差量。

在训练过程中,单层感知器通过反向传播算法对权重和偏差量进行不断调整,从而不断提高分类准确率。

二、单层感知器的训练过程单层感知器的训练过程可以分为以下几步:1. 准备数据准备数据是机器学习的第一步,也是单层感知器训练的必要条件。

通常,我们需要用一些已经标记好标签的数据集,输入向量 x 和对应的标签 y,作为算法的训练数据集。

2. 初始化权重和偏差量在开始训练之前,需要初始化权重 w 和偏差量 b。

通常,我们可以使用随机的小数值来初始化它们。

3. 计算误差并更新参数单层感知器的权重和偏差量通过随机初始化后,就可以开始输入训练集数据,并对其进行分类。

如果分类结果与真实标签不一致,则需要通过误差计算来调整权重和偏差。

通常,我们可以使用代价函数作为误差计算的准则,常见的代价函数有均方误差MSE 和交叉熵 CE. 通过代价函数计算出误差值,再通过反向传播算法对权重和偏差量进行更新,不断调整,直到误差值最小化。

4. 不断迭代在更新了权重和偏差量之后,需要再次用训练集测试,并根据误差值调整权重和偏差,直到误差值达到预设精度或者达到最大迭代次数停止。

三、总结单层感知器算法作为神经网络中的一种基本算法,其训练过程简单,易于理解,对于初学者来说是一种入门机器学习和神经网络的良好途径。

总之,单层感知器是机器学习和深度学习的起点,学习它可以让我们更好地理解更复杂的神经网络和机器学习算法,为未来更高级的研究打下坚实的基础。

感知器神经网络

感知器神经网络

感知器神经网络感知器是一种前馈人工神经网络,是人工神经网络中的一种典型结构。

感知器具有分层结构,信息从输入层进入网络,逐层向前传递至输出层。

根据感知器神经元变换函数、隐层数以及权值调整规则的不同,可以形成具有各种功能特点的人工神经网络。

本节将介绍单层感知器和多层感知器的工作原理。

5.3.1单层感知器1958年,美国心理学家Frank Rosenblatt 提出一种具有单层计算单元的神经网络,称为Perceptron ,即感知器。

感知器是模拟人的视觉接受环境信息,并由神经冲动进行信息传递的层次型神经网络。

感知器研究中首次提出了自组织、自学习的思想,而且对所能解决的问题存在着收敛算法,并能从数学上严格证明,因而对神经网络研究起了重要推动作用。

单层感知器的结构与功能都非常简单,以至于在解决实际问题时很少采用,但由于它在神经网络研究中具有重要意义,是研究其它网络的基础,而且较易学习和理解,适合于作为学习神经网络的起点。

1.感知器模型单层感知器是指只有一层处理单元的感知器,如果包括输入层在内,应为两层,如图5-14所示。

图中输入层也称为感知层,有n 个神经元节点,这些节点只负责引入外部信息,自身无信息处理能力,每个节点接收一个输入信号,n 个输入信号构成输入列向量X 。

输出层也称为处理层,有m 个神经元节点,每个节点均具有信息处理能力,m 个节点向外部输出处理信息,构成输出列向量O 。

两层之间的连接权值用权值列向量Wj 表示,m 个权向量构成单层感知器的权值矩阵W 。

3个列向量分别表示为:()()()121212,,,,,,,,,,,,,,,,1,2,,T i n Ti n Tj j j ij nj X x x x x O o o o o W w w w w j m====图5-14单层感知器对于处理层中任一节点,由第二节介绍的神经元数学模型知,其净输入j net '为来自输入层各节点的输入加权和∑==ni i ij j x w net 1'(5-26)输出o j 为节点净输入与阈值之差的函数,离散型单计算层感知器的转移函数一般采用符号函数。

人工神经网络——感知机

人工神经网络——感知机

所以当采用感知器对不同的输入矢 量进行期望输出为0或1的分类时,其问 题可转化为:对于已知输入矢量在输入 空间形成的不同点的位置,设计感知器 的权值W和b,将由W*P+b=0的直线 放置在适当的位置上使输入矢量按期望 输出值进行上下分类。
输入矢量平面图
举例:用感知机实现“与”的功能
w的解并不唯一,能把两类分开即可 由于网络是以w1x1+w2x2+……+θ=0为分界线的, 这可以看成一直线或一超平面。
d X 1 x1 2 x2
y
1
θ
2
x1
d X 1
x2
d X

x



样本集分别属于2类。

d X 1
1 特点: 1)多输入,单输出 2)激活函数/传递函数为二值,一般为阶跃函 数或符号函数 3)输出为二值:0/1或-1/1
n 4) y f i xi i 1
人工神经元模型,如图所示
感知机是最早被设计并被实现的人工神网络。感知 器是一种非常特殊的神经网络,它在人工神经网络 的发展历史上有着非常重要的地位,尽管它的能力 非常有限,主要用于线性分类。
x1 1

xn
n

θ

yj
yj
某个神经元 j 的输入—输出关系为
s j ji xi j
输入矢量P,输出矢量Y,目标矢量为 T的感知器网络,其学习规则为:
如果第i个神经元的输出是正确的, 即有:yi=ti,那么与第i个神经元 联接的权值wij和偏差值bi保持不变;
如果第i个神经元的输出是0,但 期望输出为1,即有yi=0,而ti =1,此时权值修正算法为:新 的权值wij为旧的权值wij加上输 入矢量pj;类似的,新的偏差bi 为旧偏差bi加上它的输入1;

单层感知器 激发函数

单层感知器 激发函数

单层感知器激发函数单层感知器是一种人工神经元网络模型,它是神经网络的一种最简单形式。

在单层感知器中,激发函数(activation function)是至关重要的组成部分。

激发函数定义了神经元的输出值,它的作用是对输入值进行加权求和并经过某个非线性变换,最终产生非线性的输出。

激发函数在单层感知器中起到将连续的输入转化为离散输出的作用。

常见的激发函数有线性激发函数(Linear Activation Function)、阶跃激发函数(Step Activation Function)、Sigmoid激发函数(Sigmoid Activation Function)等。

在单层感知器中,最常用的激发函数是阶跃激发函数和Sigmoid激发函数。

阶跃激发函数是一个简单的二进制函数,将输入映射为0或1。

它的定义如下:如果输入大于等于0,则输出为1;如果输入小于0,则输出为0。

阶跃函数的输出是离散的二进制值,它适用于处理离散的输出问题。

Sigmoid激发函数则将连续的输入映射到0和1之间,它的定义如下:输出等于1除以1加上e的负指数的输入的指数;其中e是自然对数的底数。

Sigmoid激发函数的输出是连续的、非线性的值,它适用于处理连续的输出问题。

由于其输出在0和1之间,Sigmoid激发函数常用于神经网络中的二分类问题。

激发函数在单层感知器中的作用是实现对输入值的非线性变换,使得单层感知器也能够处理非线性的输入和输出。

激发函数的选择取决于具体的任务需求和数据特征。

除了阶跃激活函数和Sigmoid激活函数,还有其他激活函数常用于深度神经网络中,例如ReLU激活函数、Leaky ReLU激活函数、Tanh激活函数等。

这些激活函数可以更好地处理复杂的非线性关系。

总结起来,单层感知器是一种最简单的神经网络模型,激发函数是其重要的组成部分。

激发函数通过对输入值进行非线性变换,实现了对非线性输入和输出的处理。

常见的激发函数包括阶跃激活函数和Sigmoid激活函数,根据具体任务需求和数据特征,选择合适的激发函数可以更好地实现神经网络的功能。

简述单层感知器与多层感知器的具体内容

简述单层感知器与多层感知器的具体内容

单层感知器与多层感知器是人工智能领域中常用的两种神经网络模型。

它们分别具有不同的结构和功能,应用范围也有所不同。

下面将分别对单层感知器和多层感知器的具体内容进行简述。

一、单层感知器的具体内容1. 结构单层感知器是由输入层和输出层构成的,输入层接收外部输入信号,并将信号通过神经元进行加权求和处理,然后传递给输出层。

输出层对输入信号进行阈值判定,输出0或1的二元信号。

2. 功能单层感知器主要用于解决线性可分问题,即可以通过在二维平面上找到一条直线将两类样本完全分开的问题。

由于单层感知器只具有简单的线性分类功能,因此在处理复杂的非线性问题时表现较差。

3. 应用单层感知器常被用于简单的逻辑运算、线性分类等问题。

使用单层感知器可以实现与门、或门、非门等基本逻辑运算,也可以用于简单的模式识别和分类任务。

二、多层感知器的具体内容1. 结构多层感知器由输入层、隐藏层和输出层构成。

隐藏层可以包含多个神经元,并且隐藏层与输出层之间存在多个连接。

隐藏层可以对输入信号进行非线性变换,从而使多层感知器具有较强的非线性建模能力。

2. 功能多层感知器通过对输入信号的多次非线性变换和权值调整,可以逼近任意复杂的非线性函数。

这使得多层感知器在处理复杂的模式识别、分类和回归等问题时具有很强的表达能力和建模能力。

3. 应用多层感知器在人工智能领域中被广泛应用,包括图像识别、语音识别、自然语言处理、游戏智能等方面。

深度学习模型中的卷积神经网络(CNN)和循环神经网络(RNN)就是基于多层感知器设计和构建的。

总结:单层感知器和多层感知器分别具有不同的结构和功能,应用范围也有所不同。

单层感知器主要用于解决线性可分问题,而多层感知器则适用于解决复杂的非线性问题。

随着人工智能领域的不断发展,多层感知器将在更多领域展现出其强大的建模能力和应用价值。

多层感知器(MLP)的结构之所以能够处理复杂的非线性问题,主要得益于其隐藏层的非线性变换和权值调整能力。

第三章 单层感知器

第三章 单层感知器

10
• Uses a non-linear (McCulloch-Pitts) model of neuron: b (bias)
x1
x2 xn w1 w2 wn v
(v)
y
• is the sign function: (v) =
+1
-1
IF v >= 0
Is the function sign(v) IF v < 0
28
异或(Exclusive –OR)问题
g( x, y)
y
0
x 0 1 0 1
1
1 0
29
+ 用多个单级网组合在一起,并用其中的一
个去综合其它单级网的结果 + 解决好隐藏层的联接权的调整问题是非常 关键的
30
Classification: 将样本
集合正确分类到两类 中:C1, C2:
Perceptron的输出为 +1, 输入向量被分配到类C1 输出为 -1,则分配到类 C2 只能处理线形可分离的情 况
2
+ 结合了神经生理学和数理逻辑的研究
描述了一个神经网络的逻辑运算 + 其神经元模型假定遵循一种有或无 (all-or-none)规则 + 如果神经元数目足够多,适当设置突 触连接,并且同步操作,原则上可以 计算任何可计算函数 + 标志着神经网络和人工智能科学的诞 生
3
x1
w
x2

w w -p
o
19
+ 样本集:{(X,Y)|Y为输入向量X对应的输出} + 输入向量:X=(x1,x2,…,xn) + 理想输出向量:Y=(y1,y2,…,ym) + 激活函数:F + 权矩阵W=(wij) + 实际输出向量:O=(o1,o2,…,om)

单层感知器

单层感知器
2
i
y
f
... ...
xN
N
输入 x(n) 1, x1(n), x2(n),L , xN (n)T
权值 ω(n) b(n),1(n),2(n),L ,N (n)T
N
v(n) i xi ωT (n)x(n) i0
2.单层感知器的学习算法
(1)定义变量和参数。X为输入,y为实际输出,d为 期望输出,b为偏置,w为权值。
➢ 粗准焦螺旋 和细准焦螺旋的类比。——自适应 学习率。
3.感知器的局限性
单层感知器无法解决线性不可分问题, 只能做近似分类。 感知器的激活函数使用阈值函数,输出值只有 两种取值,限制了在分类种类上的扩展 。 如果输入样本存在奇异样本,网络需要花费很 长的时间。 感知器的学习算法只对单层有效 。
4.单层感知器相关函数详解
>> T=[0,0,0,0,0,1,1,1,1,1] % 训练输出,负数输出0,非负数输出1
>> net=train(net,P,T);
>> newP=-10:.2:10;
% 测试输入
>> newT=sim(net,newP);
>> plot(newP,newT,'LineWidth',3);
>> title('判断数字符号的感知器');
3, 0 x1
l2类 4, 1
向量 ω 2, 3
二维空间中的超平面是一条
直线。在直线下方的点,输
出-1;在直线上方的点,输
出1。分类面:
1x1 2 x2 b 0
2.单层感知器的学习算法
在实际应用中 ,通常采用纠错学习规则的学习算法。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

3.5单层感知器# include <stdio.h># include <math.h># define N 100int sgn(double x) //符号运算函数{int y;if(x>0||x==0)y=1;elsey=-1;return y;}void main(){double W[4]={0.0,0.0,0.0,0.0},X[6][4]={{-1,0.8,0.5,0},{-1,0.9,0.7,0.3},{-1,1,0.8,0.5}, {-1,0,0.2,0.3},{-1,0.2,0.1,1.3},{-1,0.2,0.7,0.8}};int err,o[6],i,j,k,num,d[6]={1,1,1,-1,-1,-1};double n,WX;n=1.0;k=0;do {k++;num=0;for(i=0;i<6;i++){WX=0.0;for(j=0;j<4;j++)WX=WX+W[j]*X[i][j];o[i]=sgn(WX);err=d[i]-o[i];for(j=0;j<4;j++)W[j]=W[j]+n*err*X[i][j];if(err==0)num++;}}while(num!=6);printf("调整后的权值矩阵为:\n");for(j=0;j<4;j++)printf("%f\n",W[j]);printf("分类结果为:\n");for(i=0;i<6;i++)printf("%d\n",o[i]);}3.6单次训练的结果# include <stdio.h># include <math.h>double Sig(double x) //单极性函数{double y;y=1.0/(1.0+exp(-x));return y;}void main(){doublex[3]={-1,1,3},V[3][3]={{0,3,-1},{0,1,2},{0,-2,0}},W[3][3]={{0,2,3},{0,1,1},{0,0,-2}};double d[3]={0,0.95,0.05},nety[3],neto[3],Y[3],O[3],dety[3],deto[3];double D,yita;int i,j;yita=1.0;FILE *fp;fp=fopen("out.txt","w");fprintf(fp,"初始W矩阵:\n");for(i=0;i<3;i++){for(j=1;j<3;j++)fprintf(fp,"%f ",W[i][j]);fprintf(fp,"\n");}fprintf(fp,"初始V矩阵:\n");for(i=0;i<3;i++){for(j=1;j<3;j++)fprintf(fp,"%f ",V[i][j]);fprintf(fp,"\n");}//计算隐层的输出fprintf(fp,"隐层的净输入:\n");for(j=1;j<3;j++){nety[j]=0.0;for(i=0;i<3;i++)nety[j]=nety[j]+V[i][j]*x[i];fprintf(fp,"%f\t",nety[j]);}fprintf(fp,"\n");Y[0]=-1.0;fprintf(fp,"隐层的输出:\n");for(i=1;i<3;i++)Y[i]=Sig(nety[i]);for(j=1;j<3;j++)fprintf(fp,"%f\t",Y[j]);fprintf(fp,"\n");//计算输出层的输出fprintf(fp,"输出层的净输入:\n");for(j=1;j<3;j++){neto[j]=0.0;for(i=0;i<3;i++)neto[j]=neto[j]+W[i][j]*Y[i];fprintf(fp,"%f\t",neto[j]);}fprintf(fp,"\n");fprintf(fp,"输出层的输出:\n");for(i=1;i<3;i++)O[i]=Sig(neto[i]);for(j=1;j<3;j++)fprintf(fp,"%f\t",O[j]);fprintf(fp,"\n");//计算导数fprintf(fp,"隐层输出的一阶导数:\n");for(i=1;i<3;i++)fprintf(fp,"%f\t",Sig(nety[i])*(1.0-Sig(nety[i])));fprintf(fp,"\n");fprintf(fp,"输出层输出的一阶导数:\n");for(i=1;i<3;i++)fprintf(fp,"%f\t",Sig(neto[i])*(1.0-Sig(neto[i])));//计算输出层误差fprintf(fp,"\n输出层误差:\n");for(i=1;i<3;i++){deto[i]=(d[i]-O[i])*O[i]*(1.0-O[i]);fprintf(fp,"%f\t",deto[i]);}fprintf(fp,"\n隐层误差:\n");//计算隐层误差for(i=1;i<3;i++){D=0.0;for(j=1;j<3;j++)D=D+deto[j]*W[i][j];dety[i]=D*Y[i]*(1.0-Y[i]);fprintf(fp,"%f\t",dety[i]);}fprintf(fp,"\n");//调整W矩阵for(i=1;i<3;i++){for(j=0;j<3;j++)W[j][i]=W[j][i]+yita*deto[i]*Y[j];}//调整V矩阵for(i=1;i<3;i++){for(j=0;j<3;j++)V[j][i]=V[j][i]+yita*dety[i]*x[j];}//输出调整一次后的权值矩阵fprintf(fp,"调整一次后的W矩阵:\n");for(i=0;i<3;i++){for(j=1;j<3;j++)fprintf(fp,"%f ",W[i][j]);fprintf(fp,"\n");}fprintf(fp,"调整一次后的V矩阵:\n");for(i=0;i<3;i++){for(j=1;j<3;j++)fprintf(fp,"%f ",V[i][j]);fprintf(fp,"\n");}本程序的输出为输出到文本文件中,结果如下:初始W矩阵:2.0000003.0000001.000000 1.0000000.000000 -2.000000初始V矩阵:3.000000 -1.0000001.0000002.000000-2.000000 0.000000隐层的净输入:-8.000000 3.000000隐层的输出:0.000335 0.952574输出层的净输入:-1.999665 -4.904813输出层的输出:0.119238 0.007356隐层输出的一阶导数:0.000335 0.045177输出层输出的一阶导数:0.105020 0.007302输出层误差:0.087247 0.000311隐层误差:0.000029 -0.000028调整一次后的W矩阵:1.9127532.9996891.000029 1.0000000.083109 -1.999703调整一次后的V矩阵:2.999971 -0.9999721.000029 1.999972-1.999912 -0.0000843.7 批训练BP算法# include <stdio.h>#include<time.h># include <math.h># include <stdlib.h># define N 100# define NUM 1e5 //循环最大次数int IN,HN,ON; //IN为输入层节点数,HN为隐层节点数,ON为输出层节点数double Sig(double x) //单极性函数double y;y=1.0/(1.0+exp(-x));return y;}double DSig(double x) //双极性函数{double y;y=(1.0-exp(-x))/(1.0+exp(-x));return y;}void main(){float x[N][N],V[N][N],W[N][N];float d[N][N],nety[N],neto[N],Y[N],O[N][N],dety[N],deto[N];float D,E,Ep,Emin;float yita;int i,j,k,choose,p,yb;//p用于计数,看样本是否输入完毕,choose用于选择单极性、双极性函数k=0;Emin=1e-5;//输入各层节点数和学习率printf("请输入输入层节点数IN=");scanf("%d",&IN);printf("请输入隐层节点数HN=");scanf("%d",&HN);printf("请输入输出层节点数ON=");scanf("%d",&ON);printf("请输入学习率yita=");scanf("%f",&yita);printf("请输入函数选择参数choose,1代表单极性,2代表双极性:");scanf("%d",&choose);printf("请输入样本总数yb=");scanf("%d",&yb);printf("输入样本(第一个为-1):\n");for(j=0;j<yb;j++)for(i=0;i<=IN;i++)scanf("%f",&x[j][i]);printf("输入期望输出值(在期望值前加0):\n");for(j=0;j<yb;j++)for(i=0;i<=ON;i++)scanf("%f",&d[j][i]);printf("\n");//初始化权值矩阵,取-1到1的随机数for(i=0;i<=IN;i++)for(j=0;j<=HN;j++){srand((unsigned)time(NULL));V[i][j]=(double)((rand()/32767.0)*2-1);}for(i=0;i<=HN;i++)for(j=0;j<=ON;j++){srand((unsigned)time(NULL));W[i][j]=(double)((rand()/32767.0)*2-1);}do{p=0;E=0.0;while(p<yb){/**************************计算隐层的输出*****************************/ for(j=1;j<=HN;j++){nety[j]=0.0;for(i=0;i<=IN;i++)nety[j]=nety[j]+V[i][j]*x[p][i];}Y[0]=-1.0;for(i=1;i<=HN;i++){if(choose==1)Y[i]=Sig(nety[i]);else if(choose==2)Y[i]=DSig(nety[i]);}/*************************计算输出层的输出*****************************/ for(j=1;j<=ON;j++){neto[j]=0.0;for(i=0;i<=HN;i++)neto[j]=neto[j]+W[i][j]*Y[i];}for(i=1;i<=ON;i++){if(choose==1)O[p][i]=Sig(neto[i]);else if(choose==2)O[p][i]=DSig(neto[i]);}/************************求样本的误差累计******************************/ for(i=1;i<=ON;i++)E=E+(d[p][i]-O[p][i])*(d[p][i]-O[p][i]);p++;}Ep=E/2.0;//sqrt(E);/************************计算输出层误差********************************/ for(i=1;i<=ON;i++){if(choose==1)deto[i]=(d[p][i]-O[p][i])*O[p][i]*(1.0-O[p][i]);else if(choose==2)deto[i]=(d[p][i]-O[p][i])*0.5*(1.0-O[p][i]*O[p][i]);}/*************************计算隐层误差*********************************/ for(i=1;i<=HN;i++){D=0.0;for(j=1;j<=ON;j++)D=D+deto[j]*W[i][j];if(choose==1)dety[i]=D*Y[i]*(1.0-Y[i]);else if(choose==2)dety[i]=D*0.5*(1.0-Y[i]*Y[i]);}/***************************调整输出层权值矩阵W*************************/ for(i=1;i<=ON;i++){for(j=0;j<=HN;j++)W[j][i]=W[j][i]+yita*deto[i]*Y[j];}/****************************调整隐层权值矩阵V**************************/ for(i=1;i<=HN;i++){for(j=0;j<=IN;j++)V[j][i]=V[j][i]+yita*dety[i]*x[p][j];}k++;printf("%d\n",k);if(k>NUM){printf("到达最大循环次数");break;}}while(Ep>Emin);//输出结果,验证for(p=0;p<yb;p++){for(i=1;i<=ON;i++)printf("%f\t",O[p][i]);printf("\n");}for(i=1;i<=ON;i++)printf("%f\t",deto[i]);printf("\n");//输出误差printf("%f\tEp=%f\n",E,Ep);//输出调整后的权值矩阵for(i=0;i<=HN;i++){for(j=0;j<=ON;j++)printf("%f ",W[i][j]);printf("\n");}for(i=0;i<=IN;i++){for(j=0;j<=HN;j++)printf("%f ",V[i][j]);printf("\n");}}3.8 字符分类(标准BP算法):# include <stdio.h># include <math.h>#include<time.h># include <stdlib.h># define N 100# define NUM 1e6 //循环最大次数int IN,HN,ON; //IN为输入层节点数,HN为隐层节点数,ON为输出层节点数float Sig(float x) //双极性函数{float y;y=(1.0-exp(-x))/(1.0+exp(-x));return y;}void main(){float x[N][N]={{-1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,1.0},{-1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},{-1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1}},V[N][N],W[N][N];// floatd[N][N]={{0.0,1.0,-1.0,-1.0},{0.0,-1.0,1.0,-1.0},{0.0,-1.0,-1.0,1.0}},nety[N],neto[N],Y[N],O[N][ N],dety[N],deto[N];//float D,E,Ep,Emin;float yita;int i,j,p,yb;//p用于计数,看样本是否输入完毕long int k;k=0;Emin=0.001;IN=16;ON=3;/******************输入隐层节点数和学习率***********************/printf("请输入隐层节点数HN=");scanf("%d",&HN);printf("请输入学习率yita=");scanf("%f",&yita);printf("请输入样本总数yb=");scanf("%d",&yb);/**************初始化权值矩阵,取-1到1的随机数******************/for(i=0;i<=IN;i++)for(j=0;j<=HN;j++){srand((unsigned)time(NULL));V[i][j]=(double)((rand()/32767.0)*2-1);}for(i=0;i<=HN;i++)for(j=0;j<=ON;j++){srand((unsigned)time(NULL));W[i][j]=(double)((rand()/32767.0)*2-1);}while(k<NUM){p=0;k++;while(p<yb){E=0.0;/**************************计算隐层的输出*****************************/ for(j=1;j<=HN;j++){nety[j]=0.0;for(i=0;i<=IN;i++)nety[j]=nety[j]+V[i][j]*x[p][i];}Y[0]=-1.0;for(i=1;i<=HN;i++)Y[i]=Sig(nety[i]);/*************************计算输出层的输出*****************************/ for(j=1;j<=ON;j++){neto[j]=0.0;for(i=0;i<=HN;i++)neto[j]=neto[j]+W[i][j]*Y[i];}for(i=1;i<=ON;i++)O[p][i]=Sig(neto[i]);/************************求样本的误差累计******************************/ for(i=1;i<=ON;i++)E=E+(d[p][i]-O[p][i])*(d[p][i]-O[p][i]);Ep=sqrt(E);/************************计算输出层误差********************************/ for(i=1;i<=ON;i++)deto[i]=(d[p][i]-O[p][i])*0.5*(1.0-O[p][i]*O[p][i]);/*************************计算隐层误差*********************************/ for(i=1;i<=HN;i++){D=0.0;for(j=1;j<=ON;j++)D=D+deto[j]*W[i][j];dety[i]=D*0.5*(1.0-Y[i]*Y[i]);}/***************************调整输出层权值矩阵W*************************/ for(i=1;i<=ON;i++){for(j=0;j<=HN;j++)W[j][i]=W[j][i]+yita*deto[i]*Y[j];}/****************************调整隐层权值矩阵V**************************/ for(i=1;i<=HN;i++){for(j=0;j<=IN;j++)V[j][i]=V[j][i]+yita*dety[i]*x[p][j];}// printf("%d\n",k);p++;}if(Ep<Emin)break;}//输出结果,验证printf("分类输出结果为:\n");for(p=0;p<yb;p++){for(i=1;i<=ON;i++)printf("%f\t",O[p][i]);printf("\n");}//输出误差printf("Ep=%f\n",E,Ep);printf("运行次数:%d\n",k);}运行结果:《选取不同的隐节点,观察运行结果》隐节点为5时隐节点为6时隐节点为7时隐节点为8时隐节点为9时隐节点为10时隐节点为11时隐节点为12时隐节点为13时3.11函数逼近# include<stdio.h># include<math.h># include <stdlib.h>#include<time.h># define NUM 200# define N 110# define e 1e-10# define pi 3.14159double F(double x){double y;y=1.1*(1-x+2*x*x)*exp(-x*x/2);return y;}double Sig(double x) //单极性函数{double y;y=1.0/(1.0+exp(-x));return y;}double zaosh(){double y;y=(double)(rand()/32767.0/10.0);return y;}void main(){double x[N],o[N],y[N],d[N],dd[N];int i,j,P,p,k=1,HN;double w[N],v[N][N],Do,Dy[N],nety[N],neto,dnety[N],dneto;double yita,E,Ez=0,t,Emin;P=100;FILE *fp;fp=fopen("out.txt","w");if(fopen==NULL){printf("Error!");exit(0);}for(i=1;i<=P;i++)x[i]=-4.0+(i-1)*8.0/(P-1);for(i=1;i<=P;i++){srand((unsigned)time(NULL));d[i]=F(x[i]);dd[i]=d[i]+zaosh();}yita=1.0;HN=80;//printf("输入隐层节点数:\n");// scanf("%d",&HN);//初始化权值矩阵for(j=1;j<=HN;j++){v[0][j]=0;v[1][j]=0;}for(j=0;j<=HN;j++){w[j]=0;}y[0]=-1,x[0]=-1;do{t=0;Ez=0;for(p=1;p<=P;p++){E=0;for(j=1;j<=HN;j++){nety[j]=v[0][j]*x[0]+v[1][j]*x[p];y[j]=Sig(nety[j]);dnety[j]=y[j]*(1-y[j]);}neto=0;for(j=0;j<=HN;j++){neto=neto+w[j]*y[j];}o[p]=neto;dneto=1;E=dd[p]-o[p];Ez=Ez+E;t=t+E*E;Do=(dd[p]-o[p])*dneto; //计算输出层误差for(j=1;j<=HN;j++) //计算隐层误差Dy[j]=Do*w[j]*dnety[j];/*********调整权值矩阵w************/for(j=0;j<=HN;j++)w[j]=w[j]+yita*Do*y[j];/*********调整权值矩阵v************/for(j=1;j<=HN;j++){v[0][j]=v[0][j]+yita*Dy[j]*x[0];v[1][j]=v[1][j]+yita*Dy[j]*x[p];}}Emin=sqrt(t);Ez=Ez/P;k++;if(k>NUM)break;}while(Ez>e||Emin>0.1);printf("%d\n",k);printf("%f\t%f\n",Ez,Emin);for(p=1;p<=P;p++)fprintf(fp,"%f\t%f\t%f\t%f\n",x[p],d[p],o[p],dd[p]);}结果如下图所示,B代表的是函数的真值,C代表的是网路计算值,D代表的是加噪声后的函数输出值:Y A x i s T i t l eX Axis Title。

相关文档
最新文档