Exemplo n.º 1
0
    def __call__(self, features: List[Dict[str, Union[List[int], np.ndarray]]]) -> Dict[str, np.ndarray]:
        # reformat list to dict and set to pytorch format
        batch = self.feature_extractor.pad(
            features,
            max_length=self.max_length,
            padding=self.padding,
            pad_to_multiple_of=self.pad_to_multiple_of,
            return_tensors="np",
        )
        mask_indices_seq_length = self.model._get_feat_extract_output_lengths(batch["input_values"].shape[-1])

        # sample randomly masked indices
        batch["mask_time_indices"] = _compute_mask_indices(
            (batch["input_values"].shape[0], mask_indices_seq_length),
            self.model.config.mask_time_prob,
            self.model.config.mask_time_length,
            min_masks=2,
        )

        # sample indices to take for negative vectors
        batch["sampled_negative_indices"] = _sample_negative_indices(
            (batch["mask_time_indices"].shape + (self.model.config.proj_codevector_dim,)),
            self.model.config.num_negatives,
        )

        return batch
Exemplo n.º 2
0
    def test_sample_negatives(self):
        batch_size = 2
        sequence_length = 10
        hidden_size = 4
        num_negatives = 3

        features = (np.arange(sequence_length * hidden_size) // hidden_size).reshape(
            sequence_length, hidden_size
        )  # each value in vector consits of same value
        features = np.broadcast_to(features[None, :], (batch_size, sequence_length, hidden_size))

        negative_indices = _sample_negative_indices(features.shape, num_negatives)

        features = features.reshape(-1, hidden_size)  # BTC => (BxT)C
        # take negative vectors from sampled indices
        sampled_negatives = features[negative_indices.reshape(-1)]
        negatives = sampled_negatives.reshape(batch_size, sequence_length, num_negatives, hidden_size).transpose(
            2, 0, 1, 3
        )

        self.assertTrue(negatives.shape == (num_negatives, batch_size, sequence_length, hidden_size))

        # make sure no negatively sampled vector is actually a positive one
        for negative in negatives:
            self.assertTrue(((negative - features.reshape(negative.shape)) == 0).sum() == 0.0)

        # make sure that full vectors are sampled and not values of vectors
        # => this means that `unique()` yields a single value for `hidden_size` dim
        self.assertTrue(np.unique(negatives, axis=-1).shape, (num_negatives, batch_size, sequence_length, 1))
    def test_sample_negatives_with_attn_mask(self):
        batch_size = 2
        sequence_length = 10
        hidden_size = 4
        num_negatives = 3

        features = (
            np.arange(sequence_length * hidden_size) // hidden_size).reshape(
                sequence_length,
                hidden_size)  # each value in vector consits of same value

        # second half of last input tensor is padded
        attention_mask = np.ones((batch_size, sequence_length), dtype=np.int8)
        attention_mask[-1, sequence_length // 2:] = 0

        forbidden_indices = (
            np.arange(sequence_length // 2, sequence_length, dtype=np.int32) +
            (batch_size - 1) * sequence_length).tolist()

        features = np.broadcast_to(features[None, :],
                                   (batch_size, sequence_length, hidden_size))

        negative_indices = _sample_negative_indices(
            features.shape, num_negatives, attention_mask=attention_mask)

        # make sure that no padding tokens are sampled
        self.assertTrue(
            all([idx not in negative_indices for idx in forbidden_indices]))

        features = features.reshape(-1, hidden_size)  # BTC => (BxT)C
        # take negative vectors from sampled indices
        sampled_negatives = features[negative_indices.reshape(-1)]
        negatives = sampled_negatives.reshape(batch_size, sequence_length,
                                              num_negatives,
                                              hidden_size).transpose(
                                                  2, 0, 1, 3)

        self.assertTrue(negatives.shape == (num_negatives, batch_size,
                                            sequence_length, hidden_size))

        # make sure no negatively sampled vector is actually a positive one
        for negative in negatives:
            self.assertTrue(
                ((negative -
                  features.reshape(negative.shape)) == 0).sum() == 0.0)

        # make sure that full vectors are sampled and not just slices of vectors
        # => this means that `unique()` yields a single value for `hidden_size` dim
        self.assertTrue(
            np.unique(negatives, axis=-1).shape,
            (num_negatives, batch_size, sequence_length, 1))
Exemplo n.º 4
0
    def __call__(
        self, features: List[Dict[str, Union[List[int], np.ndarray]]]
    ) -> Dict[str, np.ndarray]:
        # reformat list to dict and set to pytorch format
        batch = self.feature_extractor.pad(
            features,
            max_length=self.max_length,
            padding=self.padding,
            pad_to_multiple_of=self.pad_to_multiple_of,
            return_tensors="np",
        )
        mask_indices_seq_length = self.model._get_feat_extract_output_lengths(
            batch["input_values"].shape[-1])

        batch_size = batch["input_values"].shape[0]

        attention_mask = None
        if batch["attention_mask"] is not None:
            output_lengths = self.model._get_feat_extract_output_lengths(
                batch["attention_mask"].sum(-1))
            attention_mask = np.zeros((batch_size, mask_indices_seq_length),
                                      dtype=np.int8)

            # these two operations makes sure that all values
            # before the output lengths indices are attended to
            attention_mask[(np.arange(attention_mask.shape[0]),
                            output_lengths - 1)] = 1
            attention_mask = jnp.flip(
                jnp.flip(attention_mask, -1).cumsum(-1), -1).astype("bool")

        # sample randomly masked indices
        batch["mask_time_indices"] = _compute_mask_indices(
            (batch_size, mask_indices_seq_length),
            self.model.config.mask_time_prob,
            self.model.config.mask_time_length,
            attention_mask=attention_mask,
            min_masks=2,
        )

        # sample indices to take for negative vectors
        batch["sampled_negative_indices"] = _sample_negative_indices(
            (batch["mask_time_indices"].shape +
             (self.model.config.proj_codevector_dim, )),
            self.model.config.num_negatives,
            attention_mask=attention_mask,
        )

        return batch