Browse Source

flexiblere version

Bjoern Froehlich 13 years ago
parent
commit
a737c0e0bb
3 changed files with 175 additions and 125 deletions
  1. 1 2
      progs/testSemanticSegmentation.cpp
  2. 148 73
      semseg/SemSegContextTree.cpp
  3. 26 50
      semseg/SemSegContextTree.h

+ 1 - 2
progs/testSemanticSegmentation.cpp

@@ -115,8 +115,6 @@ int main(int argc, char **argv)
 	LOOP_ALL_S(*testFiles)
 	{
 		EACH_INFO(classno, info);
-		pb.update(testFiles->count());
-
 		std::string file = info.img();
 
 		NICE::Image lm;
@@ -211,6 +209,7 @@ int main(int argc, char **argv)
 
 		cerr << M << endl;
 		fileno++;
+		pb.update(testFiles->count());
 	}
 
 	pb.hide();

+ 148 - 73
semseg/SemSegContextTree.cpp

@@ -19,6 +19,77 @@ using namespace OBJREC;
 using namespace std;
 using namespace NICE;
 
+class Minus:public Operation
+{
+public:
+	virtual double getVal(const vector<vector<vector<double> > > &feats, const int &x, const int &y)
+	{
+		int xsize = feats.size();
+		int ysize = feats[0].size();
+		double v1 = feats[BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)][channel1];
+		double v2 = feats[BOUND(x+x2,0,xsize-1)][BOUND(y+y2,0,ysize-1)][channel2];
+		return v1-v2;
+	}
+	
+	virtual Operation* clone()
+	{
+		return new Minus();
+	};
+};
+
+class MinusAbs:public Operation
+{
+public:
+	virtual double getVal(const vector<vector<vector<double> > > &feats, const int &x, const int &y)
+	{
+		int xsize = feats.size();
+		int ysize = feats[0].size();
+		double v1 = feats[BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)][channel1];
+		double v2 = feats[BOUND(x+x2,0,xsize-1)][BOUND(y+y2,0,ysize-1)][channel2];
+		return abs(v1-v2);
+	}
+	
+	virtual Operation* clone()
+	{
+		return new MinusAbs();
+	};
+};
+
+class Addition:public Operation
+{
+public:
+	virtual double getVal(const vector<vector<vector<double> > > &feats, const int &x, const int &y)
+	{
+		int xsize = feats.size();
+		int ysize = feats[0].size();
+		double v1 = feats[BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)][channel1];
+		double v2 = feats[BOUND(x+x2,0,xsize-1)][BOUND(y+y2,0,ysize-1)][channel2];
+		return v1+v2;
+	}
+	
+	virtual Operation* clone()
+	{
+		return new Addition();
+	};
+};
+
+class Only1:public Operation
+{
+public:
+	virtual double getVal(const vector<vector<vector<double> > > &feats, const int &x, const int &y)
+	{
+		int xsize = feats.size();
+		int ysize = feats[0].size();
+		double v1 = feats[BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)][channel1];
+		return v1;
+	}
+	
+	virtual Operation* clone()
+	{
+		return new Only1();
+	};
+};
+      
 
 SemSegContextTree::SemSegContextTree( const Config *conf, const MultiDataset *md )
     : SemanticSegmentation ( conf, &(md->getClassNames("train")) )
