bp网络 改为多项式的改进

  1. 去年
    去年u.n.owen围观中 重新编辑

    实现的代码

    #include<vector>
    #include<cassert>
    #include<cmath> 
    #include<iostream>
    using std::fabs;
    using std::vector;
    using std::cout;
    using std::endl;
    using std::ends;
    
    typedef double Data_0;
    class Data_1{
    public:
    	vector<double> 	data;
    	
    	Data_1(){}
    	Data_1(vector<double> d){
    		int i,n=d.size();
    		for(i=0;i<n;++i){
    			data.push_back(d[i]);
    		}
    	}
    	operator vector<double>(){		return data;	}
    	double& operator[](unsigned int i){
    		assert(i<=data.size());
    		if(i==data.size()){
    			data.resize(i+1);
    		}
    		return data[i];
    	}
    	int size(){		return data.size();	}
    	void add(vector<double> a){		data.insert(data.end(),a.begin(),a.end());	}
    };
    
    
    
    /*
    class Cell{
    public:
    	double y;
    	double dy;
    	vector<double > w;
    };*/
    class Ploycell{
    public:
    	double y;
    	double dy;
    	vector<Ploycell > *w;
    	
    	
    	Ploycell():y(0),dy(0){	
    		w = new vector<Ploycell>;
    	}
    	//Ploycell(int y_):y(y_),dy(0){		w = new vector<Ploycell>;}
    	Ploycell(const Ploycell &p):y(p.y),dy(p.dy),w(p.w){}
    	Ploycell& operator =(const Ploycell &p){		y=p.y,dy=p.dy,w=p.w;return *this;	}
    	void clean(){
    		int i,n=w->size();
    		for(i=0;i<n;++i){
    			(*w)[i].clean();
    		}
    		delete w;
    	}
    	~Ploycell(){}
    	operator Data_1(){
    		Data_1 a;
    		int i,n=w->size();
    		for(i=0;i<n;++i){
    			a.data.push_back((*w)[i].y);
    		}
    		return a;
    	}
    	
    	
    	
    	void fun(Data_1& d){	//Data_1 operator*(Data_1);
    		y=0;
    		dy=0;
    		unsigned int i,n=d.size();
    		if(w->size()<n){
    			w->resize(n);
    		}
    		n=w->size();
    		d.data.resize(n,0);
    		for(i=0;i<n;++i){
    			if((*w)[i].w->size()!=0){/////////////////
    				(*w)[i].fun(d);
    			}
    			y += (*w)[i].y * d[i];//f(x)=x
    		}
    	}
    	void updata_0(const Data_1& d){
    		int i,n=w->size();
    		if(n==0)	return;
    		for(i=0;i<n;++i){
    			(*w)[i].dy = dy * d.data[i];
    			(*w)[i].updata_0(d);
    		}
    		dy=0;
    	}
    	void updata_1(double p=1){
    		int i,n=w->size();
    		if(n==0){
    			y -= dy;
    			dy *= p;
    		}else{
    			for(i=0;i<n;++i)
    				(*w)[i].updata_1();
    		}
    	}
    	void updata_2(){
    		int i,n=w->size();
    		if(n==0){
    			(*w).resize(1);
    			return;
    		}
    		for(i=0;i<n;++i){
    			(*w)[i].updata_2();
    		}
    	}
    };
    
    class Ploy_stream{
    public:
    	Ploycell poly;
    	vector<Data_1> sample_i;
    	vector<double> sample_o;
    	double e000;
    	int updatatime;
    	
    	
    	Ploy_stream():e000(0.01),updatatime(100){}
    	~Ploy_stream(){
    		poly.clean();
    	}
    	
    	
    	void add_sample(Data_1 i,Data_0 o){
    		sample_i.push_back(i);
    		sample_o.push_back(o);
    	}
    	void add_sample(vector<double> i,double o){
    		Data_1 a;
    		a.data.push_back(1);
    		a.data.insert(a.data.end(),i.begin(),i.end());
    		add_sample(a,o);
    	}
    	double math(Data_1 in){
    		poly.fun(in);
    		return poly.y;
    	}
    	void math(vector<double> in){
    		Data_1 a;
    		a.data.push_back(1);
    		a.data.insert(a.data.end(),in.begin(),in.end());
    		math(a);
    	}
    	void train(){
    		double l=1;
    		int i,n=sample_i.size();
    		double E,e=1000000000;
    		int t=0,time=10000;
    		int T=0;//updatatime=100
    		
    		Data_1 a; 
    		int j,m;
    		
    		
    		do{
    			E=0;
    			for(i=0;i<n;++i){
    				poly.fun(sample_i[i]);
    				poly.dy = (poly.y-sample_o[i])*l/n;
    				E=fabs(poly.y-sample_o[i]);
    				//a=sample_i[i];
    				m=sample_i[i].data.size();
    				a.data.resize(m);//a.data.clear(); 
    				for(j=0;j<m;++j){
    					//误差还原 		//y=sum(w[i]*x[i]),,dy=sum(dw*x),dw[i]=dy/x[i]	// ->dw[i]=dy/x[i]*k?
    					if(sample_i[i][j]==0){
    						a[j]=0;
    					}else{
    						a[j]=1.0/sample_i[i][j];
    					} 
    				}
    				poly.updata_0(a);
    			}
    			poly.updata_1(1);
    			
    			if(e/E<1.1){
    				l*=0.5;
    				++T;
    				if(T%updatatime==0){// updatatime=10; 
    					poly.updata_2();
    					l=1;
    				}
    			}
    			cout<<t<<"\t"<<E<<endl;
    			e=E;
    			++t;
    		}while(t<time&&E>e000);
    		
    		if(t==time){
    			cout<<"train_uncomplate"<<endl;
    		}else{
    			cout<<"train_complate"<<endl;
    		}
    	}
    };
  2. 去年u.n.owen围观中 重新编辑

    -image-
    设第n层和第m层,且n=m+1
    如代码所示,
    将神经模型: \( y_n = f( \sum y_{m,i} * w_{m,i} ) \) ,\( y_{0,i}=x_i\)
    改为: \( y_n = \sum x_i * y_{m,i}\)
    将反向传播模型:\( dw_{m,i} = dy_n * f' * y_{m,i}\)
    \( dy_{m,i} = dy_n * f' * w_{m,i}\)
    改为: \( dy_{m,i} = dy_n / x_i ,(x_i 不为0) \)
    \( dy_{m,i} = 0 ,(x_i = 0) \)

    测试用代码

    #include <stdio.h>
    #include <time.h>
    #include <math.h>
    #include <stdlib.h>
    #include <iostream>
    #include <fstream>
    #include<vector>
    
    #include"B_poly.h"
    
    using std::cout;
    using std::cerr;
    using std::endl;
    using std::ends;
    using std::ofstream;
    using std::ifstream;
    
    using std::vector;
    
    
    
    
    int Data=11000;
    int Inn=2;
    int Outn=1;
    
    vector<vector<double> > In;
    vector<vector<double> > Out;
    
    void writeTest(){
    	double r1,r2;
    	int i;
    	srand((unsigned)time(NULL));
    	
    	ofstream f1("in_1.txt");
    	if(f1.fail()){
    		cerr<<"can not open the in file"<<endl;
    		exit(0);
    	}
    	ofstream f2("out_1.txt");
    	if(f2.fail()){
    		cerr<<"can not open the out file"<<endl;
    		exit(0);
    	}
    
    
    	for(i=0;i<Data;i++){
    		r1=rand()%1000/1.0;
    		r2=rand()%1000/1.0;
    		f1<<r1<<" "<<r2<<endl;
    		f2<<sqrt(r1*r1+r2*r2)<<endl;
    	}
    	f1.close();
    	f2.close();
    }
    
    void readData(){
    	int i,j;
    	double t;
    	vector<double> in_;
    	
    	ifstream f1("in_1.txt");
    	if(f1.fail()){
    		cerr<<"can not open the in file"<<endl;
    		exit(0);
    	}
    	for(i=0;i<Data;i++){
    		for(j=0; j<Inn; j++){
    			f1 >> t;
    			in_.push_back(t);
    		}
    		In.push_back(in_);
    		in_.clear();
    	}
    		
    			
    	ifstream f2("out_1.txt");
    	if(f2.fail()){
    		cerr<<"can not open the out file"<<endl;
    		exit(0);
    	}
    	for(i=0;i<Data;i++)
    		for(j=0; j<Outn; j++){
    			f2 >> t;
    			in_.push_back(t);
    			Out.push_back(in_);
    			in_.clear();
    		}
    }
    
    
    
    int main(){
    	Ploy_stream p;
    	p.updatatime=20;
    	
    	writeTest();
    	readData();
    	
    	int i,n=In.size();
    	//cout<<n<<endl;
    	for(i=0;i<n;++i){
    		p.add_sample(In[i],Out[i][0]);
    	}
    	p.train();
    	
    	int j,x=0;
    	vector<double> a;
    	for (i = 1;i <= 1000; i+=100){
            for (j = 1;j <= 1000; j+=100){
            	a.push_back(i);
            	a.push_back(j);
            	p.math(a);
                printf("[%d,%d]=%.1lf  ",i,j,p.poly.y);
                a.clear();
                x++;
                if (x%10==0){
    				printf("\n");
                }
            }
    	}
    }
  3. 看起来是很高深的东西呢。。。楼主能不能告诉我,这些是用于做什么的?

  4. @丁香丛中的雪狼 看起来是很高深的东西呢。。。楼主能不能告诉我,这些是用于做什么的?

    就是拟合出个函数,输入任意维度的那种。。。
    虽然不管怎么想,最简单的方法就是最小二乘法处理下就完事了。但想象中觉得写个 自动生成函数然后进行矩阵运算 的程序好麻烦呀。。。
    其实原理很简单的。而且发这帖子主要因为,反向传播的那个公式,昨天我刚发现公式推导是错的,而且当时我稀里糊涂的就信了,就好气了。。。

 

后才能发言