/* trainmeanfieldperceptron.cpp - train perceptron in meanfield boltzmann machine way (deterministic real valued logistic outputs) Copyright (C) 2010 Rui Rodrigues This software is released under the terms of the GNU General Public License (http://www.gnu.org/copyleft/gpl.html). */ #include #include #include #include #include using namespace std; #include "gradgsl.h" #include "netdimsandfilenames.h" #include #include #include void checkfstream(ofstream& file_io,const char* filename); //in ../geral/checkfstream.cpp void checkfstream(ifstream& file_io,const char* filename); //in ../geral/checkfstream.cpp void read_datafile(ifstream&in,netdimsandfilenames& A); //in netdimsandfilenames.cpp void logistic (gsl_matrix * m,int nrows,int ncols); //in parallelgradgsl.cpp void writegslmatriz(const char* filename,gsl_matrix*m); void readgslmatriz(const char* filename,gsl_matrix*&m); void readgslvectorasmatriz(const char* filename,gsl_vector*v); //in iogslvectormatrix.cpp void useblacklist(gsl_matrix * &inputdata,const char*blacklistfile); //in blacklist.cpp double computeerrorperceptron(const gsl_vector *vectorweights, void *params); void computegradientperceptron(const gsl_vector *vectorweights, void *params, gsl_vector *gradient); void computegradanderror(const gsl_vector *vectorweights, void *params, double *error, gsl_vector *gradient); // ---------------------------------------------------------------------------------------- //-----------------------CONFIGURE----------------------------------------------------- const size_t batchsize=500; const size_t numepochs=100; const double epsilonweights=0.1; const double epsilonbias=0.1; const double momentum=0.5; const double weightscost=0.002; //----------------------------------------------------------------------------------- const string blacklist_use="useblacklist"; struct inputoutputdata{ gsl_matrix * ptinputdata, *ptoutputdata, *auxgrad; //auxgrad is used to compute grad and must be previously allocated with //dimensions (ptinputdata->size2,ptoutputdata->size2) gsl_vector* vectorimagedata, *ones; //vectorimagedata must be previously allocated with size (ptinputdata->size1)*(ptoutputdata->size2) //ones is used to compute grad and must be previously allocated with size (ptinputdata->size1) // and filled with ones double weightscost; }; int main(int argc, char ** argv){ try{ if(argc<4){ cout<<" must be called with argument signal1 then signal2 and at last folder name. Optionaly thereis an extra argument: useblacklist !"<size2!=ninputs){ cout<<"inputdata is not compatible with ninputs!"<size2!=noutputs){ cout<<"outputdata is not compatible with noutputs!"<size1; size_t numbatches=npatches/batchsize; //---------------------------------------------------------- //gsl random number generator gsl_rng *r = gsl_rng_alloc(gsl_rng_taus2); unsigned long seed=time (NULL) * getpid(); gsl_rng_set(r,seed); //file for perceptronweights string f="../"; f.append(cc); f.append("/perceptron_"); f.append(signal1); f.append("_"); f.append(signal2); f.append(".txt"); //load weights gsl_vector * vectorweights=gsl_vector_alloc((ninputs+1)*noutputs); readgslvectorasmatriz(f.c_str(),vectorweights); inputoutputdata params; //-------------------------computer error rate before training------------ gsl_vector *vectorimage=gsl_vector_alloc(npatches*noutputs); params.ptinputdata=inputdata; params.ptoutputdata=outputdata; params.vectorimagedata=vectorimage; double error=computeerrorperceptron(vectorweights,¶ms); cout<<"square error rate by patch before training is "<<(error*error)/npatches<gradient, 1e-3); //printf ("%5d %10.5f\n", iter,s->f); } while (status == GSL_CONTINUE && iter < maxiterations); printf("epoch %4i batch %4i squared error rate by patch %e \r", epoch, batch,(s->f)*(s->f)/batchsize); fflush(stdout); gsl_vector_memcpy (vectorweights,s->x); gsl_multimin_fdfminimizer_free (s); } } gsl_matrix_free(permuted_inputdata); gsl_matrix_free(permuted_outputdata); gsl_vector_free(ones); gsl_vector_free(batchvectorimage); gsl_matrix_free(auxgrad); //save new weights gsl_matrix_view weightsmatrix=gsl_matrix_view_vector(vectorweights,ninputs+1,noutputs); writegslmatriz(f.c_str(),&weightsmatrix.matrix); //-------------------------computer error rate after training------------ params.ptinputdata=inputdata; params.ptoutputdata=outputdata; params.vectorimagedata=vectorimage; error=computeerrorperceptron(vectorweights,¶ms); cout<<"square error rate by patch after training is "<<(error*error)/npatches<ptinputdata; gsl_matrix* outputdata=ptdata->ptoutputdata; gsl_vector*vectorimagedata=ptdata->vectorimagedata; unsigned batchsize=inputdata->size1; unsigned ninputs=inputdata->size2; unsigned noutputs=outputdata->size2; if(vectorweights->size!=(ninputs+1)*noutputs) throw "input, output data and weights dimensions are not compatible!"; if(vectorimagedata->size!=batchsize*noutputs) throw "vectorimagedata dimensions are not correct!"; gsl_matrix_const_view pureweights=gsl_matrix_const_view_vector (vectorweights, ninputs, noutputs); gsl_vector_const_view bias=gsl_vector_const_subvector (vectorweights,ninputs*noutputs,noutputs); gsl_matrix_view imagedata=gsl_matrix_view_vector(vectorimagedata,batchsize,noutputs); //insert bias on matrix for(unsigned i=0;iptinputdata; gsl_matrix* outputdata=ptdata->ptoutputdata; gsl_matrix* auxgrad=ptdata->auxgrad; gsl_vector*vectorimagedata=ptdata->vectorimagedata; gsl_vector*ones=ptdata->ones; double weightscost=ptdata->weightscost; unsigned batchsize=inputdata->size1; unsigned ninputs=inputdata->size2; unsigned noutputs=outputdata->size2; if(vectorweights->size!=(ninputs+1)*noutputs) throw "input, output data and weights dimensions are not compatible!"; if(gradient->size!=(ninputs+1) *noutputs) throw "gradient and weights dimensions are not compatible!"; if((auxgrad->size1!=ninputs)||(auxgrad->size2!=noutputs)) throw "auxgrad dimensions are not correct!"; if(vectorimagedata->size!=batchsize*noutputs) throw "vectorimagedata dimensions are not correct!"; if(ones->size!=batchsize) throw "ones dimension is not correct!"; gsl_matrix_const_view pureweights=gsl_matrix_const_view_vector (vectorweights, ninputs, noutputs); gsl_vector_const_view bias=gsl_vector_const_subvector (vectorweights,ninputs*noutputs,noutputs); gsl_matrix_view imagedata=gsl_matrix_view_vector(vectorimagedata,batchsize,noutputs); //insert bias on matrix for(unsigned i=0;iptinputdata; gsl_matrix* outputdata=ptdata->ptoutputdata; gsl_matrix* auxgrad=ptdata->auxgrad; gsl_vector*vectorimagedata=ptdata->vectorimagedata; gsl_vector*ones=ptdata->ones; double weightscost=ptdata->weightscost; unsigned batchsize=inputdata->size1; unsigned ninputs=inputdata->size2; unsigned noutputs=outputdata->size2; if(vectorweights->size!=(ninputs+1)*noutputs) throw "input, output data and weights dimensions are not compatible!"; if(gradient->size!=(ninputs+1)*noutputs) throw "gradient and weights dimensions are not compatible!"; if((auxgrad->size1!=ninputs)||(auxgrad->size2!=noutputs)) throw "auxgrad dimensions are not correct!"; if(vectorimagedata->size!=batchsize*noutputs) throw "vectorimagedata dimensions are not correct!"; if(ones->size!=batchsize) throw "ones dimension is not correct!"; gsl_matrix_const_view pureweights=gsl_matrix_const_view_vector (vectorweights, ninputs, noutputs); gsl_vector_const_view bias=gsl_vector_const_subvector (vectorweights,ninputs*noutputs,noutputs); gsl_matrix_view imagedata=gsl_matrix_view_vector(vectorimagedata,batchsize,noutputs); //insert bias on matrix for(unsigned i=0;i