bp神经网络详细步骤C实现.docx
《bp神经网络详细步骤C实现.docx》由会员分享,可在线阅读,更多相关《bp神经网络详细步骤C实现.docx(14页珍藏版)》请在冰豆网上搜索。
![bp神经网络详细步骤C实现.docx](https://file1.bdocx.com/fileroot1/2022-10/27/a387fd1f-eee5-4761-ba06-acd3e9eacf2c/a387fd1f-eee5-4761-ba06-acd3e9eacf2c1.gif)
bp神经网络详细步骤C实现
usingSystem;
using;
usingSystem.Linq;
usingSystem.Text;
usingSystem;
usingSystem.IO;
usingSystem.Text;
namespaceBpANNet
{
///
///BpNet的摘要说明。
///
publicclassBpNet
{
publicintinNum;//输入节点数
inthideNum;//隐层节点数
publicintoutNum;//输出层节点数
publicintsampleNum;//样本总数
RandomR;
double[]x;//输入节点的输入数据
double[]x1;//隐层节点的输出
double[]x2;//输出节点的输出
double[]o1;//隐层的输入
double[]o2;//输出层的输入
publicdouble[,]w;//权值矩阵w,这是输入层与隐藏层之间的权值矩阵
publicdouble[,]v;//权值矩阵V,这是隐藏层与输出层之间的权值矩阵
publicdouble[,]dw;//权值矩阵w
publicdouble[,]dv;//权值矩阵V
publicdoublerate;//学习率
publicdouble[]b1;//隐层阈值矩阵
publicdouble[]b2;//输出层阈值矩阵
publicdouble[]db1;//隐层阈值矩阵
publicdouble[]db2;//输出层阈值矩阵
double[]pp;//隐藏层的误差
double[]qq;//输出层的误差
double[]yd;//输出层的教师数据,所谓教师数据就是实际数据而已!
publicdoublee;//均方误差
doublein_rate;//归一化比例系数
//用于确定隐藏层的神经细胞数
publicintcomputeHideNum(intm,intn)
{
doubles=Math.Sqrt(0.43*m*n+0.12*n*n+2.54*m+0.77*n+0.35)+0.51;
intss=Convert.ToInt32(s);
return((s-(double)ss)>0.5)?
ss+1:
ss;
}
publicBpNet(double[,]p,double[,]t)
{
//构造函数逻辑
R=newRandom();
this.inNum=p.GetLength
(1);
this.outNum=t.GetLength
(1);
this.hideNum=computeHideNum(inNum,outNum);
//this.hideNum=18;
this.sampleNum=p.GetLength(0);
Console.WriteLine("输入节点数目:
"+inNum);
Console.WriteLine("隐层节点数目:
"+hideNum);
Console.WriteLine("输出层节点数目:
"+outNum);
Console.ReadLine();
//将这些矩阵规定好矩阵大小
x=newdouble[inNum];
x1=newdouble[hideNum];
x2=newdouble[outNum];
o1=newdouble[hideNum];
o2=newdouble[outNum];
w=newdouble[inNum,hideNum];//权值矩阵w,这是输入层与隐藏层之间的权值矩阵
v=newdouble[hideNum,outNum];
dw=newdouble[inNum,hideNum];
dv=newdouble[hideNum,outNum];
//阈值
b1=newdouble[hideNum];
b2=newdouble[outNum];
db1=newdouble[hideNum];
db2=newdouble[outNum];
//误差
pp=newdouble[hideNum];//隐藏层的误差
qq=newdouble[outNum];//输出层的误差
yd=newdouble[outNum];//输出层的教师数据
//初始化w
for(inti=0;i{
for(intj=0;j{
//NextDouble返回一个介于0.0和1.0之间的随机数。
w[i,j]=(R.NextDouble()*2-1.0)/2;
}
}
//初始化v
for(inti=0;i{
for(intj=0;j{
v[i,j]=(R.NextDouble()*2-1.0)/2;
}
}
rate=0.8;
e=0.0;
in_rate=1.0;?
}
//训练函数
publicvoidtrain(double[,]p,double[,]t)
{
e=0.0;
//★求p,t中的最大值
doublepMax=0.0;
//sampleNum为样本总数
for(intisamp=0;isamp{
//inNum是输入层的节点数(即神经细胞数)
for(inti=0;i{
if(Math.Abs(p[isamp,i])>pMax)
{
pMax=Math.Abs(p[isamp,i]);
}
}
for(intj=0;j{
if(Math.Abs(t[isamp,j])>pMax)
{
pMax=Math.Abs(t[isamp,j]);
}
}
in_rate=pMax;
}//endisamp
for(intisamp=0;isamp{
//★数据归一化
for(inti=0;i{
x[i]=p[isamp,i]/in_rate;
}
for(inti=0;i{
yd[i]=t[isamp,i]/in_rate;
}
//计算隐层的输入和输出
for(intj=0;j{
o1[j]=0.0;
for(inti=0;i{
o1[j]+=w[i,j]*x[i];//“权值”*“输入”的那个累加的过程
}
//这个b1[j]就是隐藏层的阈值,阈值就是一个输入为“-1”的累加值
x1[j]=1.0/(1.0+Math.Exp(-o1[j]-b1[j]));
}
//计算输出层的输入和输出
for(intk=0;k{
o2[k]=0.0;
for(intj=0;j{
o2[k]+=v[j,k]*x1[j];
}
x2[k]=1.0/(1.0+Math.Exp(-o2[k]-b2[k]));
}
//计算输出层误差和均方差
for(intk=0;k{
//yd[k]是输出层的教师数据,所谓教师数据就是实际应该输出的数据而已
qq[k]=(yd[k]-x2[k])*x2[k]*(1.0-x2[k]);
e+=(yd[k]-x2[k])*(yd[k]-x2[k]);
//更新V,V矩阵是隐藏层与输出层之间的权值
for(intj=0;j{
v[j,k]+=rate*qq[k]*x1[j];
}
}
//计算隐层误差
for(intj=0;j{
//PP矩阵是隐藏层的误差
pp[j]=0.0;
//算法参考我的视频截图
for(intk=0;k{
pp[j]+=qq[k]*v[j,k];
}
pp[j]=pp[j]*x1[j]*(1-x1[j]);
//更新W
for(inti=0;i{
w[i,j]+=rate*pp[j]*x[i];
}
}
//更新b2,输出层的阈值
for(intk=0;k{
b2[k]+=rate*qq[k];
}
//更新b1,隐藏层的阈值
for(intj=0;j{
b1[j]+=rate*pp[j];
}
}//endisamp
e=Math.Sqrt(e);//均方差
//adjustWV(w,dw);
//adjustWV(v,dv);
}//endtrain
publicvoidadjustWV(double[,]w,double[,]dw)
{
for(inti=0;i{
for(intj=0;j(1);j++)
{
w[i,j]+=dw[i,j];
}
}
}
publicvoidadjustWV(double[]w,double[]dw)
{
for(inti=0;i{
w[i]+=dw[i];
}
}
//数据仿真函数
publicdouble[]sim(double[]psim)
{
for(inti=0;ix[i]=psim[i]/in_rate;//in_rate为归一化系数
for(intj=0;j{
o1[j]=0.0;
for(inti=0;io1[j]=o1[j]+w[i,j]*x[i];
x1[j]=1.0/(1.0+Math.Exp(-o1[j]-b1[j]));
}
for(intk=0;k{
o2[k]=0.0;
for(intj=0;jo2[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;
}//endsim
//保存矩阵w,v
publicvoidsaveMatrix(double[,]w,stringfilename)
{
StreamWritersw=File.CreateText(filename);
for(inti=0;i{
for(intj=0;j(1);j++)
{
sw.Write(w[i,j]+"");
}
sw.WriteLine();
}
sw.Close();
}
//保存矩阵b1,b2
publicvoidsaveMatrix(double[]b,stringfilename)
{
StreamWritersw=File.CreateText(filename);
for(inti=0;i{
sw.Write(b[i]+"");
}
sw.Close();
}
//读取矩阵W,V
publicvoidreadMatrixW(double[,]w,stringfilename)
{
StreamReadersr;
try?
{
sr=newStreamReader(filename,Encoding.GetEnc