00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <boost/numeric/ublas/vector.hpp>
00020 #include <boost/numeric/ublas/matrix.hpp>
00021 #include <boost/numeric/ublas/matrix_expression.hpp>
00022 #include <boost/numeric/ublas/triangular.hpp>
00023 #include <boost/numeric/ublas/io.hpp>
00024
00025 #include <algorithm>
00026 #include <iomanip>
00027
00028 #include <math.h>
00029
00030 #include "rf_full.hpp"
00031 #include "my_expression.hpp"
00032
00033 RFFull::RFFull()
00034 {
00035
00036 }
00037
00038 RFFull::RFFull(Types::Input c) :
00039 RF(c),
00040 D(c.size(),c.size()),
00041 M(c.size(),c.size()),
00042 alpha(c.size(),c.size()),
00043 dwdM(c.size(),c.size()),
00044 dJ2dM(c.size(),c.size()),
00045 dJdM(c.size(),c.size()),
00046 meta_h(c.size(),c.size()),
00047 b(c.size(),c.size()),
00048 dJ2_2dM_2(c.size(),c.size()),
00049 dw_2dM_2(c.size(),c.size()),
00050 aux(c.size(),c.size())
00051 {
00052 D.assign(d_def*ublas::identity_matrix<Types::RValue>(c.size()));
00053 M.assign(sqrt(d_def)*ublas::identity_matrix<Types::RValue>(c.size()));
00054 alpha.assign(ublas::scalar_matrix<Types::RParam>(c.size(),c.size(),alpha_init));
00055
00056 dwdM.clear();
00057 dJ2dM.clear();
00058 dJdM.clear();
00059 dJ2_2dM_2.clear();
00060 dw_2dM_2.clear();
00061 aux.clear();
00062
00063 meta_h.clear();
00064 b.assign(ublas::scalar_matrix<Types::RParam>(c.size(),c.size(),std::log(alpha_init+1e-10)));
00065 }
00066
00067 RFFull::RFFull(Types::Input c, const boost::program_options::variables_map& vm) :
00068 RF(c,vm),
00069 D(c.size(),c.size()),
00070 M(c.size(),c.size()),
00071 alpha(c.size(),c.size()),
00072 dwdM(c.size(),c.size()),
00073 dJ2dM(c.size(),c.size()),
00074 dJdM(c.size(),c.size()),
00075 meta_h(c.size(),c.size()),
00076 b(c.size(),c.size()),
00077 dJ2_2dM_2(c.size(),c.size()),
00078 dw_2dM_2(c.size(),c.size()),
00079 aux(c.size(),c.size())
00080 {
00081 D.assign(d_def*ublas::identity_matrix<Types::RValue>(c.size()));
00082 M.assign(sqrt(d_def)*ublas::identity_matrix<Types::RValue>(c.size()));
00083
00084 alpha.assign(ublas::scalar_matrix<Types::RParam>(c.size(),c.size(),alpha_init));
00085
00086 dwdM.clear();
00087 dJ2dM.clear();
00088 dJdM.clear();
00089 dJ2_2dM_2.clear();
00090 dw_2dM_2.clear();
00091 aux.clear();
00092
00093 meta_h.clear();
00094 b.assign(ublas::scalar_matrix<Types::RParam>(c.size(),c.size(),std::log(alpha_init+1e-10)));
00095 }
00096
00097 RFFull::RFFull(const RFFull& rf, Types::Input c, const boost::program_options::variables_map& vm) :
00098 RF(c, vm),
00099 D(c.size(),c.size()),
00100 M(c.size(),c.size()),
00101 alpha(c.size(),c.size()),
00102 dwdM(c.size(),c.size()),
00103 dJ2dM(c.size(),c.size()),
00104 dJdM(c.size(),c.size()),
00105 meta_h(c.size(),c.size()),
00106 b(c.size(),c.size()),
00107 dJ2_2dM_2(c.size(),c.size()),
00108 dw_2dM_2(c.size(),c.size()),
00109 aux(c.size(),c.size())
00110 {
00111 std::cerr << "Adding Receptive Field" << std::endl;
00112 alpha.assign(rf.getAlpha());
00113 D.assign(rf.getD());
00114 M.assign(rf.getM());
00115
00116 dwdM.clear();
00117 dJ2dM.clear();
00118 dJdM.clear();
00119 dJ2_2dM_2.clear();
00120 dw_2dM_2.clear();
00121 aux.clear();
00122
00123 meta_h.clear();
00124 b.assign(ublas::scalar_matrix<Types::RParam>(c.size(),c.size(),std::log(alpha_init+1e-10)));
00125 }
00126
00127
00128 Types::RValue RFFull::learn(Types::Input x, Types::Output y, Types::RValueP w) {
00129
00130
00131
00132
00133 const Types::RValue W_old = W;
00134 W = lambda * W + w;
00135
00136
00137 localModel.learn(x,y,w,W,W_old);
00138
00139
00140 const Types::RValue e_cv = localModel.get_e_cv();
00141 const Types::RValue e = localModel.get_e();
00142 Types::Input z = localModel.get_z();
00143
00144
00145
00146
00147
00148 Types::Input derivative = localModel.check_derivatives();
00149
00150 if(derivative(0) != 0){
00151
00152
00153 e_2 = lambda * e_2 + w*e*e;
00154
00155
00156
00157 a_E = lambda * a_E + w*e_cv*e_cv;
00158
00159 Types::RValue transient_multiplier = std::min(1.0, pow( e_2 / (a_E + 1e-10) , 4));
00160
00161
00162 q = element_div(element_prod(z,derivative),localModel.get_a_zz());
00163
00164
00165 a_pk = lambda*a_pk + w*w*prec_inner_prod(q,z);
00166
00167 const Types::RValue dJ1dw = (e_cv*e_cv)/W - 2*e/W * prec_inner_prod(q,a_H) - 2/W*prec_inner_prod(element_prod(q,q),a_G) - a_E/(W*W);
00168
00169 temp2 = x - center;
00170
00171 dwdM.clear();
00172
00173
00174 for(int k=0; k<dwdM.size1(); ++k)
00175 for(int l=k; l<dwdM.size2(); ++l){
00176 Types::RValue sum_aux = 0;
00177 Types::RValue dDdM_2 = 0;
00178
00179
00180 for(int i=0; i<dwdM.size1(); ++i){
00181 sum_aux += D(i,l)*M(k,i)*2;
00182 dwdM(k,l) += temp2(i)*temp2(l)*M(k,i)*((i==l)?2:1);
00183
00184 if(meta)
00185 dDdM_2 += (M(k,i)*M(k,i)*((i==l)?2:1)) * 2;
00186
00187 }
00188
00189 dwdM(k,l) = -0.5 * w * dwdM(k,l);
00190 dJ2dM(k,l) = 2 * gamma / center.size() * sum_aux;
00191
00192 if(meta)
00193 {
00194 dJ2_2dM_2(k,l) = 2*gamma/center.size()*(2*D(l,l) + dDdM_2);
00195 dw_2dM_2(k,l) = dwdM(k,l)*dwdM(k,l)/w - w*temp2(k)*temp2(k);
00196 }
00197
00198 }
00199
00200 dJdM = dJ1dw * dwdM + (w/W)*dJ2dM;
00201
00202
00203 const Types::RValue h = w * prec_inner_prod(z,q);
00204
00205 if(meta){
00206 const Types::RValue dJ1_2dw_2 = -(e_cv*e_cv)/(W*W)
00207 + 2*e*e*h/(W*w)
00208 + a_E/(W*W*W)
00209 - 2/W*((-(e/W) - 2*e*prec_inner_prod(q,z))*prec_inner_prod(q,a_H))
00210 - 1/(W*W)*( (e_cv*e_cv) - 2*e*prec_inner_prod(q,a_H) );
00211
00212 dJ_2dM_2 = (dw_2dM_2*dJ1dw + element_prod(dwdM,dwdM)*dJ1_2dw_2) + w/W*dJ2_2dM_2;
00213
00214 aux = meta_alpha * transient_multiplier * element_prod(dJdM,meta_h);
00215
00216 for(int i=0; i<aux.size1(); ++i)
00217 for(int j=i; j<aux.size2(); ++j)
00218 if(fabs(aux(i,j)) > 0.1)
00219 aux(i,j) = 0.1 * ((aux(i,j)>0)?1:-1);
00220
00221 b -= aux;
00222
00223 for(int i=0; i<b.size1(); ++i)
00224 for(int j=i; j<b.size2(); ++j)
00225 if(fabs(b(i,j)) > 10)
00226 b(i,j) = 10 * ((b(i,j)>0)?1:-1);
00227
00228
00229 alpha = (ublas::apply_to_all<ublas::scalar_exp<Types::RValue> >( b ));
00230
00231 aux = ublas::scalar_matrix<Types::RValue>(alpha.size1(),alpha.size2(),1.0) - (element_prod(alpha,dJ_2dM_2)*transient_multiplier);
00232
00233 for(int i=0; i<aux.size1(); ++i)
00234 for(int j=i; j<aux.size2(); ++j)
00235 if(aux(i,j) < 0.0)
00236 aux(i,j) = 0;
00237
00238 meta_h = element_prod(meta_h,aux) - element_prod(alpha,dJdM)*transient_multiplier;
00239 }
00240
00241
00242 H_temp = lambda * a_H + (w*e_cv*z*transient_multiplier)/(1-h);
00243 a_H = element_prod(derivative, H_temp) + element_prod(ublas::scalar_vector<Types::RValue>(derivative.size(),1.0)-derivative,a_H);
00244 H_temp = lambda * a_G + (w*w*(e_cv*e_cv)*element_prod(z,z)*transient_multiplier)/(1-h);
00245 a_G = element_prod(derivative, H_temp) + element_prod(ublas::scalar_vector<Types::RValue>(derivative.size(),1.0)-derivative,a_G);
00246
00247
00248 Types::RValue maxM = 0.0;
00249 for(int i=0; i<M.size1(); ++i)
00250 for(int j=i; j<M.size2(); ++j)
00251 if(fabs(M(i,j)) > maxM)
00252 maxM = fabs(M(i,j));
00253
00254 for(int i=0; i<alpha.size1(); ++i)
00255 for(int j=i; j<alpha.size2(); ++j)
00256 if(alpha(i,j) * dJdM(i,j) * transient_multiplier > .1*maxM)
00257 alpha(i,j) /= 2;
00258
00259
00260
00261 M -= element_prod(alpha,dJdM) * transient_multiplier;
00262 D = prod(trans(M),M);
00263
00264 }
00265
00266
00267
00268 if(localModel.updateNumProjections()){
00269 int R = a_H.size()+1;
00270 a_H.resize(R);
00271 a_H(R-1) = 0;
00272 a_G.resize(R);
00273 a_G(R-1) = 0;
00274 H_temp.resize(R);
00275 }
00276
00277 }
00278
00279 std::ostream& operator<<(std::ostream& out, const RFFull& rf)
00280 {
00281 out << rf.center(0) << " " << rf.center(1) << " ";
00282 out << rf.D(0,0) << " " << rf.D(0,1) << " " << rf.D(1,0) << " " << rf.D(1,1) << std::endl;
00283 }