libeblearn
|
00001 /*************************************************************************** 00002 * Copyright (C) 2008 by Yann LeCun, Pierre Sermanet, Koray Kavukcuoglu * 00003 * yann@cs.nyu.edu, pierre.sermanet@gmail.com, koray@cs.nyu.edu * 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * * Redistributions of source code must retain the above copyright 00008 * notice, this list of conditions and the following disclaimer. 00009 * * Redistributions in binary form must reproduce the above copyright 00010 * notice, this list of conditions and the following disclaimer in the 00011 * documentation and/or other materials provided with the distribution. 00012 * * Redistribution under a license not approved by the Open Source 00013 * Initiative (http://www.opensource.org) must display the 00014 * following acknowledgement in all advertising material: 00015 * This product includes software developed at the Courant 00016 * Institute of Mathematical Sciences (http://cims.nyu.edu). 00017 * * The names of the authors may not be used to endorse or promote products 00018 * derived from this software without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 00021 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00022 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00023 * DISCLAIMED. IN NO EVENT SHALL ThE AUTHORS BE LIABLE FOR ANY 00024 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00025 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00026 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00027 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00029 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 ***************************************************************************/ 00031 00032 using namespace std; 00033 00034 namespace ebl { 00035 00036 template <class T> 00037 module_tester<T>::module_tester(double thres_, T rrange_min_, T rrange_max_, 00038 FILE* out_) 00039 : acc_thres(thres_), rrange_min(rrange_min_), rrange_max(rrange_max_), 00040 out(out_), 00041 jac_fprop(1,1), jac_bprop(1,1), jac_pfprop(1,1), jac_pbprop(1,1), 00042 hes_fprop(1,1), hes_bprop(1,1), hes_pfprop(1,1), hes_pbprop(1,1) { 00043 dynamic_init_drand(); 00044 } 00045 00046 template <class T> 00047 module_tester<T>::~module_tester() { 00048 } 00049 00050 template <class T> 00051 idx<double> module_tester<T>:: 00052 test_jacobian(module_1_1<T> &module, bbstate_idx<T> &in, 00053 bbstate_idx<T> &out) { 00054 forget_param_linear fp(2,0.5); 00055 idx_random(in.x, rrange_min, rrange_max); // randomize input for fprop 00056 module.fprop(in,out); // just to resize states 00057 module.forget(fp); // randomize parametes if there are any 00058 // clear all input and output 00059 in.clear(); 00060 in.clear_dx(); 00061 in.clear_ddx(); 00062 out.clear(); 00063 out.clear_dx(); 00064 out.clear_ddx(); 00065 idx_random(in.x, rrange_min, rrange_max); // randomize input for fprop 00066 // EDEBUG("in: " << in.x.str() << " out: " << out.x.str()); 00067 get_jacobian_fprop(module, in, out, jac_fprop); 00068 get_jacobian_bprop(module, in, out, jac_bprop); 00069 // EDEBUG(" jac_fprop: " << jac_fprop.str() 00070 // << " jac_bprop " << jac_bprop.str()); 00071 return get_errs(jac_fprop,jac_bprop); 00072 } 00073 00074 template <class T> 00075 idx<double> module_tester<T>:: 00076 test_jacobian_param(parameter<bbstate_idx<T> > &p, module_1_1<T> &module, 00077 bbstate_idx<T> &in, bbstate_idx<T> &out) { 00078 forget_param_linear fp(2,0); 00079 idx_random(in.x, rrange_min, rrange_max); // randomize input for fprop 00080 module.fprop(in,out); // just to resize states 00081 module.forget(fp); // randomize parametes if there are any 00082 // clear all input and output 00083 in.clear(); 00084 in.clear_dx(); 00085 in.clear_ddx(); 00086 out.clear(); 00087 out.clear_dx(); 00088 out.clear_ddx(); 00089 idx_random(p.x, rrange_min, rrange_max); // randomize input for fprop 00090 idx_random(in.x, rrange_min, rrange_max); 00091 get_jacobian_fprop_param(p, module, in, out, jac_pfprop); 00092 in.clear_dx(); 00093 get_jacobian_bprop_param(p, module, in, out, jac_pbprop); 00094 return get_errs(jac_pfprop, jac_pbprop); 00095 } 00096 00097 00098 template <class T> 00099 idx<double> module_tester<T>:: 00100 test_hessian(module_1_1<T> &module, bbstate_idx<T> &in, 00101 bbstate_idx<T> &out) { 00102 forget_param_linear fp(2,0.5); 00103 idx_random(in.x, rrange_min, rrange_max); // randomize input for fprop 00104 module.fprop(in,out); // just to resize states 00105 module.forget(fp); // randomize parametes if there are any 00106 // clear all input and output 00107 in.clear(); 00108 in.clear_dx(); 00109 in.clear_ddx(); 00110 out.clear(); 00111 out.clear_dx(); 00112 out.clear_ddx(); 00113 idx_random(in.x, rrange_min, rrange_max); // randomize input for fprop 00114 get_hessian_fprop(module, in, out, hes_fprop); 00115 get_hessian_bprop(module, in, out, hes_bprop); 00116 return get_errs(hes_fprop, hes_bprop); 00117 } 00118 00119 template <class T> 00120 idx<double> module_tester<T>:: 00121 test_hessian_param(parameter<bbstate_idx<T> > &p, module_1_1<T> &module, 00122 bbstate_idx<T> &in, bbstate_idx<T> &out) { 00123 forget_param_linear fp(2,0); 00124 idx_random(in.x, rrange_min, rrange_max); // randomize input for fprop 00125 module.fprop(in,out); // just to resize states 00126 module.forget(fp); // randomize parametes if there are any 00127 // clear all input and output 00128 in.clear(); 00129 in.clear_dx(); 00130 in.clear_ddx(); 00131 out.clear(); 00132 out.clear_dx(); 00133 out.clear_ddx(); 00134 idx_random(p.x, rrange_min, rrange_max); // randomize input for fprop 00135 idx_random(in.x, rrange_min, rrange_max); 00136 get_hessian_fprop_param(p, module, in, out, hes_pfprop); 00137 in.clear_dx(); 00138 get_hessian_bprop_param(p, module, in, out, hes_pbprop); 00139 return get_errs(hes_pfprop, hes_pbprop); 00140 } 00141 00142 template <class T> 00143 double module_tester<T>::get_acc_thres() const { 00144 return acc_thres; 00145 } 00146 00147 template <class T> 00148 void module_tester<T>::set_acc_thres(double acc_thres_) { 00149 acc_thres = acc_thres_; 00150 } 00151 00152 template <class T> 00153 T module_tester<T>::get_rrange() const { 00154 return rrange_max; 00155 } 00156 00157 template <class T> 00158 void module_tester<T>::set_rrange(T rrange) { 00159 rrange_min = -rrange; 00160 rrange_max = rrange; 00161 } 00162 00163 template <class T> 00164 FILE* module_tester<T>::get_out() const { 00165 return out; 00166 } 00167 00168 template <class T> 00169 void module_tester<T>::set_out(FILE* out) { 00170 this->out = out; 00171 } 00172 00173 // protected members ///////////////////////////////////////////////////////// 00174 00175 template <class T> 00176 void module_tester<T>:: 00177 get_jacobian_fprop(module_1_1<T> &module, bbstate_idx<T> &in, 00178 bbstate_idx<T> &out, idx<T>& jac) { 00179 bbstate_idx<T> sina = in.make_copy(); //x-small 00180 bbstate_idx<T> sinb = in.make_copy(); //x+small 00181 bbstate_idx<T> souta = out.make_copy(); //f(x-small) 00182 bbstate_idx<T> soutb = out.make_copy(); //f(x+small) 00183 T small = 1e-6; 00184 int cnt = 0; 00185 // clear out jacobian matrix 00186 jac.resize(in.size(), out.size()); 00187 idx_clear(jac); 00188 idx_aloop3(sx, in.x, T, sxa, sina.x, T, sxb, sinb.x, T) { 00189 idx_copy(in.x, sina.x); 00190 idx_copy(in.x, sinb.x); 00191 // perturb 00192 *sxa = *sx - small; 00193 *sxb = *sx + small; 00194 00195 // idx_addc(in.x, -small, sina.x); 00196 // idx_addc(in.x, small, sinb.x); 00197 // perturb 00198 // T t0 = *sx; 00199 // T t1 = t0 - small; 00200 // T t2 = t0 + small; 00201 // double t3 = (double) t2 - (double) t1; 00202 // cout << "t0 " << t0 << " t1 " << t1 << " t2 " << t2 << " t3 " << t3 << endl; 00203 // *sxa = *sx - small; 00204 // cout << "sina: " << sina.x.gget() << " souta: " << souta.x.gget() <<endl; 00205 // cout << "sinb: " << sinb.x.gget() << " soutb: " << soutb.x.gget() <<endl; 00206 // idx_sub(sinb.x, sina.x, soutb.x); 00207 // // cout << "diff: " << soutb.x.gget() <<endl; 00208 // idx_clear(souta.x); 00209 // idx_clear(soutb.x); 00210 00211 module.fprop(sina, souta); 00212 // *sxb = *sxa + 2 * small; 00213 module.fprop(sinb, soutb); 00214 idx_sub(soutb.x, souta.x, soutb.x); 00215 // cout << "diff: " << soutb.x.gget() <<endl; 00216 idx<T> j = jac.select(0, cnt); 00217 idx_dotc(soutb.x, (T) (1.0 / (2 * small)), j); 00218 // cout << "1/2small: " << (T) (1.0 / (2 * small)) <<endl; 00219 // cout << "soutbx: " << soutb.x.gget() <<endl; 00220 // cout << "soutbx/2small: " << (soutb.x.gget() / (2 * small)) <<endl; 00221 // cout << "jac: " << (T) jac.gget() << endl; 00222 cnt++; 00223 } 00224 } 00225 00226 template <class T> 00227 void module_tester<T>:: 00228 get_jacobian_fprop_param(parameter<bbstate_idx<T> > &p, module_1_1<T> &module, 00229 bbstate_idx<T> &in, bbstate_idx<T> &out, 00230 idx<T>& jac) { 00231 bbstate_idx<T> souta = out.make_copy(); //f(x-small) 00232 bbstate_idx<T> soutb = out.make_copy(); //f(x+small) 00233 T small = 1e-6; 00234 int cnt = 0; 00235 // clear out jacobian matrix 00236 idx_clear(jac); 00237 { idx_aloop1(px, p.x, T) { 00238 // perturb 00239 *px = *px - small; 00240 module.fprop(in, souta); 00241 *px = *px + 2*small; 00242 module.fprop(in, soutb); 00243 *px = *px - small; 00244 idx_sub(soutb.x,souta.x,soutb.x); 00245 idx<T> j = jac.select(0,cnt); 00246 idx_dotc(soutb.x,1.0/(2*small),j); 00247 cnt++; 00248 }} 00249 } 00250 00251 template <class T> 00252 void module_tester<T>:: 00253 get_jacobian_bprop(module_1_1<T> &module, bbstate_idx<T> &in, 00254 bbstate_idx<T> &out, idx<T>& jac) { 00255 jac.resize(in.size(), out.size()); 00256 idx_clear(jac); 00257 int cnt = 0; 00258 idx_aloop1(dx, out.dx,T) { 00259 idx_clear(out.dx); 00260 idx_clear(in.dx); 00261 *dx = (T) 1.0; 00262 module.bprop(in, out); 00263 idx<T> j = jac.select(1, cnt); 00264 idx_copy(in.dx, j); 00265 cnt++; 00266 } 00267 //cout << "jac bprop: " << (T) jac.gget() << endl; 00268 } 00269 00270 template <class T> 00271 void module_tester<T>:: 00272 get_jacobian_bprop_param(parameter<bbstate_idx<T> > &p, module_1_1<T> &module, 00273 bbstate_idx<T> &in, bbstate_idx<T> &out, 00274 idx<T>& jac) { 00275 eblerror("not implemented"); 00276 } 00277 00278 template <class T> 00279 void module_tester<T>:: 00280 get_hessian_fprop(module_1_1<T> &module, bbstate_idx<T> &in, 00281 bbstate_idx<T> &out, idx<T> &jac) { 00282 bbstate_idx<T> sina = in.make_copy(); //x-small 00283 bbstate_idx<T> sinb = in.make_copy(); //x+small 00284 bbstate_idx<T> souta = out.make_copy(); //f(x-small) 00285 bbstate_idx<T> soutb = out.make_copy(); //f(x+small) 00286 double small = 1e-6; 00287 int cnt = 0; 00288 // clear out hessian matrix 00289 jac.resize(in.size(), out.size()); 00290 idx_clear(jac); 00291 idx_aloop3(sx, in.x, T, sxa, sina.x, T, sxb, sinb.x, T) { 00292 idx_copy(in.x, sina.x); 00293 idx_copy(in.x, sinb.x); 00294 // perturb 00295 *sxa = *sx - small; 00296 *sxb = *sx + small; 00297 module.fprop(sina, souta); 00298 module.fprop(sinb, soutb); 00299 idx<T> ad(souta.x.get_idxdim()); 00300 idx<T> dot(souta.x.get_idxdim()); 00301 idx<T> sub(souta.x.get_idxdim()); 00302 idx_add(souta.x, soutb.x, ad); 00303 idx_dotc(out.x, 2, dot); 00304 idx_sub(ad, dot, sub); 00305 idx<T> j = jac.select(0, cnt); 00306 idx_dotc(sub, 1.0 / small, j); 00307 cnt++; 00308 } 00309 } 00310 00311 template <class T> 00312 void module_tester<T>:: 00313 get_hessian_fprop_param(parameter<bbstate_idx<T> > &p, module_1_1<T> &module, 00314 bbstate_idx<T> &in, bbstate_idx<T> &out, idx<T>& jac){ 00315 bbstate_idx<T> souta = out.make_copy(); //f(x-small) 00316 bbstate_idx<T> soutb = out.make_copy(); //f(x+small) 00317 double small = 1e-6; 00318 int cnt = 0; 00319 // clear out hessian matrix 00320 idx_clear(jac); 00321 { idx_aloop1(px, p.x, T) { 00322 // perturb 00323 *px = *px - small; 00324 module.fprop(in, souta); 00325 *px = *px + 2*small; 00326 module.fprop(in, soutb); 00327 *px = *px - small; 00328 idx_sub(soutb.x,souta.x,soutb.x); 00329 idx<T> j = jac.select(0,cnt); 00330 idx_dotc(soutb.x,1.0/(2*small),j); 00331 cnt++; 00332 }} 00333 } 00334 00335 template <class T> 00336 void module_tester<T>:: 00337 get_hessian_bprop(module_1_1<T> &module, bbstate_idx<T> &in, 00338 bbstate_idx<T> &out, idx<T>& jac) { 00339 jac.resize(in.size(), out.size()); 00340 idx_clear(jac); 00341 // module.fprop(in, out); 00342 // module.bprop(in, out); 00343 // module.bbprop(in, out); 00344 // idx_copy(in.ddx, jac); 00345 00346 int cnt = 0; 00347 idx_aloop1(ddx, out.ddx,T) { 00348 idx_clear(out.ddx); 00349 idx_clear(in.ddx); 00350 // *ddx = 1.0; 00351 module.bbprop(in, out); 00352 idx<T> j = jac.select(1, cnt); 00353 idx_copy(in.ddx, j); 00354 cnt++; 00355 } 00356 } 00357 00358 template <class T> 00359 void module_tester<T>:: 00360 get_hessian_bprop_param(parameter<bbstate_idx<T> > &p, module_1_1<T> &module, 00361 bbstate_idx<T> &in, bbstate_idx<T> &out, idx<T>& jac){ 00362 eblerror("not implemented"); 00363 } 00364 00365 template <class T> 00366 idx<double> module_tester<T>::get_errs(idx<T>& a, idx<T>& b) { 00367 double maxdist; 00368 // max distance 00369 idx_sub(a,b,a); 00370 idx_abs(a,a); 00371 double totdist = idx_sum(a); 00372 maxdist = (double) idx_max(a); 00373 idx<double> errs(2); 00374 errs.set(maxdist, 0); 00375 errs.set(totdist, 1); 00376 return errs; 00377 } 00378 00379 template <class T> 00380 void module_tester<T>::report_err(idx<T>& a, idx<T>& b, const char* msg) { 00381 idx<double> errs = get_errs(a, b); 00382 stringstream ss(stringstream::in | stringstream::out); 00383 // report results 00384 ss << "Max " << msg << " distance"; 00385 fprintf(this->out,"%-40s = %-15g %15s\n",ss.str().c_str(), errs.get(0), 00386 ((errs.get(0) < this->acc_thres)?"OK":"NOT OK")); 00387 ss.str(""); 00388 ss << "Total " << msg << "distance"; 00389 fprintf(this->out,"%-40s = %-15g %15s\n",ss.str().c_str(), errs.get(1), 00390 ((errs.get(1) < this->acc_thres)?"OK":"NOT OK")); 00391 fflush(this->out); 00392 } 00393 00395 00396 template <class T> 00397 void Jacobian_tester<T>::test(module_1_1<T> &module) { 00398 int insize = 16; 00399 bbstate_idx<T> in(insize, 1, 1); 00400 bbstate_idx<T> out(insize, 1, 1); 00401 00402 //init 00403 dseed(2); // 2 is chosen randomly... feel free to change it 00404 module.fprop(in, out); // used to resize the outputs 00405 { idx_bloop1( i, in.x, T) 00406 { idx_bloop1 (ii, i, T) 00407 { idx_bloop1( iii, ii, T) 00408 { iii.set(drand(2)); } 00409 } 00410 } 00411 } 00412 { idx_bloop1( o, out.x, T) 00413 { idx_bloop1 (oo, o, T) 00414 { idx_bloop1( ooo, oo, T) 00415 { ooo.set(drand(2)); } 00416 } 00417 } 00418 } 00419 00420 // check the Jacobian 00421 int ndim_in = in.x.nelements(); 00422 int ndim_out = in.x.nelements(); 00423 // used to store the jacobian calculated via bprop 00424 idx<T> jac_fprop(ndim_in, ndim_out); 00425 // used to store the jacobian calculated via prturbations 00426 idx<T> jac_bprop(ndim_in, ndim_out); 00427 00428 // creation of jac_fprop 00429 module.fprop(in, out); 00430 int cnt = 0; 00431 { idx_bloop1(o, out.x, T) 00432 { idx_bloop1(oo, o, T) 00433 { idx_bloop1(ooo, oo, T) 00434 { 00435 out.clear_dx(); 00436 in.clear_dx(); 00437 ooo.set(1); 00438 module.bprop(in, out); 00439 idx<T> bla = jac_bprop.select(1, cnt); 00440 idx_copy(in.dx, bla); 00441 cnt++; 00442 } 00443 } 00444 } 00445 } 00446 00447 // creation of jac_bprop 00448 cnt = 0; 00449 double small = pow(10.0, -6); 00450 bbstate_idx<T> in1(in.x.dim(0), in.x.dim(1), in.x.dim(2)); 00451 bbstate_idx<T> in2(in.x.dim(0), in.x.dim(1), in.x.dim(2)); 00452 bbstate_idx<T> out1(1, 1, 1); 00453 bbstate_idx<T> out2(1, 1, 1); 00454 for(int d1 = 0; d1 < in.x.dim(0); d1++){ 00455 for(int d2 = 0; d2 < in.x.dim(1); d2++){ 00456 for(int d3 = 0; d3 < in.x.dim(2); d3++){ 00457 idx_copy(in.x, in1.x); 00458 idx_copy(in.x, in2.x); 00459 in1.x.set(in1.x.get( d1, d2, d3) + small, d1, d2, d3); 00460 in2.x.set(in2.x.get( d1, d2, d3) - small, d1, d2, d3); 00461 module.fprop(in1, out1); 00462 module.fprop(in2, out2); 00463 idx<T> sub(new srg<T>(), out1.x.spec); 00464 idx<T> dot(new srg<T>(), out1.x.spec); 00465 idx_sub(out1.x, out2.x, sub); 00466 idx_dotc(sub, 0.5/small, dot); 00467 idx<T> bla2 = jac_fprop.select(0, cnt); 00468 idx_copy(dot, bla2); 00469 cnt++; 00470 } 00471 } 00472 } 00473 00474 // comparison 00475 printf("Jacobian error: %8.7e\n", idx_sqrdist(jac_fprop, jac_bprop)); 00476 } 00477 00479 00480 template <class T> 00481 void Bbprop_tester<T>::test(module_1_1<T> &module){ 00482 00483 int insize = 16; 00484 bbstate_idx<T> in(insize, 1, 1); 00485 bbstate_idx<T> out(insize, 1, 1); 00486 00487 //init 00488 dseed(2); // 2 is chosen randomly... feel free to change it 00489 module.fprop(in, out); // used to resize the outputs 00490 { idx_bloop1( i, in.x, T) 00491 { idx_bloop1 (ii, i, T) 00492 { idx_bloop1( iii, ii, T) 00493 { iii.set(drand(2)); } 00494 } 00495 } 00496 } 00497 { idx_bloop1( o, out.x, T) 00498 { idx_bloop1 (oo, o, T) 00499 { idx_bloop1( ooo, oo, T) 00500 { ooo.set(drand(2)); } 00501 } 00502 } 00503 } 00504 00505 module.fprop(in, out); 00506 module.bprop(in, out); 00507 module.bbprop(in, out); 00508 00509 // used to store the bbprop calculated via perturbation 00510 idx<T> bbprop_p(in.x.dim(0), in.x.dim(1), in.x.dim(2)); 00511 00512 // creation of bbprop_p 00513 int cnt = 0; 00514 double small = pow(10.0, -6); 00515 bbstate_idx<T> in1(in.x.dim(0), in.x.dim(1), in.x.dim(2)); 00516 bbstate_idx<T> in2(in.x.dim(0), in.x.dim(1), in.x.dim(2)); 00517 bbstate_idx<T> out1( 1, 1, 1); 00518 bbstate_idx<T> out2( 1, 1, 1); 00519 for(int d1 = 0; d1 < in.x.dim(0); d1++){ 00520 for(int d2 = 0; d2 < in.x.dim(1); d2++){ 00521 for(int d3 = 0; d3 < in.x.dim(2); d3++){ 00522 idx_copy(in.x, in1.x); 00523 idx_copy(in.x, in2.x); 00524 in1.x.set(in1.x.get( d1, d2, d3) + small, d1, d2, d3); 00525 in2.x.set(in2.x.get( d1, d2, d3) - small, d1, d2, d3); 00526 module.fprop(in1, out1); 00527 module.fprop(in2, out2); 00528 // here we calculate a in aX²+bX+c as a model for the 3 points 00529 // calculated via 00530 // fprop(...), fprop(...+small) and fprop(...-small). the second 00531 // derivative is then 2*a 00532 idx<T> ad(new srg<T>(), out1.x.spec); 00533 idx<T> sub(new srg<T>(), out1.x.spec); 00534 idx<T> dot(new srg<T>(), out1.x.spec); 00535 idx<T> dot2(new srg<T>(), out1.x.spec); 00536 idx_add(out1.x, out2.x, ad); 00537 idx_dotc(out.x, 2, dot); 00538 idx_sub(ad, dot, sub); 00539 idx_dotc(sub, 1/small, dot2); 00540 bbprop_p.set(dot2.get( d1, d2, d3), d1, d2, d3); 00541 cnt++; 00542 } 00543 } 00544 } 00545 00546 // comparison 00547 printf("bbprop error: %8.7e \n", idx_sqrdist(in.ddx, bbprop_p)); 00548 } 00549 00551 00552 template <class T> 00553 void Bprop_tester<T>::test(module_1_1<T> &module){ 00554 00555 int insize = 16; 00556 bbstate_idx<T> in(insize, 1, 1); 00557 bbstate_idx<T> out(insize, 1, 1); 00558 00559 //init 00560 dseed(2); // 2 is chosen randomly... feel free to change it 00561 module.fprop(in, out); // used to resize the outputs 00562 { idx_bloop1( i, in.x, T) 00563 { idx_bloop1 (ii, i, T) 00564 { idx_bloop1( iii, ii, T) 00565 { iii.set(drand(2)); } 00566 } 00567 } 00568 } 00569 { idx_bloop1( o, out.x, T) 00570 { idx_bloop1 (oo, o, T) 00571 { idx_bloop1( ooo, oo, T) 00572 { ooo.set(drand(2)); } 00573 } 00574 } 00575 } 00576 00577 // used to store the bbprop calculated via perturbation 00578 idx<T> bprop_p(in.x.dim(0), in.x.dim(1), in.x.dim(2)); 00579 00580 // creation of bprop_p 00581 int cnt = 0; 00582 double small = pow(10.0, -6); 00583 bbstate_idx<T> in1(in.x.dim(0), in.x.dim(1), in.x.dim(2)); 00584 bbstate_idx<T> in2(in.x.dim(0), in.x.dim(1), in.x.dim(2)); 00585 bbstate_idx<T> out1(1, 1, 1); 00586 bbstate_idx<T> out2(1, 1, 1); 00587 for(int d1 = 0; d1 < in.x.dim(0); d1++){ 00588 for(int d2 = 0; d2 < in.x.dim(1); d2++){ 00589 for(int d3 = 0; d3 < in.x.dim(2); d3++){ 00590 idx_copy(in.x, in1.x); 00591 idx_copy(in.x, in2.x); 00592 in1.x.set(in1.x.get( d1, d2, d3) + small, d1, d2, d3); 00593 in2.x.set(in2.x.get( d1, d2, d3) - small, d1, d2, d3); 00594 module.fprop(in1, out1); 00595 module.fprop(in2, out2); 00596 00597 idx<T> sub(new srg<T>(), out1.x.spec); 00598 idx<T> dot(new srg<T>(), out1.x.spec); 00599 idx_sub(out1.x, out2.x, sub); 00600 idx_dotc(sub, 0.5/small, dot); 00601 bprop_p.set(dot.get( d1, d2, d3), d1, d2, d3); 00602 cnt++; 00603 } 00604 } 00605 } 00606 00607 printf("Bprop error : %8.7e \n", idx_sqrdist(in.dx, bprop_p)); 00608 } 00609 00610 } // end namespace ebl