Example #1
0
    def _get_triple_score(self,
                          head: BoxTensor,
                          tail: BoxTensor,
                          relation: BoxTensor,
                          triple_type: str = 'pos') -> torch.Tensor:
        """ Gets score using conditionals.

        :: note: We do not need to worry about the dimentions of the boxes. If
                it can sensibly broadcast it will.
            """

        triple = torch.stack((head.data, tail.data), dim=-3)
        int_lengths = head.per_dim_int_length(triple)
        head_tail_box_vol = torch.sum(
            torch.log(int_lengths.clamp_min(0) + 1e-8), dim=-1)
        # score = tail_head_relation_box_vol - tail_relation_box.log_soft_volume(
        #    temp=self.softbox_temp)
        tail_data = tail.data.view(-1, 1, 2, self.embedding_dim)
        score = head_tail_box_vol - tail._intersection_volume(tail_data, True)
        if triple_type == 'pos':
            triple = torch.stack((head.data, tail.data), dim=-3)
            target_probs = torch.ones_like(score)
            if not self.is_eval():
                self.surr_loss = self.pull_loss(triple, target_probs,
                                                int_lengths)
            else:
                self.surr_loss = 0
        return score
Example #2
0
    def _get_triple_score(self, head: BoxTensor, tail: BoxTensor,
                          relation: BoxTensor, label: Tensor) -> torch.Tensor:
        """ Gets score using conditionals.

        :: note: We do not need to worry about the dimentions of the boxes. If
                it can sensibly broadcast it will.
            """

        head.data[..., 0, :] = head.data[..., 0, :] % 1
        head.data[..., 1, :] = torch.sigmoid(head.data[..., 1, :])
        tail.data[..., 0, :] = tail.data[..., 0, :] % 1
        tail.data[..., 1, :] = torch.sigmoid(tail.data[..., 1, :])

        triple = torch.stack((head.data, tail.data), dim=-3)
        int_lengths = head.per_dim_int_length(triple)
        triple = torch.stack((head.data, tail.data), dim=-3)
        head_tail_box_vol = head._intersection_volume(triple, True, eps=1e-20)
        # score = tail_head_relation_box_vol - tail_relation_box.log_soft_volume(
        #    temp=self.softbox_temp)
        tail_data = tail.data.view(-1, 1, 2, self.embedding_dim)
        int_lengths_tail = tail.per_dim_int_length(tail_data, True)
        tail_volume = torch.sum(torch.log(int_lengths_tail.clamp_min(1e-20)),
                                dim=-1)
        score = head_tail_box_vol - tail_volume

        triple = torch.stack((head.data, tail.data), dim=-3)
        target_probs = label
        if not self.is_eval():
            self.surr_loss = self.pull_loss(triple, target_probs, int_lengths)
        else:
            self.surr_loss = 0
        return score
    def _get_triple_score(self, head: BoxTensor, tail: BoxTensor,
                          relation: BoxTensor) -> torch.Tensor:
        """ Gets score using conditionals.

        :: note: We do not need to worry about the dimentions of the boxes. If
                it can sensibly broadcast it will.
            """
        if self.is_eval():
            if len(head.data.shape) > len(tail.data.shape):
                tail.data = torch.cat(head.data.shape[-3] * [tail.data])
            elif len(head.data.shape) < len(tail.data.shape):
                head.data = torch.cat(tail.data.shape[-3] * [head.data])

        head_tail_box_vol = head.intersection_log_soft_volume(
            tail,
            temp=self.softbox_temp,
            gumbel_beta=self.gumbel_beta,
            bayesian=True)
        # score = tail_head_relation_box_vol - tail_relation_box.log_soft_volume(
        #    temp=self.softbox_temp)
        score = head_tail_box_vol - tail.log_soft_volume(
            temp=self.softbox_temp)
        if len(np.where(score > 0)[0]):
            breakpoint()
        return score
