00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "Gist/FFN.H"
00046 #include "Image/MatrixOps.H"
00047 #include "Image/CutPaste.H"
00048 #include "Util/log.H"
00049
00050
00051
00052
00053
00054
00055
00056
00057 FeedForwardNetwork::FeedForwardNetwork()
00058 { }
00059
00060
00061 FeedForwardNetwork::~FeedForwardNetwork()
00062 { }
00063
00064
00065
00066 void FeedForwardNetwork::inPlaceSigmoid(Image<double>& dst)
00067 {
00068 Image<double>::iterator aptr = dst.beginw(), stop = dst.endw();
00069
00070 while (aptr != stop) {
00071 double val;
00072 if(*aptr > 30.0) val = 1.0;
00073 else if(*aptr < -30.0) val = 0.0;
00074 else val = 1.0 / (1.0 + exp(-1.0 * (*aptr)));
00075 *aptr++ = val;
00076 }
00077 }
00078
00079
00080
00081 void FeedForwardNetwork::init
00082 (int inunits, int hidunits, int outunits, double lrate, double mrate)
00083 {
00084 std::string fname("none");
00085 init(fname, fname, inunits, hidunits, outunits, lrate, mrate);
00086 }
00087
00088
00089
00090 void FeedForwardNetwork::init(std::string wh_file, std::string wo_file,
00091 int inunits, int hidunits, int outunits,
00092 double lrate, double mrate)
00093 {
00094
00095 itsNumLayer = 2;
00096
00097
00098 itsInputLayerPotential.resize(1, inunits+1);
00099 itsHiddenLayerPotential.resize(1, hidunits+1);
00100 itsOutputLayerPotential.resize(1, outunits);
00101
00102
00103
00104 itsHiddenLayerWeight.resize(inunits+1, hidunits);
00105
00106
00107 itsOutputLayerWeight.resize(hidunits+1, outunits);
00108
00109
00110
00111
00112
00113
00114
00115 itsInputLayerPotential.setVal(0, inunits, 1.0);
00116 itsHiddenLayerPotential.setVal(0, hidunits, 1.0);
00117
00118
00119
00120 itsError.resize(1, outunits);
00121 itsHiddenLayerDelta.resize(1, hidunits);
00122 itsOutputLayerDelta.resize(1, outunits);
00123
00124
00125 itsLearningRate = lrate;
00126 itsMomentumRate = mrate;
00127
00128
00129 FILE *fp; Image<double>::iterator aptr;
00130 if((fp = fopen(wh_file.c_str(),"rb")) == NULL)
00131 {
00132 LINFO("initializing wh with random weights");
00133 srand((unsigned)time(0));
00134 aptr = itsHiddenLayerWeight.beginw();
00135 for(int i = 0; i < inunits+1; i++)
00136 for(int j = 0; j < hidunits; j++)
00137 *aptr++ = (-FFN_RW_RANGE/2.0) +
00138 (rand()/(RAND_MAX + 1.0) * FFN_RW_RANGE);
00139 }
00140 else
00141 {
00142 LINFO("reading whfile");
00143 Image<double> temp(hidunits, inunits+1, NO_INIT);
00144 double val; aptr = temp.beginw();
00145 for(int i = 0; i < inunits+1; i++)
00146 for(int j = 0; j < hidunits; j++)
00147 { if (fread(&val, sizeof(double), 1, fp) != 1) LERROR("fread error"); *aptr++ = val; }
00148 itsHiddenLayerWeight = transpose(temp);
00149 fclose(fp);
00150 }
00151
00152
00153 if((fp=fopen(wo_file.c_str(),"rb")) == NULL)
00154 {
00155 LINFO("initializing wo with random weights");
00156 srand((unsigned)time(0));
00157 aptr = itsOutputLayerWeight.beginw();
00158 for(int i = 0; i < hidunits+1; i++)
00159 for(int j = 0; j < outunits; j++)
00160 *aptr++ = (-FFN_RW_RANGE/2.0) +
00161 (rand()/(RAND_MAX + 1.0) * FFN_RW_RANGE);
00162 }
00163 else
00164 {
00165 LINFO("reading wofile");
00166 Image<double> temp(outunits, hidunits+1, NO_INIT);
00167 double val; aptr = temp.beginw();
00168 for(int i = 0; i < hidunits+1; i++)
00169 for(int j = 0; j < outunits; j++)
00170 { if (fread(&val, sizeof(double), 1, fp) != 1) LERROR("fread error"); *aptr++ = val; }
00171 itsOutputLayerWeight = transpose(temp);
00172 fclose(fp);
00173 }
00174 }
00175
00176
00177
00178 void FeedForwardNetwork::init(Image<double> wh, Image<double> wo,
00179 double lrate, double mrate)
00180 {
00181
00182 itsNumLayer = 2;
00183
00184 ASSERT(wh.getHeight() == wo.getWidth() - 1);
00185 int inunits = wh.getWidth() - 1;
00186 int hidunits = wh.getHeight();
00187 int outunits = wo.getHeight();
00188
00189
00190 itsInputLayerPotential.resize(1, inunits+1);
00191 itsHiddenLayerPotential.resize(1, hidunits+1);
00192 itsOutputLayerPotential.resize(1, outunits);
00193
00194
00195
00196 itsHiddenLayerWeight.resize(inunits+1, hidunits);
00197
00198
00199 itsOutputLayerWeight.resize(hidunits+1, outunits);
00200
00201
00202
00203
00204
00205
00206
00207 itsInputLayerPotential.setVal(0, inunits, 1.0);
00208 itsHiddenLayerPotential.setVal(0, hidunits, 1.0);
00209
00210
00211
00212 itsError.resize(1, outunits);
00213 itsHiddenLayerDelta.resize(1, hidunits);
00214 itsOutputLayerDelta.resize(1, outunits);
00215
00216
00217 itsLearningRate = lrate;
00218 itsMomentumRate = mrate;
00219
00220
00221 itsHiddenLayerWeight = wh;
00222
00223
00224 itsOutputLayerWeight = wo;
00225 }
00226
00227
00228
00229 void FeedForwardNetwork::init3L
00230 ( int inunits, int hid1units, int hid2units,
00231 int outunits, double lrate, double mrate)
00232 {
00233 std::string fname("none");
00234 init3L(fname, fname, fname, inunits, hid1units, hid2units, outunits,
00235 lrate, mrate);
00236 }
00237
00238
00239
00240 void FeedForwardNetwork::init3L
00241 ( std::string wh_file, std::string wh2_file, std::string wo_file,
00242 int inunits, int hidunits, int hid2units,
00243 int outunits, double lrate, double mrate)
00244 {
00245
00246 itsNumLayer = 3;
00247
00248
00249 itsInputLayerPotential.resize (1, inunits+1);
00250 itsHiddenLayerPotential.resize (1, hidunits+1);
00251 itsHiddenLayer2Potential.resize(1, hid2units+1);
00252 itsOutputLayerPotential.resize (1, outunits);
00253
00254
00255
00256 itsHiddenLayerWeight.resize(inunits+1, hidunits);
00257
00258
00259 itsHiddenLayer2Weight.resize(hidunits+1, hid2units);
00260
00261
00262 itsOutputLayerWeight.resize(hid2units+1, outunits);
00263
00264
00265 itsInputLayerPotential.setVal(0, inunits, 1.0);
00266 itsHiddenLayerPotential.setVal(0, hidunits, 1.0);
00267 itsHiddenLayer2Potential.setVal(0, hid2units, 1.0);
00268
00269
00270
00271 itsError.resize(1, outunits);
00272 itsHiddenLayerDelta.resize(1, hidunits);
00273 itsHiddenLayer2Delta.resize(1, hid2units);
00274 itsOutputLayerDelta.resize(1, outunits);
00275
00276
00277 itsLearningRate = lrate;
00278 itsMomentumRate = mrate;
00279
00280
00281 FILE *fp; Image<double>::iterator aptr;
00282 if((fp = fopen(wh_file.c_str(),"rb")) == NULL)
00283 {
00284 LINFO("initializing wh with random weights");
00285 srand((unsigned)time(0));
00286 aptr = itsHiddenLayerWeight.beginw();
00287 for(int i = 0; i < inunits+1; i++)
00288 for(int j = 0; j < hidunits; j++)
00289 *aptr++ = (-FFN_RW_RANGE/2.0) +
00290 (rand()/(RAND_MAX + 1.0) * FFN_RW_RANGE);
00291 }
00292 else
00293 {
00294 LINFO("reading whfile");
00295 Image<double> temp(hidunits, inunits+1, NO_INIT);
00296 double val; aptr = temp.beginw();
00297 for(int i = 0; i < inunits+1; i++)
00298 for(int j = 0; j < hidunits; j++)
00299 { if (fread(&val, sizeof(double), 1, fp) != 1) LERROR("fread error"); *aptr++ = val; }
00300 itsHiddenLayerWeight = transpose(temp);
00301 fclose(fp);
00302 }
00303
00304
00305 if((fp = fopen(wh2_file.c_str(),"rb")) == NULL)
00306 {
00307 LINFO("initializing wh2 with random weights");
00308 srand((unsigned)time(0));
00309 aptr = itsHiddenLayer2Weight.beginw();
00310 for(int i = 0; i < hidunits+1; i++)
00311 for(int j = 0; j < hid2units; j++)
00312 *aptr++ = (-FFN_RW_RANGE/2.0) +
00313 (rand()/(RAND_MAX + 1.0) * FFN_RW_RANGE);
00314 }
00315 else
00316 {
00317 LINFO("reading wh2file");
00318 Image<double> temp(hid2units, hidunits+1, NO_INIT);
00319 double val; aptr = temp.beginw();
00320 for(int i = 0; i < hidunits+1; i++)
00321 for(int j = 0; j < hid2units; j++)
00322 { if (fread(&val, sizeof(double), 1, fp) != 1) LERROR("fread error"); *aptr++ = val; }
00323 itsHiddenLayer2Weight = transpose(temp);
00324 fclose(fp);
00325 }
00326
00327
00328 if((fp=fopen(wo_file.c_str(),"rb")) == NULL)
00329 {
00330 LINFO("initializing wo with random weights");
00331 srand((unsigned)time(0));
00332 aptr = itsOutputLayerWeight.beginw();
00333 for(int i = 0; i < hid2units+1; i++)
00334 for(int j = 0; j < outunits; j++)
00335 *aptr++ = (-FFN_RW_RANGE/2.0) +
00336 (rand()/(RAND_MAX + 1.0) * FFN_RW_RANGE);
00337 }
00338 else
00339 {
00340 LINFO("reading wofile");
00341 Image<double> temp(outunits, hid2units+1, NO_INIT);
00342 double val; aptr = temp.beginw();
00343 for(int i = 0; i < hid2units+1; i++)
00344 for(int j = 0; j < outunits; j++)
00345 { if (fread(&val, sizeof(double), 1, fp) != 1) LERROR("fread error"); *aptr++ = val; }
00346 itsOutputLayerWeight = transpose(temp);
00347 fclose(fp);
00348 }
00349 }
00350
00351
00352
00353 void FeedForwardNetwork::init3L
00354 ( Image<double> wh, Image<double> wh2, Image<double> wo,
00355 double lrate, double mrate)
00356 {
00357
00358 itsNumLayer = 3;
00359
00360 ASSERT(wh.getHeight() == wh2.getWidth() - 1);
00361 ASSERT(wh2.getHeight() == wo.getWidth() - 1);
00362 int inunits = wh.getWidth() - 1;
00363 int hidunits = wh.getHeight();
00364 int hid2units = wh2.getHeight();
00365 int outunits = wo.getHeight();
00366
00367
00368 itsInputLayerPotential.resize (1, inunits+1);
00369 itsHiddenLayerPotential.resize (1, hidunits+1);
00370 itsHiddenLayer2Potential.resize(1, hid2units+1);
00371 itsOutputLayerPotential.resize (1, outunits);
00372
00373
00374
00375 itsHiddenLayerWeight.resize(inunits+1, hidunits);
00376
00377
00378 itsHiddenLayer2Weight.resize(hidunits+1, hid2units);
00379
00380
00381 itsOutputLayerWeight.resize(hid2units+1, outunits);
00382
00383
00384 itsInputLayerPotential.setVal(0, inunits, 1.0);
00385 itsHiddenLayerPotential.setVal(0, hidunits, 1.0);
00386 itsHiddenLayer2Potential.setVal(0, hid2units, 1.0);
00387
00388
00389
00390 itsError.resize(1, outunits);
00391 itsHiddenLayerDelta.resize(1, hidunits);
00392 itsHiddenLayer2Delta.resize(1, hid2units);
00393 itsOutputLayerDelta.resize(1, outunits);
00394
00395
00396 itsLearningRate = lrate;
00397 itsMomentumRate = mrate;
00398
00399
00400 itsHiddenLayerWeight = wh;
00401
00402
00403 itsHiddenLayer2Weight = wh2;
00404
00405
00406 itsOutputLayerWeight = wo;
00407 }
00408
00409
00410
00411 Image<double> FeedForwardNetwork::run(Image<double> input)
00412 {
00413
00414 Image<double>::iterator aptr = input.beginw(), stop = input.endw();
00415 Image<double>::iterator bptr = itsInputLayerPotential.beginw();
00416 while (aptr != stop) *bptr++ = *aptr++;
00417
00418
00419 Image<double> thlp =
00420 matrixMult(itsHiddenLayerWeight, itsInputLayerPotential);
00421 inPlaceSigmoid(thlp);
00422 aptr = thlp.beginw(), stop = thlp.endw();
00423 bptr = itsHiddenLayerPotential.beginw();
00424 while (aptr != stop) *bptr++ = *aptr++;
00425
00426
00427 itsOutputLayerPotential =
00428 matrixMult(itsOutputLayerWeight, itsHiddenLayerPotential);
00429 inPlaceSigmoid(itsOutputLayerPotential);
00430
00431 return itsOutputLayerPotential;
00432 }
00433
00434
00435
00436 Image<double> FeedForwardNetwork::run3L(Image<double> input)
00437 {
00438
00439 Image<double>::iterator aptr = input.beginw(), stop = input.endw();
00440 Image<double>::iterator bptr = itsInputLayerPotential.beginw();
00441 while (aptr != stop) *bptr++ = *aptr++;
00442
00443
00444 Image<double> thlp =
00445 matrixMult(itsHiddenLayerWeight, itsInputLayerPotential);
00446 inPlaceSigmoid(thlp);
00447 aptr = thlp.beginw(), stop = thlp.endw();
00448 bptr = itsHiddenLayerPotential.beginw();
00449 while (aptr != stop) *bptr++ = *aptr++;
00450
00451
00452 Image<double> thl2p =
00453 matrixMult(itsHiddenLayer2Weight, itsHiddenLayerPotential);
00454 inPlaceSigmoid(thl2p);
00455 aptr = thl2p.beginw(), stop = thl2p.endw();
00456 bptr = itsHiddenLayer2Potential.beginw();
00457 while (aptr != stop) *bptr++ = *aptr++;
00458
00459
00460 itsOutputLayerPotential =
00461 matrixMult(itsOutputLayerWeight, itsHiddenLayer2Potential);
00462 inPlaceSigmoid(itsOutputLayerPotential);
00463
00464 return itsOutputLayerPotential;
00465 }
00466
00467
00468 void FeedForwardNetwork::backprop(Image<double> target)
00469 {
00470
00471 itsError = target - itsOutputLayerPotential;
00472 Image<double>
00473 onesO(1,itsOutputLayerPotential.getSize(), ZEROS); onesO += 1.0;
00474 itsOutputLayerDelta = itsError * itsOutputLayerPotential *
00475 (onesO - itsOutputLayerPotential);
00476
00477
00478 Image<double>
00479 onesH(1,itsHiddenLayerPotential.getSize(), ZEROS); onesH += 1.0;
00480 Image<double> tempDh =
00481 matrixMult(transpose(itsOutputLayerWeight), itsOutputLayerDelta) *
00482 itsHiddenLayerPotential * (onesH - itsHiddenLayerPotential);
00483 itsHiddenLayerDelta =
00484 crop(tempDh,Point2D<int>(0,0), itsHiddenLayerDelta.getDims());
00485
00486
00487 itsOutputLayerWeight +=
00488 (matrixMult(itsOutputLayerDelta, transpose(itsHiddenLayerPotential))
00489 * itsLearningRate);
00490
00491
00492 itsHiddenLayerWeight +=
00493 matrixMult(itsHiddenLayerDelta, transpose(itsInputLayerPotential))
00494 * itsLearningRate;
00495 }
00496
00497
00498 void FeedForwardNetwork::backprop3L(Image<double> target)
00499 {
00500
00501 itsError = target - itsOutputLayerPotential;
00502 Image<double>
00503 onesO(1,itsOutputLayerPotential.getSize(), ZEROS); onesO += 1.0;
00504 itsOutputLayerDelta = itsError * itsOutputLayerPotential *
00505 (onesO - itsOutputLayerPotential);
00506
00507
00508 Image<double>
00509 onesH2(1,itsHiddenLayer2Potential.getSize(), ZEROS); onesH2 += 1.0;
00510 Image<double> tempDh2 =
00511 matrixMult(transpose(itsOutputLayerWeight), itsOutputLayerDelta) *
00512 itsHiddenLayer2Potential * (onesH2 - itsHiddenLayer2Potential);
00513 itsHiddenLayer2Delta =
00514 crop(tempDh2, Point2D<int>(0,0), itsHiddenLayer2Delta.getDims());
00515
00516
00517 Image<double>
00518 onesH(1,itsHiddenLayerPotential.getSize(), ZEROS); onesH += 1.0;
00519 Image<double> tempDh =
00520 matrixMult(transpose(itsHiddenLayer2Weight), itsHiddenLayer2Delta) *
00521 itsHiddenLayerPotential * (onesH - itsHiddenLayerPotential);
00522 itsHiddenLayerDelta =
00523 crop(tempDh, Point2D<int>(0,0), itsHiddenLayerDelta.getDims());
00524
00525
00526 itsOutputLayerWeight +=
00527 (matrixMult(itsOutputLayerDelta, transpose(itsHiddenLayer2Potential))
00528 * itsLearningRate);
00529
00530
00531 itsHiddenLayer2Weight +=
00532 matrixMult(itsHiddenLayer2Delta, transpose(itsHiddenLayerPotential))
00533 * itsLearningRate;
00534
00535
00536 itsHiddenLayerWeight +=
00537 matrixMult(itsHiddenLayerDelta, transpose(itsInputLayerPotential))
00538 * itsLearningRate;
00539 }
00540
00541
00542
00543 void FeedForwardNetwork::write(std::string wh_file, std::string wo_file)
00544 {
00545 FILE *fp;
00546
00547
00548 if((fp = fopen(wh_file.c_str(),"wb")) == NULL)
00549 LFATAL("can't open wh1");
00550 Image<double> temp = transpose(itsHiddenLayerWeight);
00551 Image<double>::iterator aptr = temp.beginw();
00552 Image<double>::iterator stop = temp.endw();
00553 while (aptr != stop)
00554 { double val = *aptr++; fwrite(&val, sizeof(double), 1, fp); }
00555 fclose(fp);
00556
00557
00558 if((fp = fopen(wo_file.c_str(),"wb")) == NULL)
00559 LFATAL("can't open wo");
00560 temp = transpose(itsOutputLayerWeight);
00561 aptr = temp.beginw(); stop = temp.endw();
00562 while (aptr != stop)
00563 { double val = *aptr++; fwrite(&val, sizeof(double), 1, fp); }
00564 fclose(fp);
00565
00566 }
00567
00568
00569
00570
00571 void FeedForwardNetwork::write3L
00572 (std::string wh_file, std::string wh2_file, std::string wo_file)
00573 {
00574 FILE *fp;
00575
00576
00577 if((fp = fopen(wh_file.c_str(),"wb")) == NULL)
00578 LFATAL("can't open wh1");
00579 Image<double> temp = transpose(itsHiddenLayerWeight);
00580 Image<double>::iterator aptr = temp.beginw();
00581 Image<double>::iterator stop = temp.endw();
00582 while (aptr != stop)
00583 { double val = *aptr++; fwrite(&val, sizeof(double), 1, fp); }
00584 fclose(fp);
00585
00586
00587 if((fp = fopen(wh2_file.c_str(),"wb")) == NULL)
00588 LFATAL("can't open wh2");
00589 temp = transpose(itsHiddenLayer2Weight);
00590 aptr = temp.beginw(); stop = temp.endw();
00591 while (aptr != stop)
00592 { double val = *aptr++; fwrite(&val, sizeof(double), 1, fp); }
00593 fclose(fp);
00594
00595
00596 if((fp = fopen(wo_file.c_str(),"wb")) == NULL)
00597 LFATAL("can't open wo");
00598 temp = transpose(itsOutputLayerWeight);
00599 aptr = temp.beginw(); stop = temp.endw();
00600 while (aptr != stop)
00601 { double val = *aptr++; fwrite(&val, sizeof(double), 1, fp); }
00602 fclose(fp);
00603 }
00604
00605
00606 void FeedForwardNetwork::setLearningRate(double newLR)
00607 {
00608 itsLearningRate = newLR;
00609 }
00610
00611
00612
00613
00614
00615