def __init__(self, dataset=FaceRecData.Yalefaces_A, data_directory='data', part=[70, 10, 20], loud=False, d_tuning=[25, 100, 25], k_tuning=[1, 15], var_tuning=[1000, 10000, 1000], skip_tuning=False, d_value=0, k_value=3, var_value=10000, use_kernel=False): # TODO: Better way to init this? ''' Constructor for FaceRecTest. Args (optional): dataset (FaceRecData.value): The dataset to use. data_directory (str): The directory where the data lives. part (int): What percentage of the data should be used for training, dev, and test. loud (bool): Whether the classifier should print out fine details. d_tuning (tuple<int>): The range of PCA dimensions to observe during tuning. k_tuning (tuple<int>): The ranke of k for the kNN classifier to observe during tuning. ''' self.dataset = dataset self.data_directory = data_directory self.trn_part = part[0] self.dev_part = part[1] self.tst_part = part[2] self.loud = loud self.d_tuning = d_tuning self.k_tuning = k_tuning self.var_tuning = var_tuning self.skip_tuning = skip_tuning self.d_value = d_value self.k_value = k_value self.var_value = var_value self.use_kernel = use_kernel self.face_recognizer = FaceRecognizer(use_kernel=use_kernel) self.instances = None self.trn_data = None self.dev_data = None self.tst_data = None if sum(part) != 100: raise RuntimeError('Train/Dev/Test partitions don\'t add up ' 'to 100%') if len(d_tuning) != 3: raise RuntimeError('3 parameters are required for tuning d ' '({} found)'.format(len(d_tuning))) if len(k_tuning) != 2: raise RuntimeError('2 parameters are required for tuning k ' '({} found)'.format(len(d_tuning)))
def ready(self): # This global variable will be used by views.py. # read_trained_data() only needs to be read once here, instead # of every time a request comes in.`` global myFaceRecognizer myFaceRecognizer = FaceRecognizer() logger.info("Created myFaceRecognizer")
class FaceRecTest: def __init__(self, dataset=FaceRecData.Yalefaces_A, data_directory='data', part=[70, 10, 20], loud=False, d_tuning=[25, 100, 25], k_tuning=[1, 15], var_tuning=[1000, 10000, 1000], skip_tuning=False, d_value=0, k_value=3, var_value=10000, use_kernel=False): # TODO: Better way to init this? ''' Constructor for FaceRecTest. Args (optional): dataset (FaceRecData.value): The dataset to use. data_directory (str): The directory where the data lives. part (int): What percentage of the data should be used for training, dev, and test. loud (bool): Whether the classifier should print out fine details. d_tuning (tuple<int>): The range of PCA dimensions to observe during tuning. k_tuning (tuple<int>): The ranke of k for the kNN classifier to observe during tuning. ''' self.dataset = dataset self.data_directory = data_directory self.trn_part = part[0] self.dev_part = part[1] self.tst_part = part[2] self.loud = loud self.d_tuning = d_tuning self.k_tuning = k_tuning self.var_tuning = var_tuning self.skip_tuning = skip_tuning self.d_value = d_value self.k_value = k_value self.var_value = var_value self.use_kernel = use_kernel self.face_recognizer = FaceRecognizer(use_kernel=use_kernel) self.instances = None self.trn_data = None self.dev_data = None self.tst_data = None if sum(part) != 100: raise RuntimeError('Train/Dev/Test partitions don\'t add up ' 'to 100%') if len(d_tuning) != 3: raise RuntimeError('3 parameters are required for tuning d ' '({} found)'.format(len(d_tuning))) if len(k_tuning) != 2: raise RuntimeError('2 parameters are required for tuning k ' '({} found)'.format(len(d_tuning))) def load_data(self): ''' Loads data to use in training. ''' # Load data if self.dataset == FaceRecData.Yalefaces_A: self.instances = ImageIO.loadYalefacesImages(self.data_directory, loud=False) elif self.dataset == FaceRecData.Yalefaces_B: self.instances = ImageIO.loadExtendedCroppedYalefaces( self.data_directory, loud=False) else: raise RuntimeError('FaceRecTest not assigned a valid dataset') # Sample from each class to create train/dev/test partitions self.trn_data = list() self.dev_data = list() self.tst_data = list() # Sort instances by label classes = dict() for instance in self.instances: label = instance[0] if label not in classes.keys(): classes[label] = list() classes[label].append(instance) num_labels = max(classes.keys()) + 1 # Calculate how many samples should be in each partition num_trn = int((self.trn_part / 100.0) * len(self.instances)) num_dev = int((self.dev_part / 100.0) * len(self.instances)) num_tst = int((self.tst_part / 100.0) * len(self.instances)) # If any leftovers, give more to training partition num_trn += len(self.instances) - sum((num_trn, num_dev, num_tst)) # Partition trn/dev/tst def partition(src, dest, num): num_labels = max(src.keys()) + 1 count = 0 i = 0 while i < num: instances = src[count % num_labels] if len(instances) > 0: idx = random.randint(0, len(instances) - 1) dest.append(instances.pop(idx)) i += 1 count += 1 partition(classes, self.trn_data, num_trn) partition(classes, self.dev_data, num_dev) partition(classes, self.tst_data, num_tst) def train(self): ''' Trains the face recognizer with the training data. ''' if self.trn_data is None: raise RuntimeError('Data has not been loaded yet!') self.face_recognizer.set_dimensions(self.d_value) self.face_recognizer.set_k_neighbors(self.k_value) self.face_recognizer.set_kernel_variance(self.var_value) self.face_recognizer.train(self.trn_data) def tune(self): ''' Tunes the face recognizer with the dev data. ''' results = list() optimal_d = 1 optimal_k = 1 optimal_v = 1 accuracy = 0 d_start, d_end, d_step = self.d_tuning k_start, k_end = self.k_tuning v_start, v_end, v_step = self.var_tuning if not self.use_kernel: v_start, v_end, v_step = 0, 0, 1 for v in range(v_start, v_end + 1, v_step): self.face_recognizer.set_kernel_variance(v) for d in range(d_start, d_end + 1, d_step): self.face_recognizer.set_dimensions(d) for k in range(k_start, k_end + 1, 2): self.face_recognizer.set_k_neighbors(k) test_results = self.test(use_dev=True) results.append((d, k, test_results['accuracy'])) if test_results['accuracy'] > accuracy: optimal_d = d optimal_k = k optimal_v = v accuracy = test_results['accuracy'] self.face_recognizer.set_dimensions(optimal_d) self.face_recognizer.set_k_neighbors(optimal_k) self.face_recognizer.set_kernel_variance(optimal_v) return results def test(self, use_dev=False): ''' Tests the data and prints the results. Returns: dict, database of results: 'accuracy' : Accuracy of the classifier. 'correct' : The number the classifier got correct. 'predictions' : List of predictions the classifier made. ''' if self.tst_data is None: raise RuntimeError('Data has not been loaded yet!') predicted_labels = list() data = self.tst_data if not use_dev else self.dev_data correct_count = 0 for idx, instance in enumerate(data): predicted_label = self.face_recognizer.classify(instance[1]) if predicted_label == instance[0]: correct_count += 1 predicted_labels.append(predicted_label) return { 'accuracy': correct_count / float(len(data)), 'correct': correct_count, 'predictions': predicted_labels } def run(self): ''' Loads, trains, and tests the FaceRecognizer. Prints out a report. ''' print '| ---- ---- FaceRec ---- ----' print '| Dataset : {}'.format(self.dataset) print '| Train/Dev/Test : {}/{}/{}'.format(self.trn_part, self.dev_part, self.tst_part) self.load_data() print '|' print '| Total Samples : {}'.format(len(self.instances)) print '| Dimensions : {}'.format(len(self.instances[0][1])) self.train() if not self.skip_tuning: print '|' print '| Tuning d from {:3d} to {:3d} with step {}'.format( self.d_tuning[0], self.d_tuning[1], self.d_tuning[2]) print '| Tuning k from {:3d} to {:3d} with step 2'.format( self.k_tuning[0], self.k_tuning[1]) if self.use_kernel: print '| Tuning RBF variance from {} to {} with step {}' \ .format(self.var_tuning[0], self.var_tuning[1], self.var_tuning[2]) tune_results = self.tune() print '|' print '| PCA Dimensions : {}'.format( self.face_recognizer.pca_model.dimensions) print '| k-Neighbors : {}'.format( self.face_recognizer.knn_classifier.neighbors) if self.use_kernel: print '| RBF Variance : {}'.format( self.face_recognizer.pca_model.variance) print '' test_results = self.test() print 'Accuracy: {:.3f} ({}/{})'.format(test_results['accuracy'], test_results['correct'], len(self.tst_data)) if self.loud: print '\nTuning results:' for entry in tune_results: print '\td = {:2d}, k = {:2d}, accuracy = {:.3f}'.format( entry[0], entry[1], entry[2]) print '\nPer-case results:' for idx, predicted_label in enumerate(test_results['predictions']): print '\t[Case {:03d}] Predicted {:2d} as {:2d}'.format( idx, self.tst_data[idx][0], predicted_label)
class FaceRecTest: def __init__(self, dataset=FaceRecData.Yalefaces_A, data_directory='data', part=[70, 10, 20], loud=False, d_tuning=[25, 100, 25], k_tuning=[1, 15], var_tuning=[1000, 10000, 1000], skip_tuning=False, d_value=0, k_value=3, var_value=10000, use_kernel=False): # TODO: Better way to init this? ''' Constructor for FaceRecTest. Args (optional): dataset (FaceRecData.value): The dataset to use. data_directory (str): The directory where the data lives. part (int): What percentage of the data should be used for training, dev, and test. loud (bool): Whether the classifier should print out fine details. d_tuning (tuple<int>): The range of PCA dimensions to observe during tuning. k_tuning (tuple<int>): The ranke of k for the kNN classifier to observe during tuning. ''' self.dataset = dataset self.data_directory = data_directory self.trn_part = part[0] self.dev_part = part[1] self.tst_part = part[2] self.loud = loud self.d_tuning = d_tuning self.k_tuning = k_tuning self.var_tuning = var_tuning self.skip_tuning = skip_tuning self.d_value = d_value self.k_value = k_value self.var_value = var_value self.use_kernel = use_kernel self.face_recognizer = FaceRecognizer(use_kernel=use_kernel) self.instances = None self.trn_data = None self.dev_data = None self.tst_data = None if sum(part) != 100: raise RuntimeError('Train/Dev/Test partitions don\'t add up ' 'to 100%') if len(d_tuning) != 3: raise RuntimeError('3 parameters are required for tuning d ' '({} found)'.format(len(d_tuning))) if len(k_tuning) != 2: raise RuntimeError('2 parameters are required for tuning k ' '({} found)'.format(len(d_tuning))) def load_data(self): ''' Loads data to use in training. ''' # Load data if self.dataset == FaceRecData.Yalefaces_A: self.instances = ImageIO.loadYalefacesImages( self.data_directory, loud=False) elif self.dataset == FaceRecData.Yalefaces_B: self.instances = ImageIO.loadExtendedCroppedYalefaces( self.data_directory, loud=False) else: raise RuntimeError('FaceRecTest not assigned a valid dataset') # Sample from each class to create train/dev/test partitions self.trn_data = list() self.dev_data = list() self.tst_data = list() # Sort instances by label classes = dict() for instance in self.instances: label = instance[0] if label not in classes.keys(): classes[label] = list() classes[label].append(instance) num_labels = max(classes.keys())+1 # Calculate how many samples should be in each partition num_trn = int( (self.trn_part/100.0) * len(self.instances) ) num_dev = int( (self.dev_part/100.0) * len(self.instances) ) num_tst = int( (self.tst_part/100.0) * len(self.instances) ) # If any leftovers, give more to training partition num_trn += len(self.instances) - sum((num_trn, num_dev, num_tst)) # Partition trn/dev/tst def partition(src, dest, num): num_labels = max(src.keys())+1 count = 0 i = 0 while i < num: instances = src[count % num_labels] if len(instances) > 0: idx = random.randint(0, len(instances)-1) dest.append( instances.pop(idx) ) i += 1 count += 1 partition(classes, self.trn_data, num_trn) partition(classes, self.dev_data, num_dev) partition(classes, self.tst_data, num_tst) def train(self): ''' Trains the face recognizer with the training data. ''' if self.trn_data is None: raise RuntimeError('Data has not been loaded yet!') self.face_recognizer.set_dimensions(self.d_value) self.face_recognizer.set_k_neighbors(self.k_value) self.face_recognizer.set_kernel_variance(self.var_value) self.face_recognizer.train(self.trn_data) def tune(self): ''' Tunes the face recognizer with the dev data. ''' results = list() optimal_d = 1 optimal_k = 1 optimal_v = 1 accuracy = 0 d_start, d_end, d_step = self.d_tuning k_start, k_end = self.k_tuning v_start, v_end, v_step = self.var_tuning if not self.use_kernel: v_start, v_end, v_step = 0, 0, 1 for v in range(v_start, v_end+1, v_step): self.face_recognizer.set_kernel_variance(v) for d in range(d_start, d_end+1, d_step): self.face_recognizer.set_dimensions(d) for k in range(k_start, k_end+1, 2): self.face_recognizer.set_k_neighbors(k) test_results = self.test(use_dev=True) results.append( (d, k, test_results['accuracy'])) if test_results['accuracy'] > accuracy: optimal_d = d optimal_k = k optimal_v = v accuracy = test_results['accuracy'] self.face_recognizer.set_dimensions(optimal_d) self.face_recognizer.set_k_neighbors(optimal_k) self.face_recognizer.set_kernel_variance(optimal_v) return results def test(self, use_dev=False): ''' Tests the data and prints the results. Returns: dict, database of results: 'accuracy' : Accuracy of the classifier. 'correct' : The number the classifier got correct. 'predictions' : List of predictions the classifier made. ''' if self.tst_data is None: raise RuntimeError('Data has not been loaded yet!') predicted_labels = list() data = self.tst_data if not use_dev else self.dev_data correct_count = 0 for idx, instance in enumerate(data): predicted_label = self.face_recognizer.classify(instance[1]) if predicted_label == instance[0]: correct_count += 1 predicted_labels.append(predicted_label) return { 'accuracy' : correct_count/float(len(data)), 'correct' : correct_count, 'predictions' : predicted_labels } def run(self): ''' Loads, trains, and tests the FaceRecognizer. Prints out a report. ''' print '| ---- ---- FaceRec ---- ----' print '| Dataset : {}'.format(self.dataset) print '| Train/Dev/Test : {}/{}/{}'.format(self.trn_part, self.dev_part, self.tst_part) self.load_data() print '|' print '| Total Samples : {}'.format(len(self.instances)) print '| Dimensions : {}'.format(len(self.instances[0][1])) self.train() if not self.skip_tuning: print '|' print '| Tuning d from {:3d} to {:3d} with step {}'.format( self.d_tuning[0], self.d_tuning[1], self.d_tuning[2]) print '| Tuning k from {:3d} to {:3d} with step 2'.format( self.k_tuning[0], self.k_tuning[1]) if self.use_kernel: print '| Tuning RBF variance from {} to {} with step {}' \ .format(self.var_tuning[0], self.var_tuning[1], self.var_tuning[2]) tune_results = self.tune() print '|' print '| PCA Dimensions : {}'.format( self.face_recognizer.pca_model.dimensions) print '| k-Neighbors : {}'.format( self.face_recognizer.knn_classifier.neighbors) if self.use_kernel: print '| RBF Variance : {}'.format( self.face_recognizer.pca_model.variance) print '' test_results = self.test() print 'Accuracy: {:.3f} ({}/{})'.format(test_results['accuracy'], test_results['correct'], len(self.tst_data)) if self.loud: print '\nTuning results:' for entry in tune_results: print '\td = {:2d}, k = {:2d}, accuracy = {:.3f}'.format( entry[0], entry[1], entry[2]) print '\nPer-case results:' for idx, predicted_label in enumerate(test_results['predictions']): print '\t[Case {:03d}] Predicted {:2d} as {:2d}'.format( idx, self.tst_data[idx][0], predicted_label)