Example #4
0
    def _get_triple_score(self, head: BoxTensor, tail: BoxTensor,
                          relation: BoxTensor) -> torch.Tensor:

        transformed_box = self.get_relation_transform(head, relation)

        if self.is_eval():
            if len(head.data.shape) > len(tail.data.shape):
                tail.data = torch.cat(head.data.shape[-3] * [tail.data])
            elif len(head.data.shape) < len(tail.data.shape):
                transformed_box.data = torch.cat(tail.data.shape[-3] *
                                                 [transformed_box.data])

        intersection_box = transformed_box.gumbel_intersection(
            tail, gumbel_beta=self.gumbel_beta)
        intersection_vol = intersection_box._log_soft_volume_adjusted(
            intersection_box.z,
            intersection_box.Z,
            temp=self.softbox_temp,
            gumbel_beta=self.gumbel_beta)
        tail_vol = tail._log_soft_volume_adjusted(tail.z,
                                                  tail.Z,
                                                  temp=self.softbox_temp,
                                                  gumbel_beta=self.gumbel_beta)

        score = intersection_vol - tail_vol
        return score
 def _get_triple_score(self, head: BoxTensor, tail: BoxTensor,
                       relation_head: torch.Tensor,
                       relation_tail: torch.Tensor) -> torch.Tensor:
     head = self.get_relation_transform(box=head, relation=relation_head)
     tail = self.get_relation_transform(tail, relation_tail)
     head_tail_box_vol = head.intersection_log_soft_volume(
         tail, temp=self.softbox_temp)
     score = head_tail_box_vol - tail.log_soft_volume(
         temp=self.softbox_temp)
     return score
    def _get_triple_score(self, head: BoxTensor, tail: BoxTensor,
                          relation: BoxTensor) -> torch.Tensor:
        head_relation_box = relation.intersection(head)
        tail_relation_box = relation.intersection(tail)
        head_tail_relation_intersection_vol = tail_relation_box.intersection_log_soft_volume(
            head_relation_box, temp=self.softbox_temp)
        relation_box_vol = relation.log_soft_volume(temp=self.softbox_temp)
        score = head_tail_relation_intersection_vol - relation_box_vol

        return score
Example #7
0
 def _get_triple_score(self, head: BoxTensor, tail: BoxTensor,
                       relation: BoxTensor) -> torch.Tensor:
     intersection_box = head.gumbel_intersection(
         tail, gumbel_beta=self.gumbel_beta)
     intersection_vol = intersection_box._log_soft_volume_adjusted(
         intersection_box.z,
         intersection_box.Z,
         temp=self.softbox_temp,
         gumbel_beta=self.gumbel_beta)
     tail_vol = tail._log_soft_volume_adjusted(tail.z,
                                               tail.Z,
                                               temp=self.softbox_temp,
                                               gumbel_beta=self.gumbel_beta)
     score = intersection_vol - tail_vol
     return score
Example #8
0
 def get_relation_transform(self, box: BoxTensor, relation: torch.Tensor):
     weight_delta = self.relation_delta_weight(relation)
     weight_min = self.relation_min_weight(relation)
     bias_delta = self.relation_delta_bias(relation)
     bias_min = self.relation_min_bias(relation)
     if len(box.data.shape) == 3:
         box.data[:,
                  0, :] = box.data[:, 0, :].clone() * weight_min + bias_min
         box.data[:,
                  1, :] = nn.functional.softplus(box.data[:, 1, :].clone() *
                                                 weight_delta + bias_delta)
     else:
         box.data[:, :,
                  0, :] = box.data[:, :,
                                   0, :].clone() * weight_min + bias_min
         box.data[:, :, 1, :] = nn.functional.softplus(
             box.data[:, :, 1, :].clone() * weight_delta + bias_delta)
     return box
Example #9
0
    def _get_triple_score_hard_box(self,
                          head: BoxTensor, 
                          tail: BoxTensor,
                          per_dim_op='max',
                          accross_dim_op='max') -> torch.Tensor:
        """ Do not use this function for this class and its children.
        Implement get_scores_directly

        """
        return head.contains_violations(tail, per_dim_op=per_dim_op, 
            accross_dim_op=accross_dim_op, margin=self.margin)
    def _get_triple_score(self, head: BoxTensor, tail: BoxTensor,
                          relation: torch.Tensor) -> torch.Tensor:
        """ Gets score using conditionals.

        :: note: We do not need to worry about the dimentions of the boxes. If
                it can sensibly broadcast it will.
            """
        # get conditionals interval intersection scores

        numerators = head.dimension_wise_intersection_soft_volume(
            tail, temp=self.softbox_temp).clamp_min(1e-38)
        denominators = head.dimension_wise_soft_volume(
            temp=self.softbox_temp).clamp_min(1e-38)

        probs = numerators / denominators  # shape = (batch, num_dims)

        weighted_probs = relation * probs
        score = torch.sum(weighted_probs, dim=-1)

        return score
    def _get_triple_score(self, head: BoxTensor, tail: BoxTensor,
                          relation: BoxTensor) -> torch.Tensor:
        """ Gets score using conditionals.

        :: note: We do not need to worry about the dimentions of the boxes. If
                it can sensibly broadcast it will.
            """
        #head_relation_box = relation.intersection(head)
        #tail_relation_box = relation.intersection(tail)
        # tail_head_relation_box_vol = tail.intersection_log_soft_volume(
        #    head_relation_box, temp=self.softbox_temp)
        # score = tail_head_relation_box_vol - head_relation_box.log_soft_volume(
        #    temp=self.softbox_temp)
        head_tail_box_vol = head.intersection_log_soft_volume(
            tail, temp=self.softbox_temp)
        # score = tail_head_relation_box_vol - tail_relation_box.log_soft_volume(
        #    temp=self.softbox_temp)
        score = head_tail_box_vol - tail.log_soft_volume(
            temp=self.softbox_temp)

        return score