@@ -38,9 +109,12 @@ SemSegContextTree::SemSegContextTree( const Config *conf, const MultiDataset *md
 	
 	featsPerSplit = conf->gI(section, "feats_per_split", 200);
 	
+	useShannonEntropy = conf->gB(section, "use_shannon_entropy", true);
+	
 	ops.push_back(new Minus());
 	ops.push_back(new MinusAbs());
 	ops.push_back(new Addition());
+	ops.push_back(new Only1());
 	
 	///////////////////////////////////
 	// Train Segmentation Context Trees
@@ -53,13 +127,13 @@ SemSegContextTree::~SemSegContextTree()
 {
 }
 
-void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> > > > &feats, vector<vector<vector<int> > > &currentfeats,const vector<vector<vector<int> > > &labels, int node, int &splitfeat, double &splitval)
+void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> > > > &feats, vector<vector<vector<int> > > &currentfeats,const vector<vector<vector<int> > > &labels, int node, Operation *&splitop, double &splitval)
 {
-	int imgCount, featsize;
+	int imgCount, featdim;
 	try
 	{
 		imgCount = (int)feats.size();
-		featsize = feats[0][0][0].size();
+		featdim = feats[0][0][0].size();
 	}
 	catch(Exception)
 	{
@@ -67,7 +141,7 @@ void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> >
 	}
 	
 	double bestig = -numeric_limits< double >::max();
-	splitfeat = -1;
+	splitop = NULL;
 	splitval = -1.0;
 	
 	set<vector<int> >selFeats;
@@ -93,9 +167,11 @@ void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> >
 	vector<double> fraction(a.size(),0.0);
 	for(uint i = 0; i < fraction.size(); i++)
 	{
-		fraction[i] = ((double)maxSamples)/(a[i]*(double)featcounter*8);
-		//cout << "fraction["<<i<<"]: "<< fraction[i] << endl;
+		fraction[i] = ((double)maxSamples)/((double)featcounter*a[i]*a.size());
+		//cout << "fraction["<<i<<"]: "<< fraction[i] << " a[" << i << "]: " << a[i] << endl;
 	}
+	//cout << "a.size(): " << a.size() << endl;
+	//getchar();
 	featcounter = 0;
 	
 	
@@ -128,7 +204,8 @@ void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> >
 		}
 	}
 	
-	//cout << "size: " << selFeats.size() << endl;
+	cout << "size: " << selFeats.size() << endl;
+	//getchar();
 	
 	map<int,int>::iterator mapit;
 	double globent = 0.0;
@@ -152,25 +229,27 @@ void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> >
 		return;
 	}
 	
-	
-	vector<int> featsubset;
+	featsel.clear();
 	for(int i = 0; i < featsPerSplit; i++)
 	{
-		int randI = ((double)rand()/(double)RAND_MAX*(double)allfeatsize);
-		featsubset.push_back(randI);
+		int x1 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
+		int x2 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
+		int y1 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
+		int y2 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
+		int f1 = (int)((double)rand()/(double)RAND_MAX*(double)featdim);
+		int f2 = (int)((double)rand()/(double)RAND_MAX*(double)featdim);
+		int o = (int)((double)rand()/(double)RAND_MAX*(double)ops.size());
+		
+		Operation *op = ops[o]->clone();
+		op->set(x1,y1,x2,y2,f1,f2);
+		featsel.push_back(op);
 	}
 	
