def compute_dist(self, images, labels, sample_size=None): """Compute distances for pairs sample_size: None or integer, number of pairs as all pairs can be large number. If None, by default all possible pairs are considered. Returns: dist_embed: array of distances actual_issame: array of booleans, True if positive pair, False if negative pair """ # Run forward pass to calculate embeddings print('Generating pairs and computing embeddings...') # Define generator to loop over data gen = ImageDataGenerator( data_format=K.image_data_format(), preprocessing_function=self.backend_class.normalize, ) features_shape = self.model.get_output_shape_at(0)[1:] if sample_size is None: n_pairs = comb(images.shape[0], 2, exact=True) else: n_pairs = int(sample_size) embeddings = np.zeros(shape=(2, n_pairs) + features_shape) actual_issame = np.full(shape=(n_pairs, ), fill_value=True, dtype=np.bool) # Create all possible combinations of images (no repeats) idx = 0 for i in range(images.shape[0]): for j in range(i): img_1 = gen.random_transform(images[i].astype(K.floatx())) img_1 = gen.preprocessing_function(img_1) img_2 = gen.random_transform(images[j].astype(K.floatx())) img_2 = gen.preprocessing_function(img_2) embeddings[0, idx] = self.model.predict_on_batch( np.expand_dims(img_1, 0)) embeddings[1, idx] = self.model.predict_on_batch( np.expand_dims(img_2, 0)) if labels[i] != labels[j]: actual_issame[idx] = False idx += 1 if idx >= n_pairs: break if idx >= n_pairs: break print('Number of pairs in evaluation {}, number of positive {}'.format( len(actual_issame), np.sum(actual_issame))) dist_emb = distance(embeddings[0], embeddings[1], distance_metric=0) return dist_emb, actual_issame
def compute_dist(self, images, labels, sample_size=None): """Compute distances for pairs sample_size: None or integer, number of pairs as all pairs can be large number. If None, by default all possible pairs are considered. """ # Run forward pass to calculate embeddings print('Generating pairs and computing embeddings...') # Define generator to loop over data gen = ImageDataGenerator( data_format=K.image_data_format(), preprocessing_function=self.backend_class.normalize, ) if sample_size is None: n_pairs = comb(images.shape[0], 2, exact=True) else: n_pairs = int(sample_size) print('Computing distances for {} pairs...'.format(n_pairs)) distances = np.zeros(shape=(n_pairs, )) actual_issame = np.full(shape=(n_pairs, ), fill_value=True, dtype=np.bool) # Create all possible combinations of images (no repeats) idx = 0 for i in range(images.shape[0]): for j in range(i): # Preprocess each image img_1 = gen.random_transform(images[i].astype(K.floatx())) img_1 = gen.preprocessing_function(img_1) img_2 = gen.random_transform(images[j].astype(K.floatx())) img_2 = gen.preprocessing_function(img_2) # Predict distance using Siamese model distances[idx] = self.model.predict_on_batch( [np.expand_dims(img_1, 0), np.expand_dims(img_2, 0)]) # Change flag to False for negative pairs if labels[i] != labels[j]: actual_issame[idx] = False if idx > 0 and idx % 100 == 0: print('Computed distances for {} pairs'.format(idx)) # print('Distance: {:.2f} actual: {}. labels {}, {}'.format(distances[idx], actual_issame[idx], # labels[i], labels[j])) idx += 1 if idx >= n_pairs: break if idx >= n_pairs: break print('Number of pairs in evaluation {}, number of positive {}'.format( len(actual_issame), np.sum(actual_issame))) return distances, actual_issame