Example #12
0
    def _get_triple_score(self, head: BoxTensor, tail: BoxTensor,
                          relation: BoxTensor) -> torch.Tensor:
        if self.is_eval():
            if len(head.data.shape) > len(tail.data.shape):
                tail.data = torch.cat(head.data.shape[-3] * [tail.data])
            elif len(head.data.shape) < len(tail.data.shape):
                head.data = torch.cat(tail.data.shape[-3] * [head.data])

        intersection_box = head.gumbel_intersection(
            tail, gumbel_beta=self.gumbel_beta)

        intersection_vol = intersection_box._log_bessel_volume(
            intersection_box.z,
            intersection_box.Z,
            gumbel_beta=self.gumbel_beta)
        tail_vol = tail._log_bessel_volume(tail.z,
                                           tail.Z,
                                           gumbel_beta=self.gumbel_beta)

        score = intersection_vol - tail_vol
        return score
Example #13
0
    def _get_triple_score(self, head: BoxTensor, tail: BoxTensor,
                          relation: BoxTensor) -> torch.Tensor:
        if self.is_eval():
            if len(head.data.shape) > len(tail.data.shape):
                tail.data = torch.cat(head.data.shape[-3] * [tail.data])
                relation.data = torch.cat(head.data.shape[-3] *
                                          [relation.data])
            elif len(head.data.shape) < len(tail.data.shape):
                head.data = torch.cat(tail.data.shape[-3] * [head.data])
                relation.data = torch.cat(tail.data.shape[-3] *
                                          [relation.data])

        tail_relation_box = relation.gumbel_intersection(
            tail, gumbel_beta=self.gumbel_beta)
        tail_head_relation_box = tail_relation_box.gumbel_intersection(
            head, gumbel_beta=self.gumbel_beta)

        tail_head_relation_box_vol = tail_head_relation_box._log_soft_volume_adjusted(
            tail_head_relation_box.z,
            tail_head_relation_box.Z,
            temp=self.softbox_temp,
            gumbel_beta=self.gumbel_beta)
        tail_vol = tail._log_soft_volume_adjusted(tail.z,
                                                  tail.Z,
                                                  temp=self.softbox_temp,
                                                  gumbel_beta=self.gumbel_beta)
        score_head = tail_head_relation_box_vol - tail_vol

        return score_head