+	
+
 #pragma omp parallel for private(mapit)
 	for(int f = 0; f < featsPerSplit; f++)
 	{
-
-		int x1 = featsel[featsubset[f]][0];
-		int y1 = featsel[featsubset[f]][1];
-		int x2 = featsel[featsubset[f]][2];
-		int y2 = featsel[featsubset[f]][3];
-		int chan = featsel[featsubset[f]][4];
-		int o = featsel[featsubset[f]][5];
-
 		double l_bestig = -numeric_limits< double >::max();
 		double l_splitval = -1.0;
 		set<vector<int> >::iterator it;
@@ -178,11 +257,7 @@ void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> >
 
 		for ( it=selFeats.begin() ; it != selFeats.end(); it++ )
 		{
-			int xsize = (int)feats[(*it)[0]].size();
-			int ysize = (int)feats[(*it)[0]][0].size();
-			double val1 = feats[(*it)[0]][BOUND((*it)[1]+x1,0,xsize-1)][BOUND((*it)[2]+y1,0,ysize-1)][chan];
-			double val2 = feats[(*it)[0]][BOUND((*it)[1]+x2,0,xsize-1)][BOUND((*it)[2]+y2,0,ysize-1)][chan];
-			vals.push_back(ops[o]->getVal(val1,val2));
+			vals.push_back(featsel[f]->getVal(feats[(*it)[0]],(*it)[1], (*it)[2]));
 		}
 		
 		int counter = 0;
@@ -217,19 +292,26 @@ void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> >
 			for ( mapit=eL.begin() ; mapit != eL.end(); mapit++ )
 			{
 				double p = (double)(*mapit).second/(double)counterL;
-				leftent += p*log2(p);
+				leftent -= p*log2(p);
 			}
-			leftent = -leftent;
+
 			
 			double rightent = 0.0;
 			for ( mapit=eR.begin() ; mapit != eR.end(); mapit++ )
 			{
 				double p = (double)(*mapit).second/(double)counterR;
-				rightent += p*log2(p);
+				rightent -= p*log2(p);
 			}
-			rightent = -rightent;
 			//cout << "rightent: " << rightent << " leftent: " << leftent << endl;
-			double ig = globent - rightent - leftent;
+			
+			double pl = counterL/(counterL+counterR);
+			double ig = globent - (1.0-pl) * rightent - pl*leftent;
+			
+			if(useShannonEntropy)
+			{
+				double esplit = - ( pl*log(pl) + (1-pl)*log(1-pl) );
+				ig = 2*ig / ( globent + esplit );
+			}
 			
 			if(ig > l_bestig)
 			{
@@ -246,12 +328,18 @@ void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> >
 		if(l_bestig > bestig)
 		{
 			bestig = l_bestig;
-			splitfeat = featsubset[f];
+			splitop = featsel[f];
 			splitval = l_splitval;
 		}
 }
 	}
-	cout << "globent: " << globent <<  " bestig " << bestig << " splitfeat: " << splitfeat << " splitval: " << splitval << endl;
+	
+	/*for(int i = 0; i < featsPerSplit; i++)
+	{
+		if(featsel[i] != splitop)
+			delete featsel[i];
+	}*/
+	cout << "globent: " << globent <<  " bestig " << bestig << " splitval: " << splitval << endl;
 }
 
 void SemSegContextTree::train ( const MultiDataset *md )
@@ -346,10 +434,10 @@ void SemSegContextTree::train ( const MultiDataset *md )
 	}
 	pb.hide();
 	
-	int opsize = (int)ops.size();
+	/*int opsize = (int)ops.size();
 	int featdim = (int)allfeats[0][0][0].size();
-	allfeatsize = windowSize*windowSize*windowSize*windowSize*featdim*opsize;
 	
+
 	for(int x1 = -windowSize/2; x1 < windowSize/2+1; x1++)
 	{
 		for(int y1 = -windowSize/2; y1 < windowSize/2+1; y1++)
@@ -375,7 +463,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
 				}
 			}
 		}
-	}
+	}*/
 	
 	map<int,int>::iterator mapit;
 	int classes = 0;
