def Classifier(self, 
                   database,
                   version,
                   num_of_kpts,
                   cutoff,
                   top = 5,
                   K = 10,
                   depth=4):
        
        num_in_set = database[0]
        num_of_sets = database[1]
        test_database = database[3]  
        
        total = num_in_set * num_of_sets
        num_in_test_set = len(test_database) / num_of_sets 
        
        classify_score =np.zeros(num_of_sets)
        class_name = [[] for i in range(num_of_sets)]
        #load weight
        wt = Weight(cutoff)
        sign_dir = os.path.join(self.SIGN_DIR, 'db_version_' + str(version))
        wt.load_weights(sign_dir, self.WEIGHT_FILE+str(num_of_kpts)+'_'+str(cutoff))
        wt.load_weighted_sign(sign_dir, self.WEIGHT_SIGN_FILE+str(num_of_kpts)+'_'+str(cutoff))
    
        #Load tree
        tree_dir = os.path.join(self.TREE_DIR, 'db_version_' + str(version))
        tr = vl._vlfeat.VlHIKMTree(0, 0)
        tr.load(os.path.join(tree_dir, str(num_of_kpts) + self.TREE_FILE))    

        for k in test_database:
            #randomly get image from the img_dir
            img = Image.open(k[2]).convert('L')
            img = self.StandalizeImage(img, 480)
            img_data = np.asarray(img, dtype=float)
            
            #generate desc, sign and weighted sign
            kp = Keypoint()
            #kp.load_keypoint(self.KEYPOINT_DIR, self.KEYPOINT_FILE+str(num_of_kpts))
            kp.generate_keypoint(num_of_kpts, img.size[0], img.size[1], self.SIGMA)
            desc = Descriptor()
            desc.generate_desc(img_data, kp.kpt)
            #very important !! convert desc to float type
            #desc_f = np.array(desc.desc, dtype=float)
            
            sign = Signature()
            s = sign.generate_sign(tr,desc.desc, K, depth)
            weighted_sign = wt.weight_sign(s)
            
            #vote
            d=np.empty(total)
            for i in range(0, total):   
                d[i] = self.dist(wt.weighted_sign[i,:], weighted_sign)
            
            perm = np.argsort(d)
            vote_for = np.floor((perm[0:top])/num_in_set)+1                      
            votes = vl.vl_binsum(np.zeros(num_of_sets), np.ones(top), vote_for)
            
            #print votes
            best = np.argmax(votes)
            
            if best == k[1]:
                classify_score[k[1]] += 1
                
            print '=>'+str(k[0])
            
            class_name[k[1]] = k[3]
        
        classify_score = classify_score / num_in_test_set
        
        return zip(class_name, classify_score.tolist())