Example #14
0
    def _get_triple_score(self, head: BoxTensor, tail: BoxTensor,
                          relation: BoxTensor) -> torch.Tensor:
        if self.is_eval():
            if len(head.data.shape) > len(tail.data.shape):
                tail.data = torch.cat(head.data.shape[-3] * [tail.data])
            elif len(head.data.shape) < len(tail.data.shape):
                head.data = torch.cat(tail.data.shape[-3] * [head.data])

        head_sample = self.reparam_trick(head,
                                         gumbel_beta=self.gumbel_beta,
                                         n_samples=self.n_samples)
        tail_sample = self.reparam_trick(tail,
                                         gumbel_beta=self.gumbel_beta,
                                         n_samples=self.n_samples)

        intersection_sample_box = head_sample.gumbel_intersection(
            tail_sample, gumbel_beta=self.gumbel_beta)
        intersection_box = head.gumbel_intersection(
            tail, gumbel_beta=self.gumbel_beta)

        intersection_volume_fwd = intersection_sample_box._log_gumbel_volume(
            intersection_sample_box.z, intersection_box.Z)
        intersection_volume_bwd = intersection_sample_box._log_gumbel_volume(
            intersection_box.z, intersection_sample_box.Z)

        tail_volume_fwd = tail_sample._log_gumbel_volume(tail.z, tail_sample.Z)
        tail_volume_bwd = tail_sample._log_gumbel_volume(tail_sample.z, tail.Z)

        # score = (intersection_volume_fwd + intersection_volume_bwd)/2 - (
        #     tail_volume_fwd + tail_volume_bwd)/2

        intersection_score = torch.logsumexp(
            torch.stack((intersection_volume_fwd, intersection_volume_bwd)), 0)
        tail_score = torch.logsumexp(
            torch.stack((tail_volume_fwd, tail_volume_bwd)), 0)

        score = intersection_score - tail_score
        if len(torch.where(score > 0)[0]):
            breakpoint()
        return score
    def _get_triple_score(self, head: BoxTensor, tail: BoxTensor,
                          relation: BoxTensor) -> torch.Tensor:
        """ Gets score using three way intersection

        We do not need to worry about the dimentions of the boxes. If
            it can sensibly broadcast it will.
        """
        head_relation_box = relation.intersection(head)
        tail_relation_box = relation.intersection(tail)
        score = head_relation_box.intersection_log_soft_volume(
            tail_relation_box, temp=self.softbox_temp)

        return score
    def _get_triple_score(self,
                          head: BoxTensor,
                          tail: BoxTensor,
                          relation: BoxTensor,
                          head_rev: BoxTensor,
                          tail_rev: BoxTensor,
                          relation_rev: BoxTensor) -> torch.Tensor:


        tail_relation_box = relation.intersection(tail)
        tail_head_relation_box_vol = tail_relation_box.intersection_log_soft_volume(
            head, temp=self.softbox_temp)
        tail_vol = tail.log_soft_volume(temp=self.softbox_temp) 
        score_fwd = tail_head_relation_box_vol - tail_vol

        tail_relation_box_rev = relation_rev.intersection(tail_rev)
        tail_head_relation_box_rev_vol = tail_relation_box_rev.intersection_soft_volume(head_rev, temp=self.softbox_temp)

        tail_rev_vol = tail_rev.log_soft_volume(temp=self.softbox_temp)
        score_rev = tail_head_relation_box_rev_vol - tail_rev_vol


        return 0.5*(score_fwd + score_rev)
    def _get_triple_score(self, head: BoxTensor, tail: BoxTensor,
                          relation: BoxTensor) -> torch.Tensor:
        """ Gets score using conditionals.

        :: note: We do not need to worry about the dimentions of the boxes. If
                it can sensibly broadcast it will.
            """
        transformed_box = self.get_relation_transform(head, relation)
        head_tail_box_vol = transformed_box.intersection_log_soft_volume(
            tail, temp=self.softbox_temp)
        score = head_tail_box_vol - tail.log_soft_volume(
            temp=self.softbox_temp)

        return score
    def reparam_trick(self, box: BoxTensor,
                      embedding_keys: torch.Tensor) -> BoxTensor:
        dev = embedding_keys.device
        dist = MultivariateNormal(
            torch.zeros(box.data.shape[0], box.data.shape[-1]).to(dev),
            torch.eye(box.data.shape[-1]).to(dev))

        samples = dist.sample(torch.Size([self.n_samples]))
        sample = torch.mean(samples, axis=0)
        L = torch.sqrt(self.sigma(embedding_keys)**2)  #Cholesky decomposition

        shift = (L * sample).view([box.data.shape[0], 1, box.data.shape[-1]])
        shift = shift.repeat(1, box.data.shape[-2],
                             1)  #same amount of shift in z & Z

        box.data = box.data + shift  #shift z
        return box
Example #19
0
    def reparam_trick(self,
                      box: BoxTensor,
                      gumbel_beta: float = 1.,
                      n_samples: int = 10) -> torch.Tensor:
        dev = box.data.device
        m = Gumbel(
            torch.zeros(box.data.shape[0], box.data.shape[-1]).to(dev),
            torch.tensor([1.0]).to(dev))
        samples = m.sample(torch.Size([n_samples]))
        sample_fwd = torch.mean(samples, axis=0)
        samples = m.sample(torch.Size([n_samples]))
        sample_bwd = -torch.mean(samples, axis=0)

        z = sample_fwd * gumbel_beta + box.z.data
        Z = sample_bwd * gumbel_beta + box.Z.data

        return BoxTensor(torch.stack((z, Z), -2))