示例#1
0
    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
示例#2
0
    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