bp神经网络详细步骤C实现
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
e+=(yd[k]-x2[k])*(yd[k]-x2[k]);
//更新V,V矩阵是隐藏层与输出层之间的权值for(intj=0;j<hideNum;j++)
{
v[j,k]+=rate*qq[k]*x1[j];
}
}
//计算隐层误差
for(intj=0;j<hideNum;j++)
{
//PP矩阵是隐藏层的误差
{
//★数据归一化
for(inti=0;i<inNum;i++)
{
x[i]=p[isamp,i]/in_rate;
}
for(inti=0;i<outNum;i++)
{
yd[i]=t[isamp,i]/in_rate;
}
//计算隐层的输入和输出
for(intj=0;j<hideNum;j++)
{
o1[j]=0.0;
{
w[i]+=dw[i];
}
}
//数据仿真函数
publicdouble[]sim(double[]psim)
{
for(i nti=O;i<i nN um;i++)
x[i]=psim[i]/in_rate;//in_rate为归一化系数
for(i ntj=O;j<hideNum;j++)
{
o1[j]=0.0;
{pMax=Math.Abs(p[isamp,i]);
}
}for(intj=0;j<outNum;j++)
{if(Math.Abs(t[isamp,j])>pMax)
{pMax=Math.Abs(t[isamp,j]);
}
}
in_rate=pMax;
}//endisamp for(intisamp=0;isamp<sampleNum;isamp++)
e=0.0;
//★求p,t中的最大值doublepMax=0.0;
//sampleNum为样本总数for(intisamp=0;isamp<sampleNum;isamp++){
//inNum是输入层的节点数(即神经细胞数)for(inti=0;i<inNum;i++)
{if(Math.Abs(p[isamp,i])>pMax)
}
}
〃初始化v
for(i nti=0;i<hideNum;i++)
{
for(i ntj=0;j<outNum;j++)
{
v[i,j]=(R.NextDouble()*2-1.0)/2;
}
}
rate=0.8;
e=0.0;
in_rate=1.0;?
}
//训练函数publicvoidtra in( double[,]p,double[,]t)
o2[k]=o2[k]+v[j,k]*x1[j];
x2[k]=1.0/(1.0+Math.Exp( -o2[k] -b2[k]));
x2[k]=in_rate*x2[k];
}?
returnx2;
}//en dsim
〃保存矩阵w,v
publicvoidsaveMatrix(double[,]w,stri ngfile name)
publicclassBpNet
public in ti nN um;〃输入节点数
inthideNum;//隐层节点数
publicintoutNum;//输出层节点数
publicintsampleNum;//样本总数
Ran domR;
double[]x;〃输入节点的输入数据
double[]x1;〃隐层节点的输出
dv=n ewdouble[hideNum,outNum];
//阈值
b1= newdouble[hideNum];
b2=n ewdouble[outNum];
db1= newdouble[hideNum];
db2=n ewdouble[outNum];
//误差
pp=newdouble[hideNum];〃隐藏层的误差
{
o2[k]=0.0;
for(intj=0;j<hideNum;j++)
{
o2[k]+=v[j,k]*x1[j];
}x2[k]=1.0/(1.0+Math.Exp(-o2[k]-b2[k]));
}
//计算输出层误差和均方差
{
//yd[k]是输出层的教师数据,所谓教师数据就是实际应该输出的 数据而已
qq[k]=(yd[k]-x2[k])*x2[k]*(1.0-x2[k]);
}
i++;
}
sr.Close();
}
catch(Excepti on e)?
{
//Lettheuserk no wwhatwe ntwro ng.
Con sole.WriteLi ne("Thefilecould notberead:");
Con sole.WriteLi ne(e.Message);
Console.WriteLine(”隐层节点数目:"+hideNum);
Console.WriteLine("输出层节点数目:"+outNum);
Con sole.ReadL in e();
//将这些矩阵规定好矩阵大小
x=n ewdouble[i nNu m];
x1= newdouble[hideNum];
}
sw.Close();
}
〃保存矩阵b1,b2
publicvoidsaveMatrix(double[]b,stri ngfile name) {
StreamWritersw=File.CreateText(file name);
for(i nti=O;i<b.Le ngth;i++)
{
sw.Write(b[i]+"");
{
b2[k]+=rate*qq[k];
}
〃更新b1,隐藏层的阈值
{
b1[j]+=rate*ppj
}
}//en disamp e=Math.Sqrt(e);〃均方差〃adjustWV(w,dw);
//adjustWV(v,dv);
}//en dtrain publicvoidadjustWV(double[,]w,double[,]dw)
{
StreamWritersw=File.CreateText(file name);
for(i nti=O;i<w.GetLe ngth(O);i++)
{
for(i ntj=O;j<w.GetLe ngth(1);j++)
{
sw.Write(w[i,j]+"");
}
sw.WriteLi ne();
this.outNum=t.GetLe ngth(1);
this.hideNum=computeHideNum(i nNu m,outNum);
〃this.hideNum=18;
this.sampleNum=p.GetLe ngth(O);
Console.WriteLine("输入节点数目:"+inNum);
12"));?
Strin gli ne;
in ti=0;
while((li ne=sr.ReadLi ne())!=null)?
{
stri ng[]s1=li ne.Trim().Split('');
for(i ntj=O;j<s1.Le ngth;j++)
{
w[i,j]=Co nvert.ToDouble(s1[j]);
}
sw.Close();
}
〃读取矩阵W,V
publicvoidreadMatrixW(double[,]w,stri ngfile name)
{
StreamReadersr;
try?
{
sr=n ewStreamReader(file name,E ncodi ng.GetE ncodi ng("gb23
}
〃读取矩阵b1,b2
publicvoidreadMatrixB(double[]b,stri ngfile name)
{
StreamReadersr;
try?
{?
sr=n ewStreamReader(file name,E ncodi ng.GetE ncodi ng("gb23
12"));?
Strin gli ne;
in ti=0;?
while((li ne=sr.ReadLi ne())!=null)?
{
b[i]=Co nvert.ToDouble(li ne);
iouble[,]dv;〃权值矩阵Vpublicdoublerate;//学习率publicdouble[]b1;〃隐层阈值矩阵publicdouble[]b2;〃输出层阈值矩阵publicdouble[]db1;〃隐层阈值矩阵publicdouble[]db2;〃输出层阈值矩阵double[]pp;〃隐藏层的误差double[]qq;〃输出层的误差
{
for(i nti=O;i<w.GetLe ngth(0);i++)
{
for(i ntj=O;j<w.GetLe ngth(1);j++) {
w[i,j]+=dw[i,j];
}
}
publicvoidadjustWV(double[]w,double[]dw)
{
for(i nti=O;i<w .Len gth;i++)
usin gSystem;
usi ng;
usin gSystem.L inq;
usin gSystem.Text;
usin gSystem;
usin gSyste m.10;
usin gSystem.Text;
n amespaceBpANNet
{
〃/<summary>
///BpNet的摘要说明'
///</summary>
qq=newdouble[outNum];〃输出层的误差
yd=newdouble[outNum];〃输出层的教师数据
//初始化w
for(i nti=O;i<i nN um;i++)
{
for(i ntj=O;j<hideNum;j++)
//NextDouble返回一个介于0.0和1.0之间的随机数。
w[i,j]=(R.NextDouble()*2-1.0)/2;
for(inti=0;i<inNum;i++)
{
o1[j]+=w[i,j]*x[i];//权值”*输“入 ”的那个累加的过程
}
//这个b1[j]就是隐藏层的阈值,阈值就是一个输入为 值
x1[j]=1.0/(1.0+Math.Exp(-o1[j]-b1[j]));
}
//计算输出层的输入和输出for(intk=0;k<outNum;k++)
pp[j]=0.0;
//算法参考我的视频截图
{
pp[j]+=qq[k]*v[j,k];
}
PP[j]=PP[j]*x1[j]*(1-x1[j]);
〃更新w
for(i nti=O;i<i nN um;i++)
{
w[i,j]+=rate*pp[j]*x[i];
}
}
〃更新b2,输出层的阈值
for(i ntk=0;k<outNum;k++)
for(i nti=O;i<i nN um;i++)
o1[j]=o1[j]+w[i,j]*x[i];
x1[j]=1.0/(1.0+Math.Exp(-o1[j] -b 1[j]));
}
for(i ntk=O;k<outNum;k++)
{
o2[k]=0.0;
for(i ntj=O;j<hideNum;j++)
double[]yd;〃输出层的教师数据,所谓教师数据就是实际数据而
已!
publicdoublee;//均方误差
doublein_rate;〃归一化比例系数
//用于确定隐藏层的神经细胞数
publici ntcomputeHideNum(i ntm,i ntn)
{
doubles=Math.Sqrt(0.43*m* n+0.12* n*n+2.54*m+0.77* n+0.35)
x2=n ewdouble[outNum];
o1= newdouble[hideNum];
o2=n ewdouble[outNum];
w=newdouble[inNum,hideNum];〃权值矩阵w,这是输入层与隐
藏层之间的权值矩阵
v=n ewdouble[hideNum,outNum];
dw=n ewdouble[i nNu m,hideNum];
double[]x2;〃输出节点的输出
double[]o1;//隐层的输入
double[]o2;//输出层的输入
publicdouble[,]w;〃权值矩阵w,这是输入层与隐藏层之间的权值 矩阵
publicdouble[,]v;〃权值矩阵V,这是隐藏层与输出层之间的权值 矩阵
publicdouble[,]dw;〃权值矩阵w
+0.51;
in tss=Co nvert.Tol nt32(s);
return((s -(double)ss)>0.5)?ss+1:ss;
}
publicBpNet(double[,]p,double[,]t)
//构造函数逻辑
R=n ewRa ndom();
this.i nNu m=p.GetLe ngth(1);
//更新V,V矩阵是隐藏层与输出层之间的权值for(intj=0;j<hideNum;j++)
{
v[j,k]+=rate*qq[k]*x1[j];
}
}
//计算隐层误差
for(intj=0;j<hideNum;j++)
{
//PP矩阵是隐藏层的误差
{
//★数据归一化
for(inti=0;i<inNum;i++)
{
x[i]=p[isamp,i]/in_rate;
}
for(inti=0;i<outNum;i++)
{
yd[i]=t[isamp,i]/in_rate;
}
//计算隐层的输入和输出
for(intj=0;j<hideNum;j++)
{
o1[j]=0.0;
{
w[i]+=dw[i];
}
}
//数据仿真函数
publicdouble[]sim(double[]psim)
{
for(i nti=O;i<i nN um;i++)
x[i]=psim[i]/in_rate;//in_rate为归一化系数
for(i ntj=O;j<hideNum;j++)
{
o1[j]=0.0;
{pMax=Math.Abs(p[isamp,i]);
}
}for(intj=0;j<outNum;j++)
{if(Math.Abs(t[isamp,j])>pMax)
{pMax=Math.Abs(t[isamp,j]);
}
}
in_rate=pMax;
}//endisamp for(intisamp=0;isamp<sampleNum;isamp++)
e=0.0;
//★求p,t中的最大值doublepMax=0.0;
//sampleNum为样本总数for(intisamp=0;isamp<sampleNum;isamp++){
//inNum是输入层的节点数(即神经细胞数)for(inti=0;i<inNum;i++)
{if(Math.Abs(p[isamp,i])>pMax)
}
}
〃初始化v
for(i nti=0;i<hideNum;i++)
{
for(i ntj=0;j<outNum;j++)
{
v[i,j]=(R.NextDouble()*2-1.0)/2;
}
}
rate=0.8;
e=0.0;
in_rate=1.0;?
}
//训练函数publicvoidtra in( double[,]p,double[,]t)
o2[k]=o2[k]+v[j,k]*x1[j];
x2[k]=1.0/(1.0+Math.Exp( -o2[k] -b2[k]));
x2[k]=in_rate*x2[k];
}?
returnx2;
}//en dsim
〃保存矩阵w,v
publicvoidsaveMatrix(double[,]w,stri ngfile name)
publicclassBpNet
public in ti nN um;〃输入节点数
inthideNum;//隐层节点数
publicintoutNum;//输出层节点数
publicintsampleNum;//样本总数
Ran domR;
double[]x;〃输入节点的输入数据
double[]x1;〃隐层节点的输出
dv=n ewdouble[hideNum,outNum];
//阈值
b1= newdouble[hideNum];
b2=n ewdouble[outNum];
db1= newdouble[hideNum];
db2=n ewdouble[outNum];
//误差
pp=newdouble[hideNum];〃隐藏层的误差
{
o2[k]=0.0;
for(intj=0;j<hideNum;j++)
{
o2[k]+=v[j,k]*x1[j];
}x2[k]=1.0/(1.0+Math.Exp(-o2[k]-b2[k]));
}
//计算输出层误差和均方差
{
//yd[k]是输出层的教师数据,所谓教师数据就是实际应该输出的 数据而已
qq[k]=(yd[k]-x2[k])*x2[k]*(1.0-x2[k]);
}
i++;
}
sr.Close();
}
catch(Excepti on e)?
{
//Lettheuserk no wwhatwe ntwro ng.
Con sole.WriteLi ne("Thefilecould notberead:");
Con sole.WriteLi ne(e.Message);
Console.WriteLine(”隐层节点数目:"+hideNum);
Console.WriteLine("输出层节点数目:"+outNum);
Con sole.ReadL in e();
//将这些矩阵规定好矩阵大小
x=n ewdouble[i nNu m];
x1= newdouble[hideNum];
}
sw.Close();
}
〃保存矩阵b1,b2
publicvoidsaveMatrix(double[]b,stri ngfile name) {
StreamWritersw=File.CreateText(file name);
for(i nti=O;i<b.Le ngth;i++)
{
sw.Write(b[i]+"");
{
b2[k]+=rate*qq[k];
}
〃更新b1,隐藏层的阈值
{
b1[j]+=rate*ppj
}
}//en disamp e=Math.Sqrt(e);〃均方差〃adjustWV(w,dw);
//adjustWV(v,dv);
}//en dtrain publicvoidadjustWV(double[,]w,double[,]dw)
{
StreamWritersw=File.CreateText(file name);
for(i nti=O;i<w.GetLe ngth(O);i++)
{
for(i ntj=O;j<w.GetLe ngth(1);j++)
{
sw.Write(w[i,j]+"");
}
sw.WriteLi ne();
this.outNum=t.GetLe ngth(1);
this.hideNum=computeHideNum(i nNu m,outNum);
〃this.hideNum=18;
this.sampleNum=p.GetLe ngth(O);
Console.WriteLine("输入节点数目:"+inNum);
12"));?
Strin gli ne;
in ti=0;
while((li ne=sr.ReadLi ne())!=null)?
{
stri ng[]s1=li ne.Trim().Split('');
for(i ntj=O;j<s1.Le ngth;j++)
{
w[i,j]=Co nvert.ToDouble(s1[j]);
}
sw.Close();
}
〃读取矩阵W,V
publicvoidreadMatrixW(double[,]w,stri ngfile name)
{
StreamReadersr;
try?
{
sr=n ewStreamReader(file name,E ncodi ng.GetE ncodi ng("gb23
}
〃读取矩阵b1,b2
publicvoidreadMatrixB(double[]b,stri ngfile name)
{
StreamReadersr;
try?
{?
sr=n ewStreamReader(file name,E ncodi ng.GetE ncodi ng("gb23
12"));?
Strin gli ne;
in ti=0;?
while((li ne=sr.ReadLi ne())!=null)?
{
b[i]=Co nvert.ToDouble(li ne);
iouble[,]dv;〃权值矩阵Vpublicdoublerate;//学习率publicdouble[]b1;〃隐层阈值矩阵publicdouble[]b2;〃输出层阈值矩阵publicdouble[]db1;〃隐层阈值矩阵publicdouble[]db2;〃输出层阈值矩阵double[]pp;〃隐藏层的误差double[]qq;〃输出层的误差
{
for(i nti=O;i<w.GetLe ngth(0);i++)
{
for(i ntj=O;j<w.GetLe ngth(1);j++) {
w[i,j]+=dw[i,j];
}
}
publicvoidadjustWV(double[]w,double[]dw)
{
for(i nti=O;i<w .Len gth;i++)
usin gSystem;
usi ng;
usin gSystem.L inq;
usin gSystem.Text;
usin gSystem;
usin gSyste m.10;
usin gSystem.Text;
n amespaceBpANNet
{
〃/<summary>
///BpNet的摘要说明'
///</summary>
qq=newdouble[outNum];〃输出层的误差
yd=newdouble[outNum];〃输出层的教师数据
//初始化w
for(i nti=O;i<i nN um;i++)
{
for(i ntj=O;j<hideNum;j++)
//NextDouble返回一个介于0.0和1.0之间的随机数。
w[i,j]=(R.NextDouble()*2-1.0)/2;
for(inti=0;i<inNum;i++)
{
o1[j]+=w[i,j]*x[i];//权值”*输“入 ”的那个累加的过程
}
//这个b1[j]就是隐藏层的阈值,阈值就是一个输入为 值
x1[j]=1.0/(1.0+Math.Exp(-o1[j]-b1[j]));
}
//计算输出层的输入和输出for(intk=0;k<outNum;k++)
pp[j]=0.0;
//算法参考我的视频截图
{
pp[j]+=qq[k]*v[j,k];
}
PP[j]=PP[j]*x1[j]*(1-x1[j]);
〃更新w
for(i nti=O;i<i nN um;i++)
{
w[i,j]+=rate*pp[j]*x[i];
}
}
〃更新b2,输出层的阈值
for(i ntk=0;k<outNum;k++)
for(i nti=O;i<i nN um;i++)
o1[j]=o1[j]+w[i,j]*x[i];
x1[j]=1.0/(1.0+Math.Exp(-o1[j] -b 1[j]));
}
for(i ntk=O;k<outNum;k++)
{
o2[k]=0.0;
for(i ntj=O;j<hideNum;j++)
double[]yd;〃输出层的教师数据,所谓教师数据就是实际数据而
已!
publicdoublee;//均方误差
doublein_rate;〃归一化比例系数
//用于确定隐藏层的神经细胞数
publici ntcomputeHideNum(i ntm,i ntn)
{
doubles=Math.Sqrt(0.43*m* n+0.12* n*n+2.54*m+0.77* n+0.35)
x2=n ewdouble[outNum];
o1= newdouble[hideNum];
o2=n ewdouble[outNum];
w=newdouble[inNum,hideNum];〃权值矩阵w,这是输入层与隐
藏层之间的权值矩阵
v=n ewdouble[hideNum,outNum];
dw=n ewdouble[i nNu m,hideNum];
double[]x2;〃输出节点的输出
double[]o1;//隐层的输入
double[]o2;//输出层的输入
publicdouble[,]w;〃权值矩阵w,这是输入层与隐藏层之间的权值 矩阵
publicdouble[,]v;〃权值矩阵V,这是隐藏层与输出层之间的权值 矩阵
publicdouble[,]dw;〃权值矩阵w
+0.51;
in tss=Co nvert.Tol nt32(s);
return((s -(double)ss)>0.5)?ss+1:ss;
}
publicBpNet(double[,]p,double[,]t)
//构造函数逻辑
R=n ewRa ndom();
this.i nNu m=p.GetLe ngth(1);