@@ -419,35 +507,23 @@ void SemSegContextTree::train ( const MultiDataset *md )
 	while(!allleaf && depth < maxDepth)
 	{
 		allleaf = true;
-		//TODO vielleicht parallel wenn nächste schleife auch noch parallelsiert würde, die hat mehr gewicht
-		//#pragma omp parallel for
+		//TODO vielleicht parallel wenn nächste schleife trotzdem noch parallelsiert würde, die hat mehr gewicht
+
 		int t = (int) tree.size();
+//#pragma omp parallel for
 		for(int i = 0; i < t; i++)
 		{
-			printf("tree[%i]: left: %i, right: %i ", i, tree[i].left, tree[i].right);
-			for(int d = 0; d < (int)tree[i].dist.size(); d++)
-			{
-				cout << " " << tree[i].dist[d];
-			}
-			cout << endl;
 			if(!tree[i].isleaf && tree[i].left < 0)
 			{  
-				int splitfeat;
+				Operation *splitfeat = NULL;
 				double splitval;
 
 				getBestSplit(allfeats, currentfeats,labels, i, splitfeat, splitval);
 				tree[i].feat = splitfeat;
 				tree[i].decision = splitval;
-				cout << "splitfeat: " << splitfeat << " splitval: " << splitval << endl;
-				if(splitfeat >= 0)
+				
+				if(splitfeat != NULL)
 				{
-					int x1 = featsel[splitfeat][0];
-					int y1 = featsel[splitfeat][1];
-					int x2 = featsel[splitfeat][2];
-					int y2 = featsel[splitfeat][3];
-					int p = featsel[splitfeat][4];
-					int o = featsel[splitfeat][5];
-
 					allleaf = false;
 					int left = tree.size();
 					tree.push_back(Node());
@@ -459,7 +535,6 @@ void SemSegContextTree::train ( const MultiDataset *md )
 					tree[right].dist = vector<double>(classes, 0.0);
 					tree[left].depth = depth+1;
 					tree[right].depth = depth+1;
-					
 #pragma omp parallel for
 					for(int iCounter = 0; iCounter < imgcounter; iCounter++)
 					{
@@ -471,11 +546,8 @@ void SemSegContextTree::train ( const MultiDataset *md )
 							{
 								if(currentfeats[iCounter][x][y] == i)
 								{
-									int xsize = (int)allfeats[iCounter].size();
-									int ysize = (int)allfeats[iCounter][0].size();
-									double val1 = allfeats[iCounter][BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)][p];
-									double val2 = allfeats[iCounter][BOUND(x+x2,0,xsize-1)][BOUND(y+y2,0,ysize-1)][p];
-									double val = ops[o]->getVal(val1,val2);
+									double val = splitfeat->getVal(allfeats[iCounter],x,y);
+
 									if(val < splitval)
 									{ 
 										currentfeats[iCounter][x][y] = left;
@@ -490,12 +562,13 @@ void SemSegContextTree::train ( const MultiDataset *md )
 							}
 						}
 					}
+
 					double lcounter = 0.0, rcounter = 0.0;
 					for(uint d = 0; d < tree[left].dist.size(); d++)
 					{
-						tree[left].dist[d]/=a[d];
+						//tree[left].dist[d]/=a[d];
 						lcounter +=tree[left].dist[d];
-						tree[right].dist[d]/=a[d];
+						//tree[right].dist[d]/=a[d];
 						rcounter +=tree[right].dist[d];
 					}
 					assert(lcounter > 0 && rcounter > 0);
@@ -509,7 +582,6 @@ void SemSegContextTree::train ( const MultiDataset *md )
 				{
 					tree[i].isleaf = true;
 				}
-				//TODO: probability ermitteln
 			}
 		}
 		
@@ -517,6 +589,19 @@ void SemSegContextTree::train ( const MultiDataset *md )
 		depth++;
 		cout << "d: " << depth << endl;
 	}
+	
+	
+	
+	int t = (int) tree.size();
+	for(int i = 0; i < t; i++)
+	{
+		printf("tree[%i]: left: %i, right: %i ", i, tree[i].left, tree[i].right);
+		for(int d = 0; d < (int)tree[i].dist.size(); d++)
+		{
+			cout << " " << tree[i].dist[d];
+		}
+		cout << endl;
+	}
 
 }
 
@@ -584,17 +669,7 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
 					if(tree[t].left > 0)
 					{
 						allleaf = false;
-						int splitfeat = tree[t].feat;
-						int x1 = featsel[splitfeat][0];
-						int y1 = featsel[splitfeat][1];
-						int x2 = featsel[splitfeat][2];
-						int y2 = featsel[splitfeat][3];
-						int p = featsel[splitfeat][4];
-						int o = featsel[splitfeat][5];
-
-						double val1 = feats[BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)][p];
-						double val2 = feats[BOUND(x+x2,0,xsize-1)][BOUND(y+y2,0,ysize-1)][p];
-						double val = ops[o]->getVal(val1,val2);
+						double val = tree[t].feat->getVal(feats,x,y);
 						
 						if(val < tree[t].decision)
 						{
@@ -615,7 +690,7 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
 	}
 	
 	//finales labeln:
