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
00051 #include <expat.h>
00052 #include <cassert>
00053 #include <vector>
00054 #include <map>
00055 #include <string>
00056 #include <iostream>
00057 #include <iterator>
00058 #include <sstream>
00059 #include "cvgenericplane.h"
00060 #include "cvconvnetparser.h"
00061 #include "cvsourceplane.h"
00062 #include "cvconvolutionplane.h"
00063 #include "cvsubsamplingplane.h"
00064 #include "cvgenericplane.h"
00065 #include "cvrbfplane.h"
00066 #include "cvmaxplane.h"
00067
00068
00069
00070 const int INSIDE_TAG=1<<0;
00071 const int FOUND_VALUE=1<<1;
00072
00073
00074 using namespace std;
00075
00076
00077
00078
00079
00081
00085 typedef struct
00086 {
00087
00088 string &creator;
00089 string &name;
00090 string &info;
00091
00092
00093 vector<CvGenericPlane *> &plane;
00094 map<string,int> &idmap;
00095
00096
00097 int depth;
00098 int isbias;
00099 int isinfo;
00100 int isconnection;
00101 vector<double> cur_weight;
00102 vector<CvGenericPlane *> cur_parents;
00103 string cur_type;
00104
00105
00106 XML_Parser &parser;
00107 } XMLparserData;
00108
00110 static void XMLCALL icvXML_StopParser(XML_Parser &parser, string errstr)
00111 {
00112 cout << "XML Error: " << errstr << endl;
00113 XML_StopParser(parser,XML_FALSE);
00114 }
00115
00117 #define CHK_POSSIBLE_FAIL(x,y) if ( x ) { \
00118 icvXML_StopParser(data.parser,(y));\
00119 return; }
00120
00122 static void XMLCALL icvXML_StartElementHandler (void *userData, const XML_Char *name, const XML_Char **atts)
00123 {
00124 assert( userData != NULL && name != NULL );
00125
00126 XMLparserData &data = *((XMLparserData *) userData);
00127 string namestr (name);
00128
00129 if ((namestr == "net") && (data.depth == 0))
00130
00131 {
00132
00133 for (signed int i = data.plane.size()-1; i >= 0; i--)
00134 {
00135 assert ( data.plane[i] != NULL );
00136 delete data.plane[i];
00137 }
00138
00139
00140 data.plane.clear();
00141 data.creator.clear();
00142 data.name.clear();
00143 data.idmap.clear();
00144 data.isbias = 0;
00145 data.isinfo = 0;
00146
00147 for (int i=0; (atts[i]!=NULL) && (atts[i+1]!=NULL); i+=2)
00148 {
00149 string attr = atts[i];
00150 string val = atts[i+1];
00151
00152 if (attr=="creator")
00153 data.creator = val;
00154 if (attr=="name")
00155 data.name = val;
00156 }
00157 }
00158 else if ((namestr == "plane") && (data.depth == 1))
00159
00160 {
00161 int curplaneid = data.plane.size();
00162 string planeid,planetype;
00163 int fmapszx = 0, fmapszy = 0, neuroszx = 0, neuroszy = 0;
00164
00165
00166 data.cur_parents.clear();
00167 data.cur_weight.clear();
00168 data.isbias = 0;
00169 data.isconnection = 0;
00170
00171 for (int i=0; (atts[i]!=NULL) && (atts[i+1]!=NULL); i+=2)
00172 {
00173 string attr = atts[i];
00174 string val = atts[i+1];
00175 if (attr=="id") planeid = val;
00176 if (attr=="type") planetype = val;
00177 if (attr=="featuremapsize")
00178 {
00179 istringstream iss ( val );
00180 char c;
00181 iss >> fmapszx >> c >> fmapszy;
00182 }
00183 if (attr=="neuronsize")
00184 {
00185 istringstream iss ( val );
00186 char c;
00187 iss >> neuroszx >> c >> neuroszy;
00188 }
00189 }
00190
00191 CHK_POSSIBLE_FAIL( planeid.size()==0 , "plane has no id");
00192
00193
00194 if (planetype != "max")
00195 {
00196 CHK_POSSIBLE_FAIL( (fmapszx <= 0 || fmapszy <= 0 || fmapszx > CVCONVOLUTIONALNET_MAX_FMAPSZ || fmapszy > CVCONVOLUTIONALNET_MAX_FMAPSZ) ,"feature map size is inconsistent");
00197
00198 CHK_POSSIBLE_FAIL( (neuroszx < 0 || neuroszy < 0 || neuroszx > CVCONVOLUTIONALNET_MAX_FMAPSZ || neuroszy > CVCONVOLUTIONALNET_MAX_FMAPSZ), "neuron window size is inconsistent");
00199 }
00200
00201
00202 if (planetype=="source")
00203 {
00204 data.plane.push_back(
00205 new CvSourcePlane(planeid,cvSize(fmapszx,fmapszy))
00206 );
00207 data.idmap[planeid] = curplaneid;
00208 } else if (planetype=="convolution")
00209 {
00210 data.plane.push_back(
00211 new CvConvolutionPlane(planeid,cvSize(fmapszx,fmapszy),cvSize(neuroszx,neuroszy))
00212 );
00213 data.idmap[planeid] = curplaneid;
00214 } else if (planetype=="subsampling")
00215 {
00216 data.plane.push_back(
00217 new CvSubSamplingPlane(planeid,cvSize(fmapszx,fmapszy),cvSize(neuroszx,neuroszy))
00218 );
00219 data.idmap[planeid] = curplaneid;
00220 } else if (planetype=="rbf")
00221 {
00222 data.plane.push_back(
00223 new CvRBFPlane(planeid,cvSize(fmapszx,fmapszy),cvSize(neuroszx,neuroszy))
00224 );
00225 data.idmap[planeid] = curplaneid;
00226 } else if (planetype=="max")
00227 {
00228 data.plane.push_back(
00229 new CvMaxPlane(planeid)
00230 );
00231 data.idmap[planeid] = curplaneid;
00232 } else
00233 {
00234 CHK_POSSIBLE_FAIL(1, "plane "+planeid+" has no type or unidentified type");
00235 }
00236 data.cur_type = planetype;
00237 data.cur_weight.clear();
00238 } else if ((namestr == "connection") && (data.depth==2))
00239
00240 {
00241 int curplaneid = data.plane.size()-1;
00242
00243 for (int i=0; (atts[i]!=NULL) && (atts[i+1]!=NULL); i+=2)
00244 {
00245 string attr = atts[i];
00246 string val = atts[i+1];
00247
00248 if (attr=="to")
00249 {
00250
00251 map<string,int>::iterator itr = data.idmap.find(val);
00252
00253 CHK_POSSIBLE_FAIL (itr == data.idmap.end(), "Connection to non-existing plane or graph is not topologically sorted! Attempt to connect to \""+val+"\"");
00254
00255 data.cur_parents.push_back(data.plane[itr->second]);
00256 }
00257 }
00258 data.isconnection |= INSIDE_TAG;
00259 }
00260 else if ((namestr == "bias") && (data.depth==2))
00261 {
00262 data.isbias |= INSIDE_TAG;
00263
00264 CHK_POSSIBLE_FAIL(data.cur_type=="max","<bias> defined for max plane");
00265 }
00266 else if ((namestr == "info") && (data.depth == 1))
00267 {
00268 data.isinfo |= INSIDE_TAG;
00269
00270 } else
00271 {
00272
00273 CHK_POSSIBLE_FAIL(1,"undefined or misplaced tag <"+namestr+"> found");
00274 }
00275
00276 data.depth++;
00277 }
00278
00280 static void XMLCALL icvXML_EndElementHandler(void *userData, const XML_Char *name)
00281 {
00282 assert( userData != NULL && name != NULL);
00283
00284 XMLparserData &data = *((XMLparserData *) userData);
00285 data.depth--;
00286
00287 string namestr (name);
00288
00289 if ((namestr == "plane") && (data.depth == 1))
00290 {
00291
00292 vector<CvGenericPlane *>::iterator i = data.plane.end()-1;
00293
00294
00295 CHK_POSSIBLE_FAIL( (!(data.isbias & FOUND_VALUE)) && (data.cur_type=="convolution" || data.cur_type=="subsampling"), "no bias found");
00296
00297
00298 CHK_POSSIBLE_FAIL( (data.cur_parents.size()==0) && (data.cur_type!="source"), "plane is not connected to anything");
00299
00300
00301 CHK_POSSIBLE_FAIL( !(*i)->connto(data.cur_parents), "failed to accomplish connections");
00302
00303
00304 CHK_POSSIBLE_FAIL( !(*i)->setweight(data.cur_weight), "failed to assign weights");
00305
00306
00307 data.cur_parents.clear();
00308 data.cur_weight.clear();
00309 data.isbias = 0;
00310 data.isconnection = 0;
00311 } else if ((namestr == "connection") && (data.depth == 2))
00312 {
00313 data.isconnection &= ~INSIDE_TAG;
00314 } else if ((namestr == "bias") && (data.depth == 2))
00315 {
00316 data.isbias &= ~INSIDE_TAG;
00317 } else if ((namestr == "info") && (data.depth == 1))
00318 {
00319 data.isinfo &= ~INSIDE_TAG;
00320 }
00321 }
00322
00324 static void XMLCALL icvXML_CharacterDataHandler(void *userData, const XML_Char *s, int len)
00325 {
00326 assert( userData != NULL && s != NULL);
00327
00328 XMLparserData &data = *((XMLparserData *) userData);
00329
00330 string weights(s,len);
00331 istringstream iss(weights);
00332
00333 double w;
00334 if (data.isbias & INSIDE_TAG)
00335
00336 {
00337 if (iss >> w)
00338 {
00339 data.cur_weight.insert(data.cur_weight.begin(),w);
00340 data.isbias |= FOUND_VALUE;
00341 }
00342
00343 } else if (data.isinfo & INSIDE_TAG)
00344
00345 {
00346 iss >> data.info;
00347 data.isinfo |= FOUND_VALUE;
00348 } else if (data.isconnection & INSIDE_TAG)
00349
00350 {
00351 while (iss >> w)
00352 {
00353 CHK_POSSIBLE_FAIL(data.cur_type=="max","weights defined for MAX plane. Nonsense!");
00354 data.cur_weight.push_back(w);
00355 }
00356 data.isconnection |= FOUND_VALUE;
00357 };
00358
00359 }
00360
00362 int parse(string xml, string &creator,
00363 string &name,
00364 string &info,
00365 vector<CvGenericPlane *> &plane,
00366 map<string,int> &idmap)
00367 {
00368 XML_Parser parser = XML_ParserCreate(NULL);
00369
00370
00371 XMLparserData handlerdata =
00372 {
00373 creator,
00374 name,
00375 info,
00376
00377 plane,
00378 idmap,
00379
00380 0,
00381 0,
00382 0,
00383 0,
00384
00385 vector<double> (),
00386 vector<CvGenericPlane *> (),
00387 "",
00388 parser
00389 };
00390
00391
00392 XML_SetUserData(parser,&handlerdata);
00393 XML_SetElementHandler(parser, icvXML_StartElementHandler, icvXML_EndElementHandler);
00394 XML_SetCharacterDataHandler(parser, icvXML_CharacterDataHandler);
00395
00396 int errcode = 1;
00397
00398
00399 if ( XML_Parse(parser, xml.c_str(), xml.size(), 1) == XML_STATUS_ERROR )
00400 {
00401 cerr << "Error parsing the XML: " << XML_ErrorString( XML_GetErrorCode(parser) ) << " at line " << XML_GetCurrentLineNumber(parser) << endl;
00402 errcode = 0;
00403 }
00404 XML_ParserFree(parser);
00405
00406 return errcode;
00407 }