/************************************************************************* Calculation of all types of errors at once for a subset or full dataset, which can be represented in different formats. THIS INTERNAL FUNCTION IS NOT INTENDED TO BE USED BY ALGLIB USERS! -- ALGLIB -- Copyright 26.07.2012 by Bochkanov Sergey *************************************************************************/ public static void mlpallerrorsx(multilayerperceptron network, double[,] densexy, sparse.sparsematrix sparsexy, int datasetsize, int datasettype, int[] idx, int subset0, int subset1, int subsettype, alglib.smp.shared_pool buf, modelerrors rep) { int nin = 0; int nout = 0; int wcount = 0; int rowsize = 0; bool iscls = new bool(); int srcidx = 0; int cstart = 0; int csize = 0; int j = 0; hpccores.mlpbuffers pbuf = null; int len0 = 0; int len1 = 0; modelerrors rep0 = new modelerrors(); modelerrors rep1 = new modelerrors(); int i_ = 0; int i1_ = 0; alglib.ap.assert(datasetsize>=0, "MLPAllErrorsX: SetSize<0"); alglib.ap.assert(datasettype==0 || datasettype==1, "MLPAllErrorsX: DatasetType is incorrect"); alglib.ap.assert(subsettype==0 || subsettype==1, "MLPAllErrorsX: SubsetType is incorrect"); // // Determine network properties // mlpproperties(network, ref nin, ref nout, ref wcount); iscls = mlpissoftmax(network); // // Split problem. // // Splitting problem allows us to reduce effect of single-precision // arithmetics (SSE-optimized version of MLPChunkedProcess uses single // precision internally, but converts them to double precision after // results are exported from HPC buffer to network). Small batches are // calculated in single precision, results are aggregated in double // precision, and it allows us to avoid accumulation of errors when // we process very large batches (tens of thousands of items). // // NOTE: it is important to use real arithmetics for ProblemCost // because ProblemCost may be larger than MAXINT. // if( subset1-subset0>=2*microbatchsize && (double)(apserv.inttoreal(subset1-subset0)*apserv.inttoreal(wcount))>(double)(gradbasecasecost) ) { apserv.splitlength(subset1-subset0, microbatchsize, ref len0, ref len1); mlpallerrorsx(network, densexy, sparsexy, datasetsize, datasettype, idx, subset0, subset0+len0, subsettype, buf, rep0); mlpallerrorsx(network, densexy, sparsexy, datasetsize, datasettype, idx, subset0+len0, subset1, subsettype, buf, rep1); rep.relclserror = (len0*rep0.relclserror+len1*rep1.relclserror)/(len0+len1); rep.avgce = (len0*rep0.avgce+len1*rep1.avgce)/(len0+len1); rep.rmserror = Math.Sqrt((len0*math.sqr(rep0.rmserror)+len1*math.sqr(rep1.rmserror))/(len0+len1)); rep.avgerror = (len0*rep0.avgerror+len1*rep1.avgerror)/(len0+len1); rep.avgrelerror = (len0*rep0.avgrelerror+len1*rep1.avgrelerror)/(len0+len1); return; } // // Retrieve and prepare // alglib.smp.ae_shared_pool_retrieve(buf, ref pbuf); if( iscls ) { rowsize = nin+1; bdss.dserrallocate(nout, ref pbuf.tmp0); } else { rowsize = nin+nout; bdss.dserrallocate(-nout, ref pbuf.tmp0); } // // Processing // hpccores.hpcpreparechunkedgradient(network.weights, wcount, mlpntotal(network), nin, nout, pbuf); cstart = subset0; while( cstart<subset1 ) { // // Determine size of current chunk and copy it to PBuf.XY // csize = Math.Min(subset1, cstart+pbuf.chunksize)-cstart; for(j=0; j<=csize-1; j++) { srcidx = -1; if( subsettype==0 ) { srcidx = cstart+j; } if( subsettype==1 ) { srcidx = idx[cstart+j]; } alglib.ap.assert(srcidx>=0, "MLPAllErrorsX: internal error"); if( datasettype==0 ) { for(i_=0; i_<=rowsize-1;i_++) { pbuf.xy[j,i_] = densexy[srcidx,i_]; } } if( datasettype==1 ) { sparse.sparsegetrow(sparsexy, srcidx, ref pbuf.xyrow); for(i_=0; i_<=rowsize-1;i_++) { pbuf.xy[j,i_] = pbuf.xyrow[i_]; } } } // // Unpack XY and process (temporary code, to be replaced by chunked processing) // for(j=0; j<=csize-1; j++) { for(i_=0; i_<=rowsize-1;i_++) { pbuf.xy2[j,i_] = pbuf.xy[j,i_]; } } mlpchunkedprocess(network, pbuf.xy2, 0, csize, pbuf.batch4buf, pbuf.hpcbuf); for(j=0; j<=csize-1; j++) { for(i_=0; i_<=nin-1;i_++) { pbuf.x[i_] = pbuf.xy2[j,i_]; } i1_ = (nin) - (0); for(i_=0; i_<=nout-1;i_++) { pbuf.y[i_] = pbuf.xy2[j,i_+i1_]; } if( iscls ) { pbuf.desiredy[0] = pbuf.xy[j,nin]; } else { i1_ = (nin) - (0); for(i_=0; i_<=nout-1;i_++) { pbuf.desiredy[i_] = pbuf.xy[j,i_+i1_]; } } bdss.dserraccumulate(ref pbuf.tmp0, pbuf.y, pbuf.desiredy); } // // Process chunk and advance line pointer // cstart = cstart+pbuf.chunksize; } bdss.dserrfinish(ref pbuf.tmp0); rep.relclserror = pbuf.tmp0[0]; rep.avgce = pbuf.tmp0[1]/Math.Log(2); rep.rmserror = pbuf.tmp0[2]; rep.avgerror = pbuf.tmp0[3]; rep.avgrelerror = pbuf.tmp0[4]; // // Recycle // alglib.smp.ae_shared_pool_recycle(buf, ref pbuf); }
/************************************************************************* Calculation of all types of errors on subset of dataset. FOR USERS OF COMMERCIAL EDITION: ! Commercial version of ALGLIB includes two important improvements of ! this function: ! * multicore support (C++ and C# computational cores) ! * SSE support ! ! First improvement gives close-to-linear speedup on multicore systems. ! Second improvement gives constant speedup (2-3x depending on your CPU) ! ! In order to use multicore features you have to: ! * use commercial version of ALGLIB ! * call this function with "smp_" prefix, which indicates that ! multicore code will be used (for multicore support) ! ! In order to use SSE features you have to: ! * use commercial version of ALGLIB on Intel processors ! * use C++ computational core ! ! This note is given for users of commercial edition; if you use GPL ! edition, you still will be able to call smp-version of this function, ! but all computations will be done serially. ! ! We recommend you to carefully read ALGLIB Reference Manual, section ! called 'SMP support', before using parallel version of this function. INPUT PARAMETERS: Network - network initialized with one of the network creation funcs XY - original dataset given by sparse matrix; one sample = one row; first NIn columns contain inputs, next NOut columns - desired outputs. SetSize - real size of XY, SetSize>=0; Subset - subset of SubsetSize elements, array[SubsetSize]; SubsetSize- number of elements in Subset[] array: * if SubsetSize>0, rows of XY with indices Subset[0]... ...Subset[SubsetSize-1] are processed * if SubsetSize=0, zeros are returned * if SubsetSize<0, entire dataset is processed; Subset[] array is ignored in this case. OUTPUT PARAMETERS: Rep - it contains all type of errors. -- ALGLIB -- Copyright 04.09.2012 by Bochkanov Sergey *************************************************************************/ public static void mlpallerrorssparsesubset(multilayerperceptron network, sparse.sparsematrix xy, int setsize, int[] subset, int subsetsize, modelerrors rep) { int idx0 = 0; int idx1 = 0; int idxtype = 0; alglib.ap.assert(sparse.sparseiscrs(xy), "MLPAllErrorsSparseSubset: XY is not in CRS format."); alglib.ap.assert(sparse.sparsegetnrows(xy)>=setsize, "MLPAllErrorsSparseSubset: XY has less than SetSize rows"); if( setsize>0 ) { if( mlpissoftmax(network) ) { alglib.ap.assert(sparse.sparsegetncols(xy)>=mlpgetinputscount(network)+1, "MLPAllErrorsSparseSubset: XY has less than NIn+1 columns"); } else { alglib.ap.assert(sparse.sparsegetncols(xy)>=mlpgetinputscount(network)+mlpgetoutputscount(network), "MLPAllErrorsSparseSubset: XY has less than NIn+NOut columns"); } } if( subsetsize>=0 ) { idx0 = 0; idx1 = subsetsize; idxtype = 1; } else { idx0 = 0; idx1 = setsize; idxtype = 0; } mlpallerrorsx(network, network.dummydxy, xy, setsize, 1, subset, idx0, idx1, idxtype, network.buf, rep); }
/************************************************************************* Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. *************************************************************************/ public static void _pexec_mlpallerrorssparsesubset(multilayerperceptron network, sparse.sparsematrix xy, int setsize, int[] subset, int subsetsize, modelerrors rep) { mlpallerrorssparsesubset(network,xy,setsize,subset,subsetsize,rep); }
/************************************************************************* Single-threaded stub. HPC ALGLIB replaces it by multithreaded code. *************************************************************************/ public static void _pexec_mlpallerrorssubset(multilayerperceptron network, double[,] xy, int setsize, int[] subset, int subsetsize, modelerrors rep) { mlpallerrorssubset(network,xy,setsize,subset,subsetsize,rep); }
/************************************************************************* Calculation of all types of errors on subset of dataset. FOR USERS OF COMMERCIAL EDITION: ! Commercial version of ALGLIB includes two important improvements of ! this function: ! * multicore support (C++ and C# computational cores) ! * SSE support ! ! First improvement gives close-to-linear speedup on multicore systems. ! Second improvement gives constant speedup (2-3x depending on your CPU) ! ! In order to use multicore features you have to: ! * use commercial version of ALGLIB ! * call this function with "smp_" prefix, which indicates that ! multicore code will be used (for multicore support) ! ! In order to use SSE features you have to: ! * use commercial version of ALGLIB on Intel processors ! * use C++ computational core ! ! This note is given for users of commercial edition; if you use GPL ! edition, you still will be able to call smp-version of this function, ! but all computations will be done serially. ! ! We recommend you to carefully read ALGLIB Reference Manual, section ! called 'SMP support', before using parallel version of this function. INPUT PARAMETERS: Network - network initialized with one of the network creation funcs XY - original dataset; one sample = one row; first NIn columns contain inputs, next NOut columns - desired outputs. SetSize - real size of XY, SetSize>=0; Subset - subset of SubsetSize elements, array[SubsetSize]; SubsetSize- number of elements in Subset[] array: * if SubsetSize>0, rows of XY with indices Subset[0]... ...Subset[SubsetSize-1] are processed * if SubsetSize=0, zeros are returned * if SubsetSize<0, entire dataset is processed; Subset[] array is ignored in this case. OUTPUT PARAMETERS: Rep - it contains all type of errors. -- ALGLIB -- Copyright 04.09.2012 by Bochkanov Sergey *************************************************************************/ public static void mlpallerrorssubset(multilayerperceptron network, double[,] xy, int setsize, int[] subset, int subsetsize, modelerrors rep) { int idx0 = 0; int idx1 = 0; int idxtype = 0; alglib.ap.assert(alglib.ap.rows(xy)>=setsize, "MLPAllErrorsSubset: XY has less than SetSize rows"); if( setsize>0 ) { if( mlpissoftmax(network) ) { alglib.ap.assert(alglib.ap.cols(xy)>=mlpgetinputscount(network)+1, "MLPAllErrorsSubset: XY has less than NIn+1 columns"); } else { alglib.ap.assert(alglib.ap.cols(xy)>=mlpgetinputscount(network)+mlpgetoutputscount(network), "MLPAllErrorsSubset: XY has less than NIn+NOut columns"); } } if( subsetsize>=0 ) { idx0 = 0; idx1 = subsetsize; idxtype = 1; } else { idx0 = 0; idx1 = setsize; idxtype = 0; } mlpallerrorsx(network, xy, network.dummysxy, setsize, 0, subset, idx0, idx1, idxtype, network.buf, rep); }
public override void init() { hllayersizes = new int[0]; hlconnections = new int[0]; hlneurons = new int[0]; structinfo = new int[0]; weights = new double[0]; columnmeans = new double[0]; columnsigmas = new double[0]; neurons = new double[0]; dfdnet = new double[0]; derror = new double[0]; x = new double[0]; y = new double[0]; xy = new double[0,0]; xyrow = new double[0]; nwbuf = new double[0]; integerbuf = new int[0]; err = new modelerrors(); rndbuf = new double[0]; buf = new alglib.smp.shared_pool(); gradbuf = new alglib.smp.shared_pool(); dummydxy = new double[0,0]; dummysxy = new sparse.sparsematrix(); dummyidx = new int[0]; dummypool = new alglib.smp.shared_pool(); }
public override alglib.apobject make_copy() { modelerrors _result = new modelerrors(); _result.relclserror = relclserror; _result.avgce = avgce; _result.rmserror = rmserror; _result.avgerror = avgerror; _result.avgrelerror = avgrelerror; return _result; }
/************************************************************************* Calculation of all types of errors. INPUT PARAMETERS: Network - network initialized with one of the network creation funcs XY - original dataset given by sparse matrix; one sample = one row; first NIn columns contain inputs, next NOut columns - desired outputs. SetSize - real size of XY, SetSize>=0; Subset - subset of SubsetSize elements, array[SubsetSize]; SubsetSize- number of elements in Subset[] array. OUTPUT PARAMETERS: Rep - it contains all type of errors. NOTE: when SubsetSize<0 is used full dataset by call MLPGradBatch function. -- ALGLIB -- Copyright 04.09.2012 by Bochkanov Sergey *************************************************************************/ public static void mlpallerrorssparsesubset(multilayerperceptron network, sparse.sparsematrix xy, int setsize, int[] subset, int subsetsize, modelerrors rep) { double[] buf = new double[0]; double[] dy = new double[0]; int rowsize = 0; int nin = 0; int nout = 0; int wcount = 0; bool iscls = new bool(); int i = 0; int i_ = 0; int i1_ = 0; alglib.ap.assert(setsize>=0, "MLPAllErrorsSparseSubset: SetSize<0"); mlpproperties(network, ref nin, ref nout, ref wcount); iscls = mlpissoftmax(network); // // Estimate error using subset of training set. // apserv.rvectorsetlengthatleast(ref network.x, nin); if( iscls ) { rowsize = nin+1; apserv.rvectorsetlengthatleast(ref network.y, 1); dy = new double[1]; bdss.dserrallocate(nout, ref buf); } else { rowsize = nin+nout; apserv.rvectorsetlengthatleast(ref network.y, nout); dy = new double[nout]; bdss.dserrallocate(-nout, ref buf); } if( subsetsize<0 ) { for(i=0; i<=setsize-1; i++) { sparse.sparsegetrow(xy, i, ref network.xyrow); for(i_=0; i_<=nin-1;i_++) { network.x[i_] = network.xyrow[i_]; } mlpprocess(network, network.x, ref network.y); if( iscls ) { dy[0] = network.xyrow[nin]; } else { i1_ = (nin) - (0); for(i_=0; i_<=nout-1;i_++) { dy[i_] = network.xyrow[i_+i1_]; } } bdss.dserraccumulate(ref buf, network.y, dy); } } else { for(i=0; i<=subsetsize-1; i++) { sparse.sparsegetrow(xy, subset[i], ref network.xyrow); for(i_=0; i_<=nin-1;i_++) { network.x[i_] = network.xyrow[i_]; } mlpprocess(network, network.x, ref network.y); if( iscls ) { dy[0] = network.xyrow[nin]; } else { i1_ = (nin) - (0); for(i_=0; i_<=nout-1;i_++) { dy[i_] = network.xyrow[i_+i1_]; } } bdss.dserraccumulate(ref buf, network.y, dy); } } bdss.dserrfinish(ref buf); rep.relclserror = buf[0]; rep.avgce = buf[1]; rep.rmserror = buf[2]; rep.avgerror = buf[3]; rep.avgrelerror = buf[4]; }