Beispiel #1
0
    def aggregate(self, v1, v2, num_classes,
                  v1_lengths=None, v2_lengths=None, use_masking=True, reuse=False):
        """
        Aggregate phase.

        Args:
            v1: tensor with shape (batch_size, time_steps, num_units)
            v2: tensor with shape (batch_size, time_steps, num_units)
            num_classes: number of output units
            v1_lengths: time_steps in v1
            v2_lengths: time_steps in v2
            use_masking: use masking
            reuse: reuse variables
        """
        with tf.variable_scope('aggregate', reuse=reuse) as _:
            if use_masking:
                v1 = mask_3d(sequences=v1, sequence_lengths=v1_lengths, mask_value=0, dimension=1)
                v2 = mask_3d(sequences=v2, sequence_lengths=v2_lengths, mask_value=0, dimension=1)

            v1_sum, v2_sum = tf.reduce_sum(v1, [1]), tf.reduce_sum(v2, [1])

            v1_v2 = tf.concat(axis=1, values=[v1_sum, v2_sum])
            transformed_v1_v2 = self._transform_aggregate(v1_v2, reuse=reuse)

            logits = tf.contrib.layers.fully_connected(inputs=transformed_v1_v2,
                                                       num_outputs=num_classes,
                                                       weights_initializer=tf.random_normal_initializer(0.0, 0.01),
                                                       biases_initializer=tf.zeros_initializer(),
                                                       activation_fn=None)
        return logits
Beispiel #2
0
    def attend(self, sequence1, sequence2,
               sequence1_lengths=None, sequence2_lengths=None, use_masking=True, reuse=False):
        """
        Attend phase.

        Args:
            sequence1: tensor with shape (batch_size, time_steps, num_units)
            sequence2: tensor with shape (batch_size, time_steps, num_units)
            sequence1_lengths: time_steps in sequence1
            sequence2_lengths: time_steps in sequence2
            use_masking: use masking
            reuse: reuse variables

        Returns:
            two tensors with shape (batch_size, time_steps, num_units)
        """
        with tf.variable_scope('attend') as _:
            # tensor with shape (batch_size, time_steps, num_units)
            transformed_sequence1 = self._transform_attend(sequence1, reuse)

            # tensor with shape (batch_size, time_steps, num_units)
            transformed_sequence2 = self._transform_attend(sequence2, True)

            # tensor with shape (batch_size, time_steps, time_steps)
            self.raw_attentions = tf.matmul(transformed_sequence1, tf.transpose(transformed_sequence2, [0, 2, 1]))

            masked_raw_attentions = self.raw_attentions
            if use_masking:
                masked_raw_attentions = mask_3d(sequences=masked_raw_attentions,
                                                sequence_lengths=sequence2_lengths,
                                                mask_value=- np.inf, dimension=2)
            self.attention_sentence1 = attention_softmax3d(masked_raw_attentions)

            # tensor with shape (batch_size, time_steps, time_steps)
            attention_transposed = tf.transpose(self.raw_attentions, [0, 2, 1])
            masked_attention_transposed = attention_transposed
            if use_masking:
                masked_attention_transposed = mask_3d(sequences=masked_attention_transposed,
                                                      sequence_lengths=sequence1_lengths,
                                                      mask_value=- np.inf, dimension=2)
            self.attention_sentence2 = attention_softmax3d(masked_attention_transposed)

            # tensors with shape (batch_size, time_steps, num_units)
            alpha = tf.matmul(self.attention_sentence2, sequence1, name='alpha')
            beta = tf.matmul(self.attention_sentence1, sequence2, name='beta')
            return alpha, beta