-	 long int offset = 0;
+	long int offset = 0;
 	for(int x = 0; x < xsize; x++)
 	{
 		for(int y = 0; y < ysize; y++,offset++)

+ 26 - 50
semseg/SemSegContextTree.h

@@ -14,6 +14,24 @@
 
 namespace OBJREC {
 
+class Operation
+{
+protected:
+	int x1, y1, x2, y2, channel1, channel2;
+public:
+	void set(int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2)
+	{
+		x1 = _x1;
+		y1 = _y1;
+		x2 = _x2;
+		y2 = _y2;
+		channel1 = _channel1;
+		channel2 = _channel2;
+	}
+	virtual double getVal(const vector<vector<vector<double> > > &feats, const int &x, const int &y) = 0;
+	virtual Operation* clone() = 0;
+};
+  
 /** Localization system */
 class SemSegContextTree : public SemanticSegmentation
 {
@@ -32,7 +50,7 @@ class SemSegContextTree : public SemanticSegmentation
 		int right;
 		
 		/** position of feat for decision */
-		int feat;
+		Operation *feat;
 		
 		/** decision stamp */
 		double decision;
@@ -47,54 +65,12 @@ class SemSegContextTree : public SemanticSegmentation
 		int depth;
 		
 		/** simple constructor */
-		Node():left(-1),right(-1),feat(-1), decision(-1.0), isleaf(false){}
+		Node():left(-1),right(-1),feat(NULL), decision(-1.0), isleaf(false){}
 		
 		/** standard constructor */
-		Node(int _left, int _right, int _feat, double _decision):left(_left),right(_right),feat(_feat), decision(_decision),isleaf(false){}
+		Node(int _left, int _right, Operation *_feat, double _decision):left(_left),right(_right),feat(_feat), decision(_decision),isleaf(false){}
 	};
 	
-	class Operation
-	{
-	public:
-		virtual double getVal(const double &v1, const double &v2) = 0;
-	};
-
-	class Minus:public Operation
-	{
-	public:
-		virtual double getVal(const double &v1, const double &v2)
-		{
-			return v1-v2;
-		}
-	};
-
-	class MinusAbs:public Operation
-	{
-	public:
-		virtual double getVal(const double &v1, const double &v2)
-		{
-			return abs(v1-v2);
-		}
-	};
-
-	class Addition:public Operation
-	{
-	public:
-		virtual double getVal(const double &v1, const double &v2)
-		{
-			return v1+v2;
-		}
-	};
-	
-	class Only1:public Operation
-	{
-	public:
-		virtual double getVal(const double &v1, const double &v2)
-		{
-			return v1;
-		}
-	};
-      
 	/** store features */
 	VVector currentfeats;
 	
@@ -140,11 +116,11 @@ class SemSegContextTree : public SemanticSegmentation
 	/** operations for pairwise features */
 	vector<Operation*> ops;
 	
-	/** number of possible features */
-	int allfeatsize;
-	
 	/** vector of all possible features */
-	vector<vector<int> > featsel;
+	vector<Operation*> featsel;
+	
+	/** use alternative calculation for information gain */
+	bool useShannonEntropy;
 	
     public:
 	/** simple constructor */
@@ -176,7 +152,7 @@ class SemSegContextTree : public SemanticSegmentation
 	 * @param splitfeat output feature position
 	 * @param splitval 
 	 */
-	void getBestSplit(const vector<vector<vector<vector<double> > > > &feats, vector<vector<vector<int> > > &currentfeats,const vector<vector<vector<int> > > &labels, int node, int &splitfeat, double &splitval);
+	void getBestSplit(const vector<vector<vector<vector<double> > > > &feats, vector<vector<vector<int> > > &currentfeats,const vector<vector<vector<int> > > &labels, int node, Operation *&splitfeat, double &splitval);
 
 };