00001
00007 #ifndef __NEURALREGION_H__
00008 #define __NEURALREGION_H__
00009
00010 #include <utility>
00011 #include <string>
00012 using std::string;
00013
00014 #include "matrix.h"
00015 #include "generic_stdlib.h"
00016 #include "matrixadapter.h"
00017 #include "boundingbox.h"
00018 #include "weightset.h"
00019 #include "bounded.h"
00020 #include "pointermap.h"
00021 #include "sequencetransform.h"
00022
00023
00024
00028 class NeuralRegion : public HasTable<mat::MatrixInterface<Bounded::Magnitude> > {
00029 public:
00032
00037 typedef Bounded::Magnitude Magnitude;
00038
00040 typedef Magnitude Activity;
00041
00043 typedef double Length;
00044
00051 typedef MatrixType<Activity>::rectangular ActivityMatrix;
00052
00054 typedef ActivityMatrix::size_type Subscript;
00055
00057 typedef std::pair<Subscript,Subscript> SubscriptPair;
00058
00060 typedef mat::MatrixInterface<Magnitude> MapBaseType;
00061
00064 typedef mat::MatrixInterfaceAdapter<ActivityMatrix,Magnitude> ActivityAdapter;
00065
00067 typedef Boundary::AARBoundingBox<int,int> Bounds;
00068
00070 typedef SequenceTransform::OneD<ActivityMatrix,ActivityMatrix> ActivationFunction;
00071
00076 struct Dimensions {
00077 Dimensions(Subscript h, Subscript w, Length xo=0.5, Length yo=0.5)
00078 : height(h), width(w), xoffset(xo), yoffset(yo) { }
00079 Subscript height;
00080 Subscript width;
00081 Length xoffset;
00082 Length yoffset;
00083 };
00085
00088 NeuralRegion(string name_i, Dimensions dims)
00089 : HasTable<mat::MatrixInterface<Bounded::Magnitude> >(),
00090 name_str(name_i), output(dims.height,dims.width),
00091 bp(dims.height,dims.width),
00092 residual(dims.height,dims.width) { }
00093
00094 NeuralRegion(const NeuralRegion& other)
00095 : HasTable<mat::MatrixInterface<Bounded::Magnitude> >(),
00096 name_str(other.name_str), output(other.output),
00097 bp(other.bp), residual(other.residual) { }
00098
00099 virtual ~NeuralRegion() { }
00101
00102
00104 virtual void activate(bool learn=false, bool settle=true, bool activatefn=true) =0;
00105
00106
00109
00110
00112 virtual Activity activity(Subscript i, Subscript j) const { return output[i][j]; }
00115 virtual const ActivityMatrix& const_activity() const { return output; }
00116
00117 virtual const ActivityMatrix& backprojection() const { return bp; }
00118
00119 virtual const ActivityMatrix& residual_activity() const { return residual; }
00120
00121
00122
00124
00126 const string& name() const { return name_str; }
00127
00128 const int nrows() const { return int(output.nrows()); }
00129 const int ncols() const { return int(output.ncols()); }
00130
00134 virtual bool is_internal() const { return false; }
00135
00139 virtual bool is_plastic() const { return true; }
00140
00149 virtual void save_state(const string&) { }
00150
00157 virtual bool restore_state(const int, const string&) { return true; }
00158
00162 virtual void prune() { }
00163
00167 virtual double size_connection_bytes() const=0;
00168
00173 virtual double size_unique_connections() const=0;
00174
00175
00176
00177
00178
00179 private:
00180 const string name_str;
00181
00184 public:
00186 Bounds bounds() const { return Bounds(0,0,output.ncols()-1,output.nrows()-1); }
00188
00189
00190 public:
00192 ActivityMatrix output;
00193 ActivityMatrix bp;
00194 ActivityMatrix residual;
00195 };
00196
00197
00198
00203 class InternalNeuralRegion : public NeuralRegion {
00204 public:
00207 InternalNeuralRegion(string name_i, Dimensions dims)
00208 : NeuralRegion(name_i,dims) { }
00209
00210 virtual ~InternalNeuralRegion() { }
00212
00219 typedef ActivityMatrix WeightMatrix;
00220
00222 typedef Generic::unary_virtual_function<double,WeightMatrix> WeightFunction;
00223
00225 typedef Boundary::BoundingBox<int,int> WeightBounds;
00226
00228 typedef WeightSet<WeightMatrix,WeightBounds,MapBaseType,mat::MatrixInterfaceAdapter<WeightMatrix,Magnitude> > Weights;
00229
00230
00232 virtual Dimensions input_dimensions(WeightFunction& fn, Length size_scale=1.0) =0;
00233
00234 virtual bool is_internal() const { return true; }
00235
00239 virtual void add_input(const string& name, NeuralRegion& upstream_region,
00240 WeightFunction& fn, Length size_scale) =0;
00241
00243 virtual void backproject() = 0;
00244
00248 virtual void backproject(const string& name, const double gammaaff=1.0) {
00249
00250
00251
00252
00253
00254
00255
00256
00257 NeuralRegion* inp = dynamic_cast<NeuralRegion*>(get_input(name));
00258 if (!inp) {
00259
00260
00261 return;
00262 }
00263
00264
00265 int nr = output.nrows(), nc = output.ncols();
00266 for (int i=0; i<nr; i++)
00267 for (int j=0; j<nc; j++) {
00268
00269 double cur_output = bp[i][j];
00270
00271
00272 const WeightMatrix wmat = get_weights(name,i,j);
00273 const WeightBounds* wbounds = get_weights_bounds(name,i,j);
00274
00275
00276
00277 int xl = wbounds->aarectangle().corners().xl;
00278 int yl = wbounds->aarectangle().corners().yl;
00279 int xh = wbounds->aarectangle().corners().xh;
00280 int yh = wbounds->aarectangle().corners().yh;
00281
00282
00283 for (int x=xl; x<=xh; ++x)
00284 for (int y=yl; y<=yh; ++y)
00285 (inp->bp[x][y]) += cur_output * wmat[x-xl][y-yl] / gammaaff;
00286
00287 delete wbounds;
00288
00289 }
00290
00291
00292 };
00293
00294
00295 #ifdef OBJ_LISSOM
00296
00298 virtual void resp_to_residual() {};
00299
00302 virtual void resp_to_residual(const string& name, const double gammaaff=1.0) {
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 NeuralRegion* inp = dynamic_cast<NeuralRegion*>(get_input(name));
00315
00316 int nr = output.nrows(), nc = output.ncols();
00317 for (int i=0; i<nr; i++)
00318 for (int j=0; j<nc; j++) {
00319
00320
00321 const WeightMatrix wmat = get_weights(name,i,j);
00322 const WeightBounds* wbounds = get_weights_bounds(name,i,j);
00323
00324
00325
00326 int xl = wbounds->aarectangle().corners().xl;
00327 int yl = wbounds->aarectangle().corners().yl;
00328 int xh = wbounds->aarectangle().corners().xh;
00329 int yh = wbounds->aarectangle().corners().yh;
00330
00331
00332 double sum = 0.0;
00333
00334 for (int x=xl; x<=xh; ++x)
00335 for (int y=yl; y<=yh; ++y)
00336 sum += (inp->residual[x][y])
00337 * wmat[x-xl][y-yl];
00338
00339 output[i][j] += sum / gammaaff;
00340
00341 delete wbounds;
00342
00343 }
00344
00345
00346 }
00347
00349 virtual void train_obj_weights() {};
00350
00352 virtual void randomize_lat_wts() {};
00353 #endif
00354
00355
00357
00359 virtual const Weights weights(const string& name, int ui=0, int uj=0) const
00360 { return Weights(new WeightMatrix(get_weights(name,ui,uj)),get_weights_bounds(name,ui,uj)); }
00361
00362
00363
00372 virtual const WeightMatrix get_weights(const string& name, int ui=0, int uj=0) const =0;
00373
00382 virtual WeightBounds* get_weights_bounds(const string& name, int ui=0, int uj=0) const =0;
00383
00385
00387
00388 virtual NeuralRegion* get_input(const string& name) = 0;
00390
00391 };
00392
00393
00394 #endif