00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "SOM.h"
00021
00022 using namespace std;
00023 using namespace Marsyas;
00024
00025
00026
00027 #define ALPHA_DEGRADE 0.98
00028 #define NEIGHBOURHOOD_DEGRADE 0.97
00029
00030 SOM::SOM(mrs_string name):MarSystem("SOM",name)
00031 {
00032
00033
00034
00035 addControls();
00036 }
00037
00038
00039 SOM::~SOM()
00040 {
00041 }
00042
00043
00044
00045 SOM::SOM(const SOM& a) : MarSystem(a)
00046 {
00047 ctrl_gridmap_ = getctrl("mrs_realvec/grid_map");
00048 }
00049
00050
00051 MarSystem*
00052 SOM::clone() const
00053 {
00054 return new SOM(*this);
00055 }
00056
00057 void
00058 SOM::addControls()
00059 {
00060 addctrl("mrs_string/mode", "train");
00061 addctrl("mrs_natural/nLabels", 1);
00062 setctrlState("mrs_natural/nLabels", true);
00063 addctrl("mrs_natural/grid_width", 10);
00064 setctrlState("mrs_natural/grid_width", true);
00065 addctrl("mrs_natural/grid_height", 10);
00066 setctrlState("mrs_natural/grid_height", true);
00067
00068 addctrl("mrs_realvec/grid_map", realvec(), ctrl_gridmap_);
00069
00070 addctrl("mrs_bool/done", false);
00071 setctrlState("mrs_bool/done", true);
00072
00073 addctrl("mrs_real/alpha", 1.0);
00074 setctrlState("mrs_real/alpha", true);
00075
00076 addctrl("mrs_real/neigh_std", 1.0);
00077 setctrlState("mrs_real/neigh_std", true);
00078
00079 addctrl("mrs_real/alpha_decay_init", ALPHA_DEGRADE);
00080 setctrlState("mrs_real/alpha_decay_init", true);
00081
00082 addctrl("mrs_real/alpha_decay_train", ALPHA_DEGRADE);
00083 setctrlState("mrs_real/alpha_decay_train", true);
00084
00085 addctrl("mrs_real/neighbourhood_decay_init", NEIGHBOURHOOD_DEGRADE);
00086 setctrlState("mrs_real/neighbourhood_decay_init", true);
00087
00088 addctrl("mrs_real/neighbourhood_decay_train", NEIGHBOURHOOD_DEGRADE);
00089 setctrlState("mrs_real/neighbourhood_decay_train", true);
00090
00091 addctrl("mrs_real/std_factor_train", 0.17);
00092 setctrlState("mrs_real/std_factor_train", true);
00093
00094 addctrl("mrs_real/std_factor_init", 0.17);
00095 setctrlState("mrs_real/std_factor_init", true);
00096 }
00097
00098
00099 void
00100 SOM::init_grid_map()
00101 {
00102
00103 MarControlAccessor acc_grid(ctrl_gridmap_);
00104 realvec& grid_map = acc_grid.to<mrs_realvec>();
00105 srand(0);
00106
00107 for (int x=0; x < grid_width_; x++)
00108 for (int y=0; y < grid_height_; y++)
00109 for (int o=0; o < inObservations_ - 3; o++)
00110 {
00111 grid_map(x * grid_height_ + y, o) = randD(1.0);
00112 }
00113
00114 alpha_ = getctrl("mrs_real/alpha")->to<mrs_real>();
00115 mrs_real std_ = getctrl("mrs_real/std_factor_train")->to<mrs_real>();
00116 neigh_std_ = ((0.5*(grid_width_+grid_height_)) * std_);
00117
00118
00119
00120 }
00121
00122
00123 double
00124 SOM::gaussian(double x, double mean, double std, bool scale)
00125 {
00126 if( scale )
00127 return (1.0/(std*sqrt(2.0*PI))) * exp( -(x-mean)*(x-mean)/(2.0*std*std) );
00128
00129 return exp( -(x-mean)*(x-mean)/(2.0*std*std) );
00130 }
00131
00132 double
00133 SOM::randD(double max)
00134 {
00135 return max * (double)rand() / ((double)(RAND_MAX)+(double)(1.0)) ;
00136 }
00137
00138 void
00139 SOM::myUpdate(MarControlPtr sender)
00140 {
00141
00142 (void) sender;
00143 MRSDIAG("SOM.cpp - SOM:myUpdate");
00144
00145 setctrl("mrs_natural/onSamples", getctrl("mrs_natural/inSamples"));
00146 setctrl("mrs_natural/onObservations", (mrs_natural)3);
00147 setctrl("mrs_real/osrate", getctrl("mrs_real/israte"));
00148
00149 grid_pos_.create(2);
00150
00151
00152 inObservations_ = getctrl("mrs_natural/inObservations")->to<mrs_natural>();
00153
00154
00155
00156
00157 grid_width_ = getctrl("mrs_natural/grid_width")->to<mrs_natural>();
00158 grid_height_ = getctrl("mrs_natural/grid_height")->to<mrs_natural>();
00159
00160 mrs_natural grid_size = grid_width_ * grid_height_;
00161
00162 mrs_natural mrows = (getctrl("mrs_realvec/grid_map")->to<mrs_realvec>()).getRows();
00163 mrs_natural mcols = (getctrl("mrs_realvec/grid_map")->to<mrs_realvec>()).getCols();
00164
00165 mrs_string mode = getctrl("mrs_string/mode")->to<mrs_string>();
00166
00167 if ((grid_size != mrows) ||
00168 (inObservations_-3 != mcols))
00169 {
00170 if (inObservations_ != 1)
00171 {
00172 MarControlAccessor acc_grid(ctrl_gridmap_);
00173 realvec& grid_map = acc_grid.to<mrs_realvec>();
00174 grid_map.create(grid_size, inObservations_-3);
00175 adjustments_.create(inObservations_-3);
00176
00177 init_grid_map();
00178 }
00179
00180 }
00181 }
00182
00183 void
00184 SOM::find_grid_location(realvec& in, int t)
00185 {
00186 mrs_natural o;
00187
00188 mrs_real ival;
00189 mrs_real pval;
00190 mrs_real minDist = MAXREAL;
00191
00192 MarControlAccessor acc_grid(ctrl_gridmap_);
00193 realvec& grid_map = acc_grid.to<mrs_realvec>();
00194
00195 for (int x=0; x < grid_width_; x++)
00196 for (int y=0; y < grid_height_; y++)
00197 {
00198
00199
00200
00201
00202
00203 mrs_real dist = 0.0;
00204
00205 for (o=0; o < inObservations_-3; o++)
00206 {
00207 ival = in(o,t);
00208 pval = grid_map(x * grid_height_ + y, o);
00209 dist += (ival - pval) * (ival - pval);
00210
00211 }
00212
00213 if (dist < minDist)
00214 {
00215 minDist = dist;
00216 grid_pos_(0) = x;
00217 grid_pos_(1) = y;
00218 }
00219 }
00220
00221
00222
00223
00224 }
00225
00226
00227
00228 void
00229 SOM::myProcess(realvec& in, realvec& out)
00230 {
00231 mrs_string mode = getctrl("mrs_string/mode")->to<mrs_string>();
00232
00233 mrs_natural o,t;
00234 mrs_real geom_dist;
00235 mrs_real geom_dist_gauss;
00236
00237 int px;
00238 int py;
00239
00240 MarControlAccessor acc_grid(ctrl_gridmap_);
00241 realvec& grid_map = acc_grid.to<mrs_realvec>();
00242
00243
00244 if (mode == "train")
00245 {
00246
00247 mrs_real dx;
00248 mrs_real dy;
00249 mrs_real adj;
00250
00251 for (t=0; t < inSamples_; t++)
00252 {
00253
00254
00255 px = (int) in(inObservations_-2, t);
00256 py = (int) in(inObservations_-1, t);
00257
00258
00259
00260 if ((px == -1.0)&&(px == -1.0))
00261 {
00262 find_grid_location(in, t);
00263 px = (int) grid_pos_(0);
00264 py = (int) grid_pos_(1);
00265 }
00266 out(0,t) = px;
00267 out(1,t) = py;
00268 out(2,t) = in(inObservations_-3,t);
00269
00270 for (int x=0; x < grid_width_; x++)
00271 for (int y=0; y < grid_height_; y++)
00272 {
00273 dx = px-x;
00274 dy = py-y;
00275 geom_dist = sqrt((double)(dx*dx + dy*dy));
00276 geom_dist_gauss = gaussian( geom_dist, 0.0, neigh_std_, false);
00277
00278
00279 adj = alpha_ * geom_dist_gauss;
00280 for (o=0; o < inObservations_-3; o++)
00281 {
00282 adjustments_(o) = in(o,t) - grid_map(x * grid_height_ + y, o);
00283 adjustments_(o) *= adj;
00284 grid_map(x * grid_height_ + y, o) += adjustments_(o);
00285 }
00286 }
00287 }
00288
00289 alpha_ *= getctrl("mrs_real/alpha_decay_train")->to<mrs_real>();
00290 neigh_std_ *= getctrl("mrs_real/neighbourhood_decay_train")->to<mrs_real>();
00291
00292
00293
00294 }
00295 if (mode == "init")
00296 {
00297 mrs_real dx;
00298 mrs_real dy;
00299 mrs_real adj;
00300
00301 mrs_real std_ = getctrl("mrs_real/std_factor_init")->to<mrs_real>();
00302 neigh_std_ = ((0.5*(grid_width_+grid_height_)) * std_);
00303
00304 for (t=0; t < inSamples_; t++)
00305 {
00306
00307 px = (int) in( in.getRows() - 2, t);
00308 py = (int) in( in.getRows() - 1, t);
00309 for(int i =0; i < inObservations_ - 3; ++i)
00310 {
00311 grid_map(px * grid_height_ + py, i) = in(i);
00312 }
00313
00314 for (int x=0; x < grid_width_; x++)
00315 for (int y=0; y < grid_height_; y++)
00316 {
00317 dx = px-x;
00318 dy = py-y;
00319 geom_dist = sqrt((double)(dx*dx + dy*dy));
00320 geom_dist_gauss = gaussian( geom_dist, 0.0, neigh_std_, false);
00321
00322
00323 adj = alpha_ * geom_dist_gauss;
00324 for (o=0; o < inObservations_-3; o++)
00325 {
00326 adjustments_(o) = in(o,t) - grid_map(x * grid_height_ + y, o);
00327 adjustments_(o) *= adj;
00328 grid_map(x * grid_height_ + y, o) += adjustments_(o);
00329 }
00330
00331 }
00332
00333
00334 }
00335
00336
00337
00338
00339 for (int x=0; x < grid_width_; x++)
00340 {
00341 for (int y=0; y < grid_height_; y++)
00342 {
00343 grid_map(x * grid_height_ + y, grid_map.getCols() - 2) = 0;
00344 grid_map(x * grid_height_ + y, grid_map.getCols() - 1) = 0;
00345 cout << "x: " << x << " y: " << y << endl;
00346 }
00347 }
00348 alpha_ *= getctrl("mrs_real/alpha_decay_init")->to<mrs_real>();
00349 neigh_std_ *= getctrl("mrs_real/neighbourhood_decay_init")->to<mrs_real>();
00350
00351 }
00352 if (mode == "predict")
00353 {
00354 for (t=0; t < inSamples_; t++)
00355 {
00356 find_grid_location(in, t);
00357 px = (int) grid_pos_(0);
00358 py = (int) grid_pos_(1);
00359
00360
00361
00362 out(0,t) = px;
00363 out(1,t) = py;
00364 out(2,t) = in(inObservations_-3,t);
00365 }
00366 }
00367
00368
00369
00370
00371
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384