SemSegNovelty.cpp 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519
  1. #include <sstream>
  2. #include <iostream>
  3. #include "core/image/FilterT.h"
  4. #include "core/basics/numerictools.h"
  5. #include "core/basics/StringTools.h"
  6. #include "core/basics/Timer.h"
  7. #include "gp-hik-exp/GPHIKClassifierNICE.h"
  8. #include "vislearning/baselib/ICETools.h"
  9. #include "vislearning/baselib/Globals.h"
  10. #include "vislearning/features/fpfeatures/SparseVectorFeature.h"
  11. #include "segmentation/GenericRegionSegmentationMethodSelection.h"
  12. #include "SemSegNovelty.h"
  13. using namespace std;
  14. using namespace NICE;
  15. using namespace OBJREC;
  16. SemSegNovelty::SemSegNovelty ( const Config *conf,
  17. const MultiDataset *md )
  18. : SemanticSegmentation ( conf, & ( md->getClassNames ( "train" ) ) )
  19. {
  20. this->conf = conf;
  21. globalMaxUncert = -numeric_limits<double>::max();
  22. string section = "SemSegNovelty";
  23. featExtract = new LocalFeatureColorWeijer ( conf );
  24. this->reuseSegmentation = conf->gB ( "FPCPixel", "reuseSegmentation", true ); //save and read segmentation results from files
  25. this->save_classifier = conf->gB ( "FPCPixel", "save_classifier", true ); //save the classifier to a file
  26. this->read_classifier = conf->gB ( "FPCPixel", "read_classifier", false ); //read the classifier from a file
  27. //write uncertainty results in the same folder as done for the segmentation results
  28. resultdir = conf->gS("debug", "resultdir", "result");
  29. cache = conf->gS ( "cache", "root", "" );
  30. //stupid work around of the const attribute
  31. Config confCopy = *conf;
  32. //just to make sure, that we do NOT perform an optimization after every iteration step
  33. //this would just take a lot of time, which is not desired so far
  34. confCopy.sB("ClassifierGPHIK","performOptimizationAfterIncrement",false);
  35. classifierString = conf->gS ( section, "classifier", "ClassifierGPHIK" );
  36. classifier = NULL;
  37. vclassifier = NULL;
  38. if ( classifierString.compare("ClassifierGPHIK") == 0)
  39. classifier = new GPHIKClassifierNICE ( &confCopy, "ClassifierGPHIK" );
  40. else
  41. vclassifier = GenericClassifierSelection::selectVecClassifier ( conf, classifierString );
  42. findMaximumUncert = conf->gB(section, "findMaximumUncert", true);
  43. whs = conf->gI ( section, "window_size", 10 );
  44. //distance to next descriptor during training
  45. trainWsize = conf->gI ( section, "train_window_size", 10 );
  46. //distance to next descriptor during testing
  47. testWSize = conf->gI (section, "test_window_size", 10);
  48. // select your segmentation method here
  49. string rsMethode = conf->gS ( section, "segmentation", "none" );
  50. if(rsMethode == "none")
  51. {
  52. regionSeg = NULL;
  53. }
  54. else
  55. {
  56. RegionSegmentationMethod *tmpRegionSeg = GenericRegionSegmentationMethodSelection::selectRegionSegmentationMethod(conf, rsMethode);
  57. if ( reuseSegmentation )
  58. regionSeg = new RSCache ( conf, tmpRegionSeg );
  59. else
  60. regionSeg = tmpRegionSeg;
  61. }
  62. cn = md->getClassNames ( "train" );
  63. if ( read_classifier )
  64. {
  65. try
  66. {
  67. if ( classifier != NULL )
  68. {
  69. string classifierdst = "/classifier.data";
  70. fprintf ( stderr, "SemSegNovelty:: Reading classifier data from %s\n", ( cache + classifierdst ).c_str() );
  71. classifier->read ( cache + classifierdst );
  72. }
  73. else
  74. {
  75. string classifierdst = "/veccl.data";
  76. fprintf ( stderr, "SemSegNovelty:: Reading classifier data from %s\n", ( cache + classifierdst ).c_str() );
  77. vclassifier->read ( cache + classifierdst );
  78. }
  79. fprintf ( stderr, "SemSegNovelty:: successfully read\n" );
  80. }
  81. catch ( char *str )
  82. {
  83. cerr << "error reading data: " << str << endl;
  84. }
  85. }
  86. else
  87. {
  88. train ( md );
  89. }
  90. //define which measure for "novelty" we want to use
  91. noveltyMethodString = conf->gS( section, "noveltyMethod", "gp-variance");
  92. if (noveltyMethodString.compare("gp-variance") == 0) // novel = large variance
  93. {
  94. this->noveltyMethod = GPVARIANCE;
  95. this->mostNoveltyWithMaxScores = true;
  96. }
  97. else if (noveltyMethodString.compare("gp-uncertainty") == 0) //novel = large uncertainty (mean / var)
  98. {
  99. this->noveltyMethod = GPUNCERTAINTY;
  100. this->mostNoveltyWithMaxScores = false;
  101. globalMaxUncert = numeric_limits<double>::max();
  102. }
  103. else if (noveltyMethodString.compare("gp-mean") == 0) //novel = small mean
  104. {
  105. this->noveltyMethod = GPMINMEAN;
  106. this->mostNoveltyWithMaxScores = false;
  107. globalMaxUncert = numeric_limits<double>::max();
  108. }
  109. else if (noveltyMethodString.compare("gp-meanRatio") == 0) //novel = small difference between mean of most plausible class and mean of snd
  110. // most plausible class (not useful in binary settings)
  111. {
  112. this->noveltyMethod = GPMEANRATIO;
  113. this->mostNoveltyWithMaxScores = false;
  114. globalMaxUncert = numeric_limits<double>::max();
  115. }
  116. else if (noveltyMethodString.compare("gp-weightAll") == 0) // novel = large weight in alpha vector after updating the model (can be predicted exactly)
  117. {
  118. this->noveltyMethod = GPWEIGHTALL;
  119. this->mostNoveltyWithMaxScores = true;
  120. }
  121. else if (noveltyMethodString.compare("gp-weightRatio") == 0) // novel = small difference between weights for alpha vectors
  122. // with assumptions of GT label to be the most
  123. // plausible against the second most plausible class
  124. {
  125. this->noveltyMethod = GPWEIGHTRATIO;
  126. this->mostNoveltyWithMaxScores = false;
  127. globalMaxUncert = numeric_limits<double>::max();
  128. }
  129. else if (noveltyMethodString.compare("random") == 0)
  130. {
  131. initRand();
  132. this->noveltyMethod = RANDOM;
  133. }
  134. else
  135. {
  136. this->noveltyMethod = GPVARIANCE;
  137. this->mostNoveltyWithMaxScores = true;
  138. }
  139. //we don't have queried any region so far
  140. queriedRegions.clear();
  141. visualizeALimages = conf->gB(section, "visualizeALimages", false);
  142. }
  143. SemSegNovelty::~SemSegNovelty()
  144. {
  145. if(newTrainExamples.size() > 0)
  146. {
  147. // show most uncertain region
  148. if (visualizeALimages)
  149. showImage(maskedImg);
  150. //incorporate new information into the classifier
  151. if (classifier != NULL)
  152. classifier->addMultipleExamples(newTrainExamples);
  153. //store the classifier, such that we can read it again in the next round (if we like that)
  154. classifier->save ( cache + "/classifier.data" );
  155. }
  156. // clean-up
  157. if ( classifier != NULL )
  158. delete classifier;
  159. if ( vclassifier != NULL )
  160. delete vclassifier;
  161. if ( featExtract != NULL )
  162. delete featExtract;
  163. }
  164. void SemSegNovelty::visualizeRegion(const NICE::ColorImage &img, const NICE::Matrix &regions, int region, NICE::ColorImage &outimage)
  165. {
  166. std::vector<uchar> color;
  167. color.push_back(255);
  168. color.push_back(0);
  169. color.push_back(0);
  170. int width = img.width();
  171. int height = img.height();
  172. outimage.resize(width,height);
  173. for(int y = 0; y < height; y++)
  174. {
  175. for(int x = 0; x < width; x++)
  176. {
  177. if(regions(x,y) == region)
  178. {
  179. for(int c = 0; c < 3; c++)
  180. {
  181. outimage(x,y,c) = color[c];
  182. }
  183. }
  184. else
  185. {
  186. for(int c = 0; c < 3; c++)
  187. {
  188. outimage(x,y,c) = img(x,y,c);
  189. }
  190. }
  191. }
  192. }
  193. }
  194. void SemSegNovelty::train ( const MultiDataset *md )
  195. {
  196. const LabeledSet train = * ( *md ) ["train"];
  197. const LabeledSet *trainp = &train;
  198. ////////////////////////
  199. // feature extraction //
  200. ////////////////////////
  201. //check the same thing for the training classes - this is very specific to our setup
  202. std::string forbidden_classesTrain_s = conf->gS ( "analysis", "donttrainTrain", "" );
  203. if ( forbidden_classesTrain_s == "" )
  204. {
  205. forbidden_classesTrain_s = conf->gS ( "analysis", "forbidden_classesTrain", "" );
  206. }
  207. cn.getSelection ( forbidden_classesTrain_s, forbidden_classesTrain );
  208. ProgressBar pb ( "Local Feature Extraction" );
  209. pb.show();
  210. int imgnb = 0;
  211. Examples examples;
  212. examples.filename = "training";
  213. int featdim = -1;
  214. classesInUse.clear();
  215. LOOP_ALL_S ( *trainp )
  216. {
  217. //EACH_S(classno, currentFile);
  218. EACH_INFO ( classno, info );
  219. std::string currentFile = info.img();
  220. CachedExample *ce = new CachedExample ( currentFile );
  221. const LocalizationResult *locResult = info.localization();
  222. if ( locResult->size() <= 0 )
  223. {
  224. fprintf ( stderr, "WARNING: NO ground truth polygons found for %s !\n",
  225. currentFile.c_str() );
  226. continue;
  227. }
  228. int xsize, ysize;
  229. ce->getImageSize ( xsize, ysize );
  230. Image labels ( xsize, ysize );
  231. labels.set ( 0 );
  232. locResult->calcLabeledImage ( labels, ( *classNames ).getBackgroundClass() );
  233. NICE::ColorImage img;
  234. try {
  235. img = ColorImage ( currentFile );
  236. } catch ( Exception ) {
  237. cerr << "SemSegNovelty: error opening image file <" << currentFile << ">" << endl;
  238. continue;
  239. }
  240. Globals::setCurrentImgFN ( currentFile );
  241. MultiChannelImageT<double> feats;
  242. // extract features
  243. featExtract->getFeats ( img, feats );
  244. featdim = feats.channels();
  245. feats.addChannel(featdim);
  246. for (int c = 0; c < featdim; c++)
  247. {
  248. ImageT<double> tmp = feats[c];
  249. ImageT<double> tmp2 = feats[c+featdim];
  250. NICE::FilterT<double, double, double>::gradientStrength (tmp, tmp2);
  251. }
  252. featdim += featdim;
  253. // compute integral images
  254. for ( int c = 0; c < featdim; c++ )
  255. {
  256. feats.calcIntegral ( c );
  257. }
  258. for ( int y = 0; y < ysize; y += trainWsize)
  259. {
  260. for ( int x = 0; x < xsize; x += trainWsize )
  261. {
  262. int classnoTmp = labels.getPixel ( x, y );
  263. if ( forbidden_classesTrain.find ( classnoTmp ) != forbidden_classesTrain.end() )
  264. {
  265. continue;
  266. }
  267. if (classesInUse.find(classnoTmp) == classesInUse.end())
  268. {
  269. classesInUse.insert(classnoTmp);
  270. }
  271. Example example;
  272. example.vec = NULL;
  273. example.svec = new SparseVector ( featdim );
  274. for ( int f = 0; f < featdim; f++ )
  275. {
  276. double val = feats.getIntegralValue ( x - whs, y - whs, x + whs, y + whs, f );
  277. if ( val > 1e-10 )
  278. ( *example.svec ) [f] = val;
  279. }
  280. example.svec->normalize();
  281. example.position = imgnb;
  282. examples.push_back ( pair<int, Example> ( classnoTmp, example ) );
  283. }
  284. }
  285. delete ce;
  286. imgnb++;
  287. pb.update ( trainp->count() );
  288. }
  289. numberOfClasses = classesInUse.size();
  290. std::cerr << "numberOfClasses: " << numberOfClasses << std::endl;
  291. std::cerr << "classes in use: " << std::endl;
  292. for (std::set<int>::const_iterator it = classesInUse.begin(); it != classesInUse.end(); it++)
  293. {
  294. std::cerr << *it << " ";
  295. }
  296. std::cerr << std::endl;
  297. pb.hide();
  298. //////////////////////
  299. // train classifier //
  300. //////////////////////
  301. FeaturePool fp;
  302. Feature *f = new SparseVectorFeature ( featdim );
  303. f->explode ( fp );
  304. delete f;
  305. if ( classifier != NULL )
  306. {
  307. std::cerr << "train FP-classifier with " << examples.size() << " examples" << std::endl;
  308. classifier->train ( fp, examples );
  309. std::cerr << "training finished" << std::endl;
  310. }
  311. else
  312. {
  313. LabeledSetVector lvec;
  314. convertExamplesToLSet ( examples, lvec );
  315. vclassifier->teach ( lvec );
  316. // if ( usegmm )
  317. // convertLSetToSparseExamples ( examples, lvec );
  318. // else
  319. std::cerr << "classifierString: " << classifierString << std::endl;
  320. if (this->classifierString.compare("nn") == 0)
  321. {
  322. convertLSetToExamples ( examples, lvec, true /* only remove pointers to the data in the LSet-struct*/);
  323. }
  324. else
  325. {
  326. convertLSetToExamples ( examples, lvec, false /* remove all training examples of the LSet-struct */);
  327. }
  328. vclassifier->finishTeaching();
  329. }
  330. fp.destroy();
  331. if ( save_classifier )
  332. {
  333. if ( classifier != NULL )
  334. classifier->save ( cache + "/classifier.data" );
  335. else
  336. vclassifier->save ( cache + "/veccl.data" );
  337. }
  338. ////////////
  339. //clean up//
  340. ////////////
  341. for ( int i = 0; i < ( int ) examples.size(); i++ )
  342. {
  343. examples[i].second.clean();
  344. }
  345. examples.clear();
  346. cerr << "SemSeg training finished" << endl;
  347. }
  348. void SemSegNovelty::semanticseg ( CachedExample *ce, NICE::Image & segresult, NICE::MultiChannelImageT<double> & probabilities )
  349. {
  350. Timer timer;
  351. timer.start();
  352. //segResult contains the GT labels when this method is called
  353. // we simply store them in labels, to have an easy access to the GT information lateron
  354. Image labels = segresult;
  355. //just to be sure that we do not have a GT-biased result :)
  356. segresult.set(0);
  357. int featdim = -1;
  358. std::string currentFile = Globals::getCurrentImgFN();
  359. int xsize, ysize;
  360. ce->getImageSize ( xsize, ysize );
  361. probabilities.reInit( xsize, ysize, cn.getMaxClassno() + 1);
  362. probabilities.setAll ( 0.0 );
  363. NICE::ColorImage img;
  364. try {
  365. img = ColorImage ( currentFile );
  366. } catch ( Exception ) {
  367. cerr << "SemSegNovelty: error opening image file <" << currentFile << ">" << endl;
  368. return;
  369. }
  370. MultiChannelImageT<double> feats;
  371. // extract features
  372. featExtract->getFeats ( img, feats );
  373. featdim = feats.channels();
  374. feats.addChannel(featdim);
  375. for (int c = 0; c < featdim; c++)
  376. {
  377. ImageT<double> tmp = feats[c];
  378. ImageT<double> tmp2 = feats[c+featdim];
  379. NICE::FilterT<double, double, double>::gradientStrength (tmp, tmp2);
  380. }
  381. featdim += featdim;
  382. // compute integral images
  383. for ( int c = 0; c < featdim; c++ )
  384. {
  385. feats.calcIntegral ( c );
  386. }
  387. timer.stop();
  388. std::cout << "AL time for preparation: " << timer.getLastAbsolute() << std::endl;
  389. timer.start();
  390. //classification results currently only needed to be computed separately if we use the vclassifier, i.e., the nearest neighbor used
  391. // for the "novel feature learning" approach
  392. //in all other settings, such as active sem seg in general, we do this within the novelty-computation-methods
  393. if ( classifier == NULL )
  394. {
  395. this->computeClassificationResults( feats, segresult, probabilities, xsize, ysize, featdim);
  396. }
  397. // timer.stop();
  398. //
  399. // std::cerr << "classification results computed" << std::endl;
  400. FloatImage noveltyImage ( xsize, ysize );
  401. noveltyImage.set ( 0.0 );
  402. switch (noveltyMethod)
  403. {
  404. case GPVARIANCE:
  405. {
  406. this->computeNoveltyByVariance( noveltyImage, feats, segresult, probabilities, xsize, ysize, featdim );
  407. break;
  408. }
  409. case GPUNCERTAINTY:
  410. {
  411. this->computeNoveltyByGPUncertainty( noveltyImage, feats, segresult, probabilities, xsize, ysize, featdim );
  412. break;
  413. }
  414. case GPMINMEAN:
  415. {
  416. std::cerr << "compute novelty using the minimum mean" << std::endl;
  417. this->computeNoveltyByGPMean( noveltyImage, feats, segresult, probabilities, xsize, ysize, featdim );
  418. break;
  419. }
  420. case GPMEANRATIO:
  421. {
  422. this->computeNoveltyByGPMeanRatio( noveltyImage, feats, segresult, probabilities, xsize, ysize, featdim );
  423. break;
  424. }
  425. case GPWEIGHTALL:
  426. {
  427. this->computeNoveltyByGPWeightAll( noveltyImage, feats, segresult, probabilities, xsize, ysize, featdim );
  428. break;
  429. }
  430. case GPWEIGHTRATIO:
  431. {
  432. this->computeNoveltyByGPWeightRatio( noveltyImage, feats, segresult, probabilities, xsize, ysize, featdim );
  433. break;
  434. }
  435. case RANDOM:
  436. {
  437. this->computeNoveltyByRandom( noveltyImage, feats, segresult, probabilities, xsize, ysize, featdim );
  438. break;
  439. }
  440. default:
  441. {
  442. //do nothing, keep the image constant to 0.0
  443. break;
  444. }
  445. }
  446. timer.stop();
  447. std::cout << "AL time for novelty score computation: " << timer.getLastAbsolute() << std::endl;
  448. if (visualizeALimages)
  449. {
  450. ColorImage imgrgbTmp (xsize, ysize);
  451. ICETools::convertToRGB ( noveltyImage, imgrgbTmp );
  452. showImage(imgrgbTmp, "Novelty Image without Region Segmentation");
  453. }
  454. timer.start();
  455. //Regionen ermitteln
  456. if(regionSeg != NULL)
  457. {
  458. NICE::Matrix mask;
  459. int amountRegions = regionSeg->segRegions ( img, mask );
  460. //compute probs per region
  461. std::vector<std::vector<double> > regionProb(amountRegions, std::vector<double>(probabilities.channels(),0.0));
  462. std::vector<double> regionNoveltyMeasure (amountRegions, 0.0);
  463. std::vector<int> regionCounter(amountRegions, 0);
  464. std::vector<int> regionCounterNovelty(amountRegions, 0);
  465. for ( int y = 0; y < ysize; y += trainWsize) //y++)
  466. {
  467. for (int x = 0; x < xsize; x += trainWsize) //x++)
  468. {
  469. int r = mask(x,y);
  470. regionCounter[r]++;
  471. for(int j = 0; j < probabilities.channels(); j++)
  472. {
  473. regionProb[r][j] += probabilities ( x, y, j );
  474. }
  475. if ( forbidden_classesActiveLearning.find( labels(x,y) ) == forbidden_classesActiveLearning.end() )
  476. {
  477. //count the amount of "novelty" for the corresponding region
  478. regionNoveltyMeasure[r] += noveltyImage(x,y);
  479. regionCounterNovelty[r]++;
  480. }
  481. }
  482. }
  483. //find best class per region
  484. std::vector<int> bestClassPerRegion(amountRegions,0);
  485. double maxNoveltyScore = -numeric_limits<double>::max();
  486. if (!mostNoveltyWithMaxScores)
  487. {
  488. maxNoveltyScore = numeric_limits<double>::max();
  489. }
  490. int maxUncertRegion = -1;
  491. //loop over all regions and compute averaged novelty scores
  492. for(int r = 0; r < amountRegions; r++)
  493. {
  494. //check for the most plausible class per region
  495. double maxval = -numeric_limits<double>::max();
  496. //loop over all classes
  497. for(int c = 0; c < probabilities.channels(); c++)
  498. {
  499. regionProb[r][c] /= regionCounter[r];
  500. if( (maxval < regionProb[r][c]) ) //&& (regionProb[r][c] != 0.0) )
  501. {
  502. maxval = regionProb[r][c];
  503. bestClassPerRegion[r] = c;
  504. }
  505. }
  506. //if the region only contains unvalid information (e.g., background) skip it
  507. if (regionCounterNovelty[r] == 0)
  508. {
  509. continue;
  510. }
  511. //normalize summed novelty scores to region size
  512. regionNoveltyMeasure[r] /= regionCounterNovelty[r];
  513. //did we find a region that has a higher score as the most novel region known so far within this image?
  514. if( ( mostNoveltyWithMaxScores && (maxNoveltyScore < regionNoveltyMeasure[r]) ) // if we look for large novelty scores, e.g., variance
  515. || ( !mostNoveltyWithMaxScores && (maxNoveltyScore > regionNoveltyMeasure[r]) ) ) // if we look for small novelty scores, e.g., min mean
  516. {
  517. //did we already query a region of this image? -- and it was this specific region
  518. if ( (queriedRegions.find( currentFile ) != queriedRegions.end() ) && ( queriedRegions[currentFile].find(r) != queriedRegions[currentFile].end() ) )
  519. {
  520. continue;
  521. }
  522. else //only accept the region as novel if we never queried it before
  523. {
  524. maxNoveltyScore = regionNoveltyMeasure[r];
  525. maxUncertRegion = r;
  526. }
  527. }
  528. }
  529. // after finding the most novel region for the current image, check whether this region is also the most novel with respect
  530. // to all previously seen test images
  531. // if so, store the corresponding features, since we want to "actively" query them to incorporate useful information
  532. if(findMaximumUncert)
  533. {
  534. if( ( mostNoveltyWithMaxScores && (maxNoveltyScore > globalMaxUncert) )
  535. || ( !mostNoveltyWithMaxScores && (maxNoveltyScore < globalMaxUncert) ) )
  536. {
  537. //current most novel region of the image has "higher" novelty score then previous most novel region of all test images worked on so far
  538. // -> save new important features of this region
  539. Examples examples;
  540. for ( int y = 0; y < ysize; y += trainWsize )
  541. {
  542. for ( int x = 0; x < xsize; x += trainWsize)
  543. {
  544. if(mask(x,y) == maxUncertRegion)
  545. {
  546. int classnoTmp = labels(x,y);
  547. if ( forbidden_classesActiveLearning.find(classnoTmp) != forbidden_classesActiveLearning.end() )
  548. continue;
  549. Example example(NULL, x, y);
  550. example.vec = NULL;
  551. example.svec = new SparseVector ( featdim );
  552. for ( int f = 0; f < featdim; f++ )
  553. {
  554. double val = feats.getIntegralValue ( x - whs, y - whs, x + whs, y + whs, f );
  555. if ( val > 1e-10 )
  556. ( *example.svec ) [f] = val;
  557. }
  558. example.svec->normalize();
  559. examples.push_back ( pair<int, Example> ( classnoTmp, example ) );
  560. }
  561. }
  562. }
  563. if(examples.size() > 0)
  564. {
  565. std::cerr << "found " << examples.size() << " new examples in the queried region" << std::endl << std::endl;
  566. newTrainExamples.clear();
  567. newTrainExamples = examples;
  568. globalMaxUncert = maxNoveltyScore;
  569. //prepare for later visualization
  570. // if (visualizeALimages)
  571. visualizeRegion(img,mask,maxUncertRegion,maskedImg);
  572. }
  573. else
  574. {
  575. std::cerr << "the queried region has no valid information" << std::endl << std::endl;
  576. }
  577. //save filename and region index
  578. currentRegionToQuery.first = currentFile;
  579. currentRegionToQuery.second = maxUncertRegion;
  580. }
  581. }
  582. //write back best results per region
  583. //i.e., write normalized novelty scores for every region into the novelty image
  584. for ( int y = 0; y < ysize; y++)
  585. {
  586. for (int x = 0; x < xsize; x++)
  587. {
  588. int r = mask(x,y);
  589. for(int j = 0; j < probabilities.channels(); j++)
  590. {
  591. probabilities ( x, y, j ) = regionProb[r][j];
  592. }
  593. segresult(x,y) = bestClassPerRegion[r];
  594. // write novelty scores for every segment into the "final" image
  595. noveltyImage(x,y) = regionNoveltyMeasure[r];
  596. }
  597. }
  598. } // if regionSeg != null
  599. timer.stop();
  600. std::cout << "AL time for determination of novel regions: " << timer.getLastAbsolute() << std::endl;
  601. // timer.stop();
  602. // cout << "second: " << timer.getLastAbsolute() << endl;
  603. timer.start();
  604. ColorImage imgrgb ( xsize, ysize );
  605. std::stringstream out;
  606. std::vector< std::string > list2;
  607. StringTools::split ( Globals::getCurrentImgFN (), '/', list2 );
  608. out << resultdir << "/" << list2.back();
  609. noveltyImage.writeRaw(out.str() + "_run_" + NICE::intToString(this->iterationCountSuffix) + "_" + noveltyMethodString+".rawfloat");
  610. if (visualizeALimages)
  611. {
  612. ICETools::convertToRGB ( noveltyImage, imgrgb );
  613. showImage(imgrgb, "Novelty Image");
  614. }
  615. timer.stop();
  616. cout << "AL time for writing the raw novelty image: " << timer.getLastAbsolute() << endl;
  617. }
  618. inline void SemSegNovelty::computeClassificationResults( const NICE::MultiChannelImageT<double> & feats,
  619. NICE::Image & segresult,
  620. NICE::MultiChannelImageT<double> & probabilities,
  621. const int & xsize,
  622. const int & ysize,
  623. const int & featdim
  624. )
  625. {
  626. std::cerr << "featdim: " << featdim << std::endl;
  627. if ( classifier != NULL )
  628. {
  629. #pragma omp parallel for
  630. for ( int y = 0; y < ysize; y += testWSize )
  631. {
  632. Example example;
  633. example.vec = NULL;
  634. example.svec = new SparseVector ( featdim );
  635. for ( int x = 0; x < xsize; x += testWSize)
  636. {
  637. for ( int f = 0; f < featdim; f++ )
  638. {
  639. double val = feats.getIntegralValue ( x - whs, y - whs, x + whs, y + whs, f );
  640. if ( val > 1e-10 )
  641. ( *example.svec ) [f] = val;
  642. }
  643. example.svec->normalize();
  644. ClassificationResult cr = classifier->classify ( example );
  645. int xs = std::max(0, x - testWSize/2);
  646. int xe = std::min(xsize - 1, x + testWSize/2);
  647. int ys = std::max(0, y - testWSize/2);
  648. int ye = std::min(ysize - 1, y + testWSize/2);
  649. for (int yl = ys; yl <= ye; yl++)
  650. {
  651. for (int xl = xs; xl <= xe; xl++)
  652. {
  653. for ( int j = 0 ; j < cr.scores.size(); j++ )
  654. {
  655. probabilities ( xl, yl, j ) = cr.scores[j];
  656. }
  657. segresult ( xl, yl ) = cr.classno;
  658. }
  659. }
  660. example.svec->clear();
  661. }
  662. delete example.svec;
  663. example.svec = NULL;
  664. }
  665. }
  666. else //vclassifier
  667. {
  668. std::cerr << "compute classification results with vclassifier" << std::endl;
  669. #pragma omp parallel for
  670. for ( int y = 0; y < ysize; y += testWSize )
  671. {
  672. for ( int x = 0; x < xsize; x += testWSize)
  673. {
  674. NICE::Vector v(featdim);
  675. for ( int f = 0; f < featdim; f++ )
  676. {
  677. double val = feats.getIntegralValue ( x - whs, y - whs, x + whs, y + whs, f );
  678. v[f] = val;
  679. }
  680. v.normalizeL1();
  681. ClassificationResult cr = vclassifier->classify ( v );
  682. int xs = std::max(0, x - testWSize/2);
  683. int xe = std::min(xsize - 1, x + testWSize/2);
  684. int ys = std::max(0, y - testWSize/2);
  685. int ye = std::min(ysize - 1, y + testWSize/2);
  686. for (int yl = ys; yl <= ye; yl++)
  687. {
  688. for (int xl = xs; xl <= xe; xl++)
  689. {
  690. for ( int j = 0 ; j < cr.scores.size(); j++ )
  691. {
  692. probabilities ( xl, yl, j ) = cr.scores[j];
  693. }
  694. segresult ( xl, yl ) = cr.classno;
  695. }
  696. }
  697. }
  698. }
  699. }
  700. }
  701. // compute novelty images depending on the strategy chosen
  702. void SemSegNovelty::computeNoveltyByRandom( NICE::FloatImage & noveltyImage,
  703. const NICE::MultiChannelImageT<double> & feats,
  704. NICE::Image & segresult,
  705. NICE::MultiChannelImageT<double> & probabilities,
  706. const int & xsize, const int & ysize, const int & featdim )
  707. {
  708. #pragma omp parallel for
  709. for ( int y = 0; y < ysize; y += testWSize )
  710. {
  711. Example example;
  712. example.vec = NULL;
  713. example.svec = new SparseVector ( featdim );
  714. for ( int x = 0; x < xsize; x += testWSize)
  715. {
  716. for ( int f = 0; f < featdim; f++ )
  717. {
  718. double val = feats.getIntegralValue ( x - whs, y - whs, x + whs, y + whs, f );
  719. if ( val > 1e-10 )
  720. ( *example.svec ) [f] = val;
  721. }
  722. example.svec->normalize();
  723. ClassificationResult cr = classifier->classify ( example );
  724. int xs = std::max(0, x - testWSize/2);
  725. int xe = std::min(xsize - 1, x + testWSize/2);
  726. int ys = std::max(0, y - testWSize/2);
  727. int ye = std::min(ysize - 1, y + testWSize/2);
  728. double randVal = randDouble();
  729. for (int yl = ys; yl <= ye; yl++)
  730. {
  731. for (int xl = xs; xl <= xe; xl++)
  732. {
  733. for ( int j = 0 ; j < cr.scores.size(); j++ )
  734. {
  735. probabilities ( xl, yl, j ) = cr.scores[j];
  736. }
  737. segresult ( xl, yl ) = cr.classno;
  738. noveltyImage ( xl, yl ) = randVal;
  739. }
  740. }
  741. }
  742. }
  743. }
  744. void SemSegNovelty::computeNoveltyByVariance( NICE::FloatImage & noveltyImage,
  745. const NICE::MultiChannelImageT<double> & feats,
  746. NICE::Image & segresult,
  747. NICE::MultiChannelImageT<double> & probabilities,
  748. const int & xsize, const int & ysize, const int & featdim )
  749. {
  750. #pragma omp parallel for
  751. for ( int y = 0; y < ysize; y += testWSize )
  752. {
  753. Example example;
  754. example.vec = NULL;
  755. example.svec = new SparseVector ( featdim );
  756. for ( int x = 0; x < xsize; x += testWSize)
  757. {
  758. for ( int f = 0; f < featdim; f++ )
  759. {
  760. double val = feats.getIntegralValue ( x - whs, y - whs, x + whs, y + whs, f );
  761. if ( val > 1e-10 )
  762. ( *example.svec ) [f] = val;
  763. }
  764. example.svec->normalize();
  765. ClassificationResult cr = classifier->classify ( example );
  766. int xs = std::max(0, x - testWSize/2);
  767. int xe = std::min(xsize - 1, x + testWSize/2);
  768. int ys = std::max(0, y - testWSize/2);
  769. int ye = std::min(ysize - 1, y + testWSize/2);
  770. for (int yl = ys; yl <= ye; yl++)
  771. {
  772. for (int xl = xs; xl <= xe; xl++)
  773. {
  774. for ( int j = 0 ; j < cr.scores.size(); j++ )
  775. {
  776. probabilities ( xl, yl, j ) = cr.scores[j];
  777. }
  778. segresult ( xl, yl ) = cr.classno;
  779. noveltyImage ( xl, yl ) = cr.uncertainty;
  780. }
  781. }
  782. example.svec->clear();
  783. }
  784. delete example.svec;
  785. example.svec = NULL;
  786. }
  787. }
  788. void SemSegNovelty::computeNoveltyByGPUncertainty( NICE::FloatImage & noveltyImage,
  789. const NICE::MultiChannelImageT<double> & feats,
  790. NICE::Image & segresult,
  791. NICE::MultiChannelImageT<double> & probabilities,
  792. const int & xsize, const int & ysize, const int & featdim )
  793. {
  794. double gpNoise = conf->gD("GPHIK", "noise", 0.01);
  795. #pragma omp parallel for
  796. for ( int y = 0; y < ysize; y += testWSize )
  797. {
  798. Example example;
  799. example.vec = NULL;
  800. example.svec = new SparseVector ( featdim );
  801. for ( int x = 0; x < xsize; x += testWSize)
  802. {
  803. for ( int f = 0; f < featdim; f++ )
  804. {
  805. double val = feats.getIntegralValue ( x - whs, y - whs, x + whs, y + whs, f );
  806. if ( val > 1e-10 )
  807. ( *example.svec ) [f] = val;
  808. }
  809. example.svec->normalize();
  810. ClassificationResult cr = classifier->classify ( example );
  811. double maxMeanAbs ( 0.0 );
  812. for ( int j = 0 ; j < cr.scores.size(); j++ )
  813. {
  814. if ( forbidden_classesTrain.find ( j ) != forbidden_classesTrain.end() )
  815. {
  816. continue;
  817. }
  818. //check for larger abs mean
  819. if (abs(cr.scores[j]) > maxMeanAbs)
  820. {
  821. maxMeanAbs = abs(cr.scores[j]);
  822. }
  823. }
  824. double firstTerm (1.0 / sqrt(cr.uncertainty+gpNoise));
  825. //compute the heuristic GP-UNCERTAINTY, as proposed by Kapoor et al. in IJCV 2010
  826. // GP-UNCERTAINTY : |mean| / sqrt(var^2 + gpnoise^2)
  827. double gpUncertaintyVal = maxMeanAbs*firstTerm; //firstTerm = 1.0 / sqrt(r.uncertainty+gpNoise))
  828. int xs = std::max(0, x - testWSize/2);
  829. int xe = std::min(xsize - 1, x + testWSize/2);
  830. int ys = std::max(0, y - testWSize/2);
  831. int ye = std::min(ysize - 1, y + testWSize/2);
  832. for (int yl = ys; yl <= ye; yl++)
  833. {
  834. for (int xl = xs; xl <= xe; xl++)
  835. {
  836. for ( int j = 0 ; j < cr.scores.size(); j++ )
  837. {
  838. probabilities ( xl, yl, j ) = cr.scores[j];
  839. }
  840. segresult ( xl, yl ) = cr.classno;
  841. noveltyImage ( xl, yl ) = gpUncertaintyVal;
  842. }
  843. }
  844. example.svec->clear();
  845. }
  846. delete example.svec;
  847. example.svec = NULL;
  848. }
  849. }
  850. void SemSegNovelty::computeNoveltyByGPMean( NICE::FloatImage & noveltyImage,
  851. const NICE::MultiChannelImageT<double> & feats,
  852. NICE::Image & segresult,
  853. NICE::MultiChannelImageT<double> & probabilities,
  854. const int & xsize, const int & ysize, const int & featdim )
  855. {
  856. double gpNoise = conf->gD("GPHIK", "noise", 0.01);
  857. #pragma omp parallel for
  858. for ( int y = 0; y < ysize; y += testWSize )
  859. {
  860. Example example;
  861. example.vec = NULL;
  862. example.svec = new SparseVector ( featdim );
  863. for ( int x = 0; x < xsize; x += testWSize)
  864. {
  865. for ( int f = 0; f < featdim; f++ )
  866. {
  867. double val = feats.getIntegralValue ( x - whs, y - whs, x + whs, y + whs, f );
  868. if ( val > 1e-10 )
  869. ( *example.svec ) [f] = val;
  870. }
  871. example.svec->normalize();
  872. ClassificationResult cr = classifier->classify ( example );
  873. double minMeanAbs ( numeric_limits<double>::max() );
  874. for ( int j = 0 ; j < probabilities.channels(); j++ )
  875. {
  876. if ( forbidden_classesTrain.find ( j ) != forbidden_classesTrain.end() )
  877. {
  878. continue;
  879. }
  880. //check whether we found a class with higher smaller abs mean than the current minimum
  881. if (abs(probabilities(x,y,j)) < minMeanAbs)
  882. {
  883. minMeanAbs = abs(cr.scores[j]);
  884. }
  885. }
  886. // compute results when we take the lowest mean value of all classes
  887. double gpMeanVal = minMeanAbs;
  888. int xs = std::max(0, x - testWSize/2);
  889. int xe = std::min(xsize - 1, x + testWSize/2);
  890. int ys = std::max(0, y - testWSize/2);
  891. int ye = std::min(ysize - 1, y + testWSize/2);
  892. for (int yl = ys; yl <= ye; yl++)
  893. {
  894. for (int xl = xs; xl <= xe; xl++)
  895. {
  896. for ( int j = 0 ; j < cr.scores.size(); j++ )
  897. {
  898. probabilities ( xl, yl, j ) = cr.scores[j];
  899. }
  900. segresult ( xl, yl ) = cr.classno;
  901. noveltyImage ( xl, yl ) = gpMeanVal;
  902. }
  903. }
  904. }
  905. }
  906. }
  907. void SemSegNovelty::computeNoveltyByGPMeanRatio( NICE::FloatImage & noveltyImage,
  908. const NICE::MultiChannelImageT<double> & feats,
  909. NICE::Image & segresult,
  910. NICE::MultiChannelImageT<double> & probabilities,
  911. const int & xsize, const int & ysize, const int & featdim )
  912. {
  913. double gpNoise = conf->gD("GPHIK", "noise", 0.01);
  914. #pragma omp parallel for
  915. for ( int y = 0; y < ysize; y += testWSize )
  916. {
  917. Example example;
  918. example.vec = NULL;
  919. example.svec = new SparseVector ( featdim );
  920. for ( int x = 0; x < xsize; x += testWSize)
  921. {
  922. for ( int f = 0; f < featdim; f++ )
  923. {
  924. double val = feats.getIntegralValue ( x - whs, y - whs, x + whs, y + whs, f );
  925. if ( val > 1e-10 )
  926. ( *example.svec ) [f] = val;
  927. }
  928. example.svec->normalize();
  929. ClassificationResult cr = classifier->classify ( example );
  930. double maxMean ( -numeric_limits<double>::max() );
  931. double sndMaxMean ( -numeric_limits<double>::max() );
  932. for ( int j = 0 ; j < cr.scores.size(); j++ )
  933. {
  934. if ( forbidden_classesTrain.find ( j ) != forbidden_classesTrain.end() )
  935. {
  936. continue;
  937. }
  938. //check for larger mean without abs as well
  939. if (cr.scores[j] > maxMean)
  940. {
  941. sndMaxMean = maxMean;
  942. maxMean = cr.scores[j];
  943. }
  944. // and also for the second highest mean of all classes
  945. else if (cr.scores[j] > sndMaxMean)
  946. {
  947. sndMaxMean = cr.scores[j];
  948. }
  949. }
  950. //look at the difference in the absolut mean values for the most plausible class
  951. // and the second most plausible class
  952. double gpMeanRatioVal= maxMean - sndMaxMean;
  953. int xs = std::max(0, x - testWSize/2);
  954. int xe = std::min(xsize - 1, x + testWSize/2);
  955. int ys = std::max(0, y - testWSize/2);
  956. int ye = std::min(ysize - 1, y + testWSize/2);
  957. for (int yl = ys; yl <= ye; yl++)
  958. {
  959. for (int xl = xs; xl <= xe; xl++)
  960. {
  961. for ( int j = 0 ; j < cr.scores.size(); j++ )
  962. {
  963. probabilities ( xl, yl, j ) = cr.scores[j];
  964. }
  965. segresult ( xl, yl ) = cr.classno;
  966. noveltyImage ( xl, yl ) = gpMeanRatioVal;
  967. }
  968. }
  969. example.svec->clear();
  970. }
  971. delete example.svec;
  972. example.svec = NULL;
  973. }
  974. }
  975. void SemSegNovelty::computeNoveltyByGPWeightAll( NICE::FloatImage & noveltyImage,
  976. const NICE::MultiChannelImageT<double> & feats,
  977. NICE::Image & segresult,
  978. NICE::MultiChannelImageT<double> & probabilities,
  979. const int & xsize, const int & ysize, const int & featdim )
  980. {
  981. double gpNoise = conf->gD("GPHIK", "noise", 0.01);
  982. #pragma omp parallel for
  983. for ( int y = 0; y < ysize; y += testWSize )
  984. {
  985. Example example;
  986. example.vec = NULL;
  987. example.svec = new SparseVector ( featdim );
  988. for ( int x = 0; x < xsize; x += testWSize)
  989. {
  990. for ( int f = 0; f < featdim; f++ )
  991. {
  992. double val = feats.getIntegralValue ( x - whs, y - whs, x + whs, y + whs, f );
  993. if ( val > 1e-10 )
  994. ( *example.svec ) [f] = val;
  995. }
  996. example.svec->normalize();
  997. ClassificationResult cr = classifier->classify ( example );
  998. double firstTerm (1.0 / sqrt(cr.uncertainty+gpNoise));
  999. double gpWeightAllVal ( 0.0 );
  1000. if ( numberOfClasses > 2)
  1001. {
  1002. //compute the weight in the alpha-vector for every sample after assuming it to be
  1003. // added to the training set.
  1004. // Thereby, we measure its "importance" for the current model
  1005. //
  1006. //double firstTerm is already computed
  1007. //
  1008. //the second term is only needed when computing impacts
  1009. //double secondTerm; //this is the nasty guy :/
  1010. //--- compute the third term
  1011. // this is the difference between predicted label and GT label
  1012. std::vector<double> diffToPositive; diffToPositive.clear();
  1013. std::vector<double> diffToNegative; diffToNegative.clear();
  1014. double diffToNegativeSum(0.0);
  1015. for ( int j = 0 ; j < cr.scores.size(); j++ )
  1016. {
  1017. if ( forbidden_classesTrain.find ( j ) != forbidden_classesTrain.end() )
  1018. {
  1019. continue;
  1020. }
  1021. // look at the difference to plus 1
  1022. diffToPositive.push_back(abs(cr.scores[j] - 1));
  1023. // look at the difference to -1
  1024. diffToNegative.push_back(abs(cr.scores[j] + 1));
  1025. //sum up the difference to -1
  1026. diffToNegativeSum += abs(cr.scores[j] - 1);
  1027. }
  1028. //let's subtract for every class its diffToNegative from the sum, add its diffToPositive,
  1029. //and use this as the third term for this specific class.
  1030. //the final value is obtained by minimizing over all classes
  1031. //
  1032. // originally, we minimize over all classes after building the final score
  1033. // however, the first and the second term do not depend on the choice of
  1034. // y*, therefore we minimize here already
  1035. double thirdTerm (numeric_limits<double>::max()) ;
  1036. for(uint tmpCnt = 0; tmpCnt < diffToPositive.size(); tmpCnt++)
  1037. {
  1038. double tmpVal ( diffToPositive[tmpCnt] + (diffToNegativeSum-diffToNegative[tmpCnt]) );
  1039. if (tmpVal < thirdTerm)
  1040. thirdTerm = tmpVal;
  1041. }
  1042. gpWeightAllVal = thirdTerm*firstTerm;
  1043. }
  1044. else //binary scenario
  1045. {
  1046. gpWeightAllVal = std::min( abs(cr.scores[*classesInUse.begin()]+1), abs(cr.scores[*classesInUse.begin()]-1) );
  1047. gpWeightAllVal *= firstTerm;
  1048. }
  1049. int xs = std::max(0, x - testWSize/2);
  1050. int xe = std::min(xsize - 1, x + testWSize/2);
  1051. int ys = std::max(0, y - testWSize/2);
  1052. int ye = std::min(ysize - 1, y + testWSize/2);
  1053. for (int yl = ys; yl <= ye; yl++)
  1054. {
  1055. for (int xl = xs; xl <= xe; xl++)
  1056. {
  1057. for ( int j = 0 ; j < cr.scores.size(); j++ )
  1058. {
  1059. probabilities ( xl, yl, j ) = cr.scores[j];
  1060. }
  1061. segresult ( xl, yl ) = cr.classno;
  1062. noveltyImage ( xl, yl ) = gpWeightAllVal;
  1063. }
  1064. }
  1065. example.svec->clear();
  1066. }
  1067. delete example.svec;
  1068. example.svec = NULL;
  1069. }
  1070. }
  1071. void SemSegNovelty::computeNoveltyByGPWeightRatio( NICE::FloatImage & noveltyImage,
  1072. const NICE::MultiChannelImageT<double> & feats,
  1073. NICE::Image & segresult,
  1074. NICE::MultiChannelImageT<double> & probabilities,
  1075. const int & xsize, const int & ysize, const int & featdim )
  1076. {
  1077. double gpNoise = conf->gD("GPHIK", "noise", 0.01);
  1078. #pragma omp parallel for
  1079. for ( int y = 0; y < ysize; y += testWSize )
  1080. {
  1081. Example example;
  1082. example.vec = NULL;
  1083. example.svec = new SparseVector ( featdim );
  1084. for ( int x = 0; x < xsize; x += testWSize)
  1085. {
  1086. for ( int f = 0; f < featdim; f++ )
  1087. {
  1088. double val = feats.getIntegralValue ( x - whs, y - whs, x + whs, y + whs, f );
  1089. if ( val > 1e-10 )
  1090. ( *example.svec ) [f] = val;
  1091. }
  1092. example.svec->normalize();
  1093. ClassificationResult cr = classifier->classify ( example );
  1094. double firstTerm (1.0 / sqrt(cr.uncertainty+gpNoise));
  1095. double gpWeightRatioVal ( 0.0 );
  1096. if ( numberOfClasses > 2)
  1097. {
  1098. //compute the weight in the alpha-vector for every sample after assuming it to be
  1099. // added to the training set.
  1100. // Thereby, we measure its "importance" for the current model
  1101. //
  1102. //double firstTerm is already computed
  1103. //
  1104. //the second term is only needed when computing impacts
  1105. //double secondTerm; //this is the nasty guy :/
  1106. //--- compute the third term
  1107. // this is the difference between predicted label and GT label
  1108. std::vector<double> diffToPositive; diffToPositive.clear();
  1109. std::vector<double> diffToNegative; diffToNegative.clear();
  1110. double diffToNegativeSum(0.0);
  1111. for ( int j = 0 ; j < cr.scores.size(); j++ )
  1112. {
  1113. if ( forbidden_classesTrain.find ( j ) != forbidden_classesTrain.end() )
  1114. {
  1115. continue;
  1116. }
  1117. // look at the difference to plus 1
  1118. diffToPositive.push_back(abs(cr.scores[j] - 1));
  1119. }
  1120. //let's subtract for every class its diffToNegative from the sum, add its diffToPositive,
  1121. //and use this as the third term for this specific class.
  1122. //the final value is obtained by minimizing over all classes
  1123. //
  1124. // originally, we minimize over all classes after building the final score
  1125. // however, the first and the second term do not depend on the choice of
  1126. // y*, therefore we minimize here already
  1127. //now look on the ratio of the resulting weights for the most plausible
  1128. // against the second most plausible class
  1129. double thirdTermMostPlausible ( 0.0 ) ;
  1130. double thirdTermSecondMostPlausible ( 0.0 ) ;
  1131. for(uint tmpCnt = 0; tmpCnt < diffToPositive.size(); tmpCnt++)
  1132. {
  1133. if (diffToPositive[tmpCnt] > thirdTermMostPlausible)
  1134. {
  1135. thirdTermSecondMostPlausible = thirdTermMostPlausible;
  1136. thirdTermMostPlausible = diffToPositive[tmpCnt];
  1137. }
  1138. else if (diffToPositive[tmpCnt] > thirdTermSecondMostPlausible)
  1139. {
  1140. thirdTermSecondMostPlausible = diffToPositive[tmpCnt];
  1141. }
  1142. }
  1143. //compute the resulting score
  1144. gpWeightRatioVal = (thirdTermMostPlausible - thirdTermSecondMostPlausible)*firstTerm;
  1145. //finally, look for this feature how it would affect to whole model (summarized by weight-vector alpha), if we would
  1146. //use it as an additional training example
  1147. //TODO this would be REALLY computational demanding. Do we really want to do this?
  1148. // gpImpactAll[s] ( pce[i].second.x, pce[i].second.y ) = thirdTerm*firstTerm*secondTerm;
  1149. // gpImpactRatio[s] ( pce[i].second.x, pce[i].second.y ) = (thirdTermMostPlausible - thirdTermSecondMostPlausible)*firstTerm*secondTerm;
  1150. }
  1151. else //binary scenario
  1152. {
  1153. gpWeightRatioVal = std::min( abs(cr.scores[*classesInUse.begin()]+1), abs(cr.scores[*classesInUse.begin()]-1) );
  1154. gpWeightRatioVal *= firstTerm;
  1155. }
  1156. int xs = std::max(0, x - testWSize/2);
  1157. int xe = std::min(xsize - 1, x + testWSize/2);
  1158. int ys = std::max(0, y - testWSize/2);
  1159. int ye = std::min(ysize - 1, y + testWSize/2);
  1160. for (int yl = ys; yl <= ye; yl++)
  1161. {
  1162. for (int xl = xs; xl <= xe; xl++)
  1163. {
  1164. for ( int j = 0 ; j < cr.scores.size(); j++ )
  1165. {
  1166. probabilities ( xl, yl, j ) = cr.scores[j];
  1167. }
  1168. segresult ( xl, yl ) = cr.classno;
  1169. noveltyImage ( xl, yl ) = gpWeightRatioVal;
  1170. }
  1171. }
  1172. example.svec->clear();
  1173. }
  1174. delete example.svec;
  1175. example.svec = NULL;
  1176. }
  1177. }
  1178. void SemSegNovelty::addNewExample(const NICE::Vector& newExample, const int & newClassNo)
  1179. {
  1180. //accept the new class as valid information
  1181. if ( forbidden_classesTrain.find ( newClassNo ) != forbidden_classesTrain.end() )
  1182. {
  1183. forbidden_classesTrain.erase(newClassNo);
  1184. numberOfClasses++;
  1185. }
  1186. if ( classesInUse.find ( newClassNo ) == classesInUse.end() )
  1187. {
  1188. classesInUse.insert( newClassNo );
  1189. }
  1190. //then add it to the classifier used
  1191. if ( classifier != NULL )
  1192. {
  1193. //TODO
  1194. }
  1195. else //vclassifier
  1196. {
  1197. if (this->classifierString.compare("nn") == 0)
  1198. {
  1199. vclassifier->teach ( newClassNo, newExample );
  1200. }
  1201. }
  1202. }
  1203. void SemSegNovelty::addNovelExamples()
  1204. {
  1205. Timer timer;
  1206. //show the image that contains the most novel region
  1207. if (visualizeALimages)
  1208. showImage(maskedImg, "Most novel region");
  1209. timer.start();
  1210. std::stringstream out;
  1211. std::vector< std::string > list2;
  1212. StringTools::split ( Globals::getCurrentImgFN (), '/', list2 );
  1213. out << resultdir << "/" << list2.back();
  1214. maskedImg.writePPM ( out.str() + "_run_" + NICE::intToString(this->iterationCountSuffix) + "_" + noveltyMethodString+ "_query.ppm" );
  1215. timer.stop();
  1216. std::cerr << "AL time for writing queried image: " << timer.getLast() << std::endl;
  1217. timer.start();
  1218. //check which classes will be added using the features from the novel region
  1219. std::set<int> newClassNumbers;
  1220. newClassNumbers.clear(); //just to be sure
  1221. for ( uint i = 0 ; i < newTrainExamples.size() ; i++ )
  1222. {
  1223. if (newClassNumbers.find(newTrainExamples[i].first /* classNumber*/) == newClassNumbers.end() )
  1224. {
  1225. newClassNumbers.insert(newTrainExamples[i].first );
  1226. }
  1227. }
  1228. //accept the new classes as valid information
  1229. for (std::set<int>::const_iterator clNoIt = newClassNumbers.begin(); clNoIt != newClassNumbers.end(); clNoIt++)
  1230. {
  1231. if ( forbidden_classesTrain.find ( *clNoIt ) != forbidden_classesTrain.end() )
  1232. {
  1233. forbidden_classesTrain.erase(*clNoIt);
  1234. numberOfClasses++;
  1235. }
  1236. if ( classesInUse.find ( *clNoIt ) == classesInUse.end() )
  1237. {
  1238. classesInUse.insert( *clNoIt );
  1239. }
  1240. }
  1241. timer.stop();
  1242. std::cerr << "AL time for accepting possible new classes: " << timer.getLast() << std::endl;
  1243. timer.start();
  1244. //then add the new features to the classifier used
  1245. if ( classifier != NULL )
  1246. {
  1247. if (this->classifierString.compare("ClassifierGPHIK") == 0)
  1248. {
  1249. classifier->addMultipleExamples ( this->newTrainExamples );
  1250. }
  1251. }
  1252. else //vclassifier
  1253. {
  1254. //TODO
  1255. }
  1256. timer.stop();
  1257. std::cerr << "AL time for actually updating the classifier: " << timer.getLast() << std::endl;
  1258. std::cerr << "the current region to query is: " << currentRegionToQuery.first << " -- " << currentRegionToQuery.second << std::endl;
  1259. //did we already query a region of this image?
  1260. if ( queriedRegions.find( currentRegionToQuery.first ) != queriedRegions.end() )
  1261. {
  1262. queriedRegions[ currentRegionToQuery.first ].insert(currentRegionToQuery.second);
  1263. }
  1264. else
  1265. {
  1266. std::set<int> tmpSet; tmpSet.insert(currentRegionToQuery.second);
  1267. queriedRegions.insert(std::pair<std::string,std::set<int> > (currentRegionToQuery.first, tmpSet ) );
  1268. }
  1269. std::cerr << "Write already queried regions: " << std::endl;
  1270. for (std::map<std::string,std::set<int> >::const_iterator it = queriedRegions.begin(); it != queriedRegions.end(); it++)
  1271. {
  1272. std::cerr << "image: " << it->first << " -- ";
  1273. for (std::set<int>::const_iterator itReg = it->second.begin(); itReg != it->second.end(); itReg++)
  1274. {
  1275. std::cerr << *itReg << " ";
  1276. }
  1277. std::cerr << std::endl;
  1278. }
  1279. //clear the latest results, since one iteration is over
  1280. globalMaxUncert = -numeric_limits<double>::max();
  1281. if (!mostNoveltyWithMaxScores)
  1282. globalMaxUncert = numeric_limits<double>::max();
  1283. }
  1284. const Examples * SemSegNovelty::getNovelExamples() const
  1285. {
  1286. return &(this->newTrainExamples);
  1287. }