• BP网络之C#实现


    转自http://blog.csdn.net/qw_study/article/details/1504147

    using System;
    using System.IO;
    using System.Text;
    namespace BpANNet
    {
      /// <summary>
      /// BpNet 的摘要说明。
      /// </summary>
      public class BpNet
      {
        public int inNum;//输入节点数
        int hideNum;//隐层节点数
        public int outNum;//输出层节点数
        public int sampleNum;//样本总数
       
        Random R;
        double [] x;//输入节点的输入数据
        double [] x1;//隐层节点的输出
        double [] x2;//输出节点的输出

        double [] o1;//隐层的输入
        double [] o2;//输出层的输入
        public double [,] w;//权值矩阵w
        public double [,] v;//权值矩阵V
        public double [,] dw;//权值矩阵w
        public double [,] dv;//权值矩阵V
       

        public double rate;//学习率
        public double [] b1;//隐层阈值矩阵
        public double [] b2;//输出层阈值矩阵
        public double [] db1;//隐层阈值矩阵
        public double [] db2;//输出层阈值矩阵
       
        double [] pp;//输出层的误差
        double [] qq;//隐层的误差
        double [] yd;//输出层的教师数据
        public double e;//均方误差
        double in_rate;//归一化比例系数

        public int computeHideNum(int m,int n)
        {
          double s=Math.Sqrt(0.43*m*n+0.12*n*n+2.54*m+0.77*n+0.35)+0.51;
          int ss=Convert.ToInt32(s);
          return ((s-(double)ss)>0.5) ? ss+1:ss;

        }
        public BpNet(double [,] p,double [,] t)
        {
         
          // 构造函数逻辑
          R=new Random();
         
          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=new double[inNum];
          x1=new double[hideNum];
          x2=new double[outNum];

          o1=new double[hideNum];
          o2=new double[outNum];

          w=new double[inNum,hideNum];
          v=new double[hideNum,outNum];
          dw=new double[inNum,hideNum];
          dv=new double[hideNum,outNum];
         
          b1=new double[hideNum];
          b2=new double[outNum];
          db1=new double[hideNum];
          db2=new double[outNum];
         
          pp=new double[hideNum];
          qq=new double[outNum];
          yd=new double[outNum];

          //初始化w
          for(int i=0;i<inNum;i++)
          {
            for(int j=0;j<hideNum;j++)
            {
              w[i,j]=(R.NextDouble()*2-1.0)/2;
            }
          }

          //初始化v
          for(int i=0;i<hideNum;i++)
          {
            for(int j=0;j<outNum;j++)
            {
              v[i,j]=(R.NextDouble()*2-1.0)/2;
            }
          }

          rate=0.8;
          e=0.0;
          in_rate=1.0;   
        }

        //训练函数
        public void train(double [,] p,double [,] t)
        {
          e=0.0;
          //求p,t中的最大值
          double pMax=0.0;
          for(int isamp=0;isamp<sampleNum;isamp++)
          {
            for(int i=0;i<inNum;i++)
            {
              if(Math.Abs(p[isamp,i])>pMax)
              {
                pMax=Math.Abs(p[isamp,i]);
              }
            }

            for(int j=0;j<outNum;j++)
            {
              if(Math.Abs(t[isamp,j])>pMax)
              {
                pMax=Math.Abs(t[isamp,j]);
              }
            }

            in_rate=pMax;
          }//end isamp

         

          for(int isamp=0;isamp<sampleNum;isamp++)
          {
            //数据归一化
            for(int i=0;i<inNum;i++)
            {
              x[i]=p[isamp,i]/in_rate;
            }
            for(int i=0;i<outNum;i++)
            {
              yd[i]=t[isamp,i]/in_rate;
            }

            //计算隐层的输入和输出

            for(int j=0;j<hideNum;j++)
            {
              o1[j]=0.0;
              for(int i=0;i<inNum;i++)
              {
                o1[j]+=w[i,j]*x[i];
              }
              x1[j]=1.0/(1.0+Math.Exp(-o1[j]-b1[j]));
            }

            //计算输出层的输入和输出
            for(int k=0;k<outNum;k++)
            {
              o2[k]=0.0;
              for(int j=0;j<hideNum;j++)
              {
                o2[k]+=v[j,k]*x1[j];
              }
              x2[k]=1.0/(1.0+Math.Exp(-o2[k]-b2[k]));
            }

            //计算输出层误差和均方差

            for(int k=0;k<outNum;k++)
            {
              qq[k]=(yd[k]-x2[k])*x2[k]*(1.0-x2[k]);
              e+=(yd[k]-x2[k])*(yd[k]-x2[k]);
              //更新V
              for(int j=0;j<hideNum;j++)
              {
                v[j,k]+=rate*qq[k]*x1[j];
              }
            }

            //计算隐层误差

            for(int j=0;j<hideNum;j++)
            {
              pp[j]=0.0;
              for(int k=0;k<outNum;k++)
              {
                pp[j]+=qq[k]*v[j,k];
              }
              pp[j]=pp[j]*x1[j]*(1-x1[j]);

              //更新W

              for(int i=0;i<inNum;i++)
              {
                w[i,j]+=rate*pp[j]*x[i];
              }
            }

            //更新b2
            for(int k=0;k<outNum;k++)
            {
              b2[k]+=rate*qq[k];
            }
           
            //更新b1
            for(int j=0;j<hideNum;j++)
            {
              b1[j]+=rate*pp[j];
            }

          }//end isamp
          e=Math.Sqrt(e);
    //      adjustWV(w,dw);
    //      adjustWV(v,dv);
         
         
        }//end train

        public void adjustWV(double [,] w,double[,] dw)
        {
          for(int i=0;i<w.GetLength(0);i++)
          {
            for(int j=0;j<w.GetLength(1);j++)
            {
              w[i,j]+=dw[i,j];
            }
          }

        }

        public void adjustWV(double [] w,double[] dw)
        {
          for(int i=0;i<w.Length;i++)
          {
           
            w[i]+=dw[i];
           
          }

        }

        //数据仿真函数
       
        public double[] sim(double [] psim)
        {
          for(int i=0;i<inNum;i++)
            x[i]=psim[i]/in_rate;

          for(int j=0;j<hideNum;j++)
          {
            o1[j]=0.0;
            for(int i=0;i<inNum;i++)
              o1[j]=o1[j]+w[i,j]*x[i];
            x1[j]=1.0/(1.0+Math.Exp(-o1[j]-b1[j]));
          }
          for(int k=0;k<outNum;k++)
          {
            o2[k]=0.0;
            for(int j=0;j<hideNum;j++)
              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];

          }

          return x2;
        } //end sim

        //保存矩阵w,v
        public void saveMatrix(double [,] w,string filename)
        {
          StreamWriter sw=File.CreateText(filename);
          for(int i=0;i<w.GetLength(0);i++)
          {
            for(int j=0;j<w.GetLength(1);j++)
            {
              sw.Write(w[i,j]+" ");
            }
            sw.WriteLine();
          }
          sw.Close();

        }

        //保存矩阵b1,b2
        public void saveMatrix(double [] b,string filename)
        {
          StreamWriter sw=File.CreateText(filename);
          for(int i=0;i<b.Length;i++)
          {
            sw.Write(b[i]+" ");
          }
          sw.Close();
        }

        //读取矩阵W,V
        public void readMatrixW(double [,] w,string filename)
        {
         
          StreamReader sr;
          try
          {
           
            sr = new StreamReader(filename,Encoding.GetEncoding("gb2312"));
         
            String line;
            int i=0;
             
            while ((line = sr.ReadLine()) != null)
            {

              string[] s1=line.Trim().Split(' ');
              for(int j=0;j<s1.Length;j++)
              {
                w[i,j]=Convert.ToDouble(s1[j]);
              }
              i++;
            }
            sr.Close();
         
          }
          catch (Exception e)
          {
            // Let the user know what went wrong.
            Console.WriteLine("The file could not be read:");
            Console.WriteLine(e.Message);
          }
         
        }

       
       

        //读取矩阵b1,b2
        public void readMatrixB(double [] b,string filename)
        {
         
          StreamReader sr;
          try
          {       
            sr = new StreamReader(filename,Encoding.GetEncoding("gb2312"));
         
            String line;
            int i=0;         
            while ((line = sr.ReadLine()) != null)
            {
              b[i]=Convert.ToDouble(line);
              i++;
            }
            sr.Close();
         
          }
          catch (Exception e)
          {
            // Let the user know what went wrong.
            Console.WriteLine("The file could not be read:");
            Console.WriteLine(e.Message);
          }     

        }

       

      }//end bpnet
    } //end namespace

    namespace BpANNet
    {
      /// <summary>
      /// Class1 的摘要说明。
      /// </summary>
      class Class1
      {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
          //0.1399,0.1467,0.1567,0.1595,0.1588,0.1622,0.1611,0.1615,0.1685,0.1789,0.1790
         
    //      double [,] p1=new double[,]{{0.05,0.02},{0.09,0.11},{0.12,0.20},{0.15,0.22},{0.20,0.25},{0.75,0.75},{0.80,0.83},{0.82,0.80},{0.90,0.89},{0.95,0.89},{0.09,0.04},{0.1,0.1},{0.14,0.21},{0.18,0.24},{0.22,0.28},{0.77,0.78},{0.79,0.81},{0.84,0.82},{0.94,0.93},{0.98,0.99}};
    //      double [,] t1=new double[,]{{1,0},{1,0},{1,0},{1,0},{1,0},{0,1},{0,1},{0,1},{0,1},{0,1},{1,0},{1,0},{1,0},{1,0},{1,0},{0,1},{0,1},{0,1},{0,1},{0,1}};
          double [,] p1=new double[,]{{0.1399,0.1467,0.1567,0.1595,0.1588,0.1622},{0.1467,0.1567,0.1595,0.1588,0.1622,0.1611},{0.1567,0.1595,0.1588,0.1622,0.1611,0.1615},{0.1595,0.1588,0.1622,0.1611,0.1615,0.1685},{0.1588,0.1622,0.1611,0.1615,0.1685,0.1789}};
          double [,] t1=new double[,]{{0.1622},{0.1611},{0.1615},{0.1685},{0.1789},{0.1790}};
          BpNet bp=new BpNet(p1,t1);
          int study=0;
          do
          {
            study++;
            bp.train(p1,t1);
    //       bp.rate=0.95-(0.95-0.3)*study/50000;
    //        Console.Write("第 "+ study+"次学习: ");
    //        Console.WriteLine(" 均方差为 "+bp.e);
           
          }while(bp.e>0.001 && study <50000);
          Console.Write("第 "+ study+"次学习: ");
          Console.WriteLine(" 均方差为 "+bp.e);
          bp.saveMatrix(bp.w,"w.txt");
          bp.saveMatrix(bp.v,"v.txt");
          bp.saveMatrix(bp.b1,"b1.txt");
          bp.saveMatrix(bp.b2,"b2.txt");

    //      double [,] p2=new double[,]{{0.05,0.02},{0.09,0.11},{0.12,0.20},{0.15,0.22},{0.20,0.25},{0.75,0.75},{0.80,0.83},{0.82,0.80},{0.90,0.89},{0.95,0.89},{0.09,0.04},{0.1,0.1},{0.14,0.21},{0.18,0.24},{0.22,0.28},{0.77,0.78},{0.79,0.81},{0.84,0.82},{0.94,0.93},{0.98,0.99}};
          double [,] p2=new double[,]{{0.1399,0.1467,0.1567,0.1595,0.1588,0.1622},{0.1622,0.1611,0.1615,0.1685,0.1789,0.1790}};
          int aa=bp.inNum;
          int bb=bp.outNum;
          int cc=p2.GetLength(0);
          double [] p21=new double[aa];
          double [] t2=new double[bb];
          for(int n=0;n<cc;n++)
          {
            for(int i=0;i<aa;i++)
            {
              p21[i]=p2[n,i];
            }
            t2=bp.sim(p21);

            for(int i=0;i<t2.Length;i++)
            {
              Console.WriteLine(t2[i]+" ");
            }

          }

          Console.ReadLine();
        }
      }
    }

  • 相关阅读:
    ndk-build:command not found
    Linux shell 之 sed 命令详解 第三部分
    Linux shell 之 sed 命令详解 第二部分
    Linux shell 之 sed 概述
    Linux shell 之 sed 命令详解 第一部分
    git 如何撤销 commit (未 push)
    如何在 ubuntu 系统上安装 jdk
    Ubuntu 16.04.06(32位)安装samba--“”拒绝访问”
    Ubuntu 安装 vim、ssh、samba
    OC中block对于变量的捕获
  • 原文地址:https://www.cnblogs.com/zhiji6/p/2352945.html
Copyright © 2020-2023  润新知