Exemple #1
0
    def forward(self, x: Tuple[t.Tensor, t.Tensor, t.Tensor], y: Tuple[t.Tensor, t.Tensor, t.Tensor]) -> t.Tensor:
        x_single_value, x_left_censored, x_right_censored = x
        y_single_value, y_left_censored, y_right_censored = y
        N = len(y_single_value) + len(y_left_censored) + len(y_right_censored)

        sigma = t.abs(self.sigma)

        # Step 1: compute loss for uncensored data based on pdf:
        # -sum(ln(pdf((y - x)/sigma)) - ln(sigma))
        log_likelihood_pdf = to_torch(0, device = self.device, grad = True)
        if len(y_single_value) > 0:
            log_likelihood_pdf = -t.sum(-(((y_single_value - x_single_value) / sigma) ** 2) / 2 - t.log(sigma + self.epsilon))

        # Step 2: compute loss for left censored data:
        # -sum(ln(cdf((y - x)/sigma) - cdf((truncation - x)/sigma)))
        log_likelihood_cdf = to_torch(0, device = self.device, grad = True)
        if len(y_left_censored) > 0:
            truncation_low_penalty = 0 if not self.truncated_low else cdf((self.truncated_low - x_left_censored) / sigma)
            log_likelihood_cdf = -t.sum(t.log(cdf((y_left_censored - x_left_censored) / sigma) - truncation_low_penalty + self.epsilon))

        # Step 3: compute the loss for right censored data:
        # -sum(ln(cdf((delta - y)/sigma) - cdf((delta - truncation)/sigma)))
        # Notice that: log(1 - cdf(z)) = log(cdf(-z)), thus compared to step 2, the signs for gamma and x are swapped
        log_likelihood_1_minus_cdf = to_torch(0, device = self.device, grad = True)
        if len(y_right_censored) > 0:
            truncation_high_penalty = 0 if not self.truncated_high else cdf((-self.truncated_high + x_right_censored) / sigma)
            log_likelihood_1_minus_cdf = -t.sum(t.log(cdf((-y_right_censored + x_right_censored) / sigma) - truncation_high_penalty + self.epsilon))

        log_likelihood = log_likelihood_pdf + log_likelihood_cdf + log_likelihood_1_minus_cdf

        std_penalty = 0 if not self.std_panalty else self.std_panalty * sigma

        return log_likelihood + std_penalty
Exemple #2
0
    def forward(self, x: Tuple[t.Tensor, t.Tensor, t.Tensor], y: Tuple[t.Tensor, t.Tensor, t.Tensor]) -> t.Tensor:
        x_single_value, x_left_censored, x_right_censored = x
        y_single_value, y_left_censored, y_right_censored = y
        N = len(y_single_value) + len(y_left_censored) + len(y_right_censored)

        # Step 1: compute loss for uncensored data based on pdf:
        # -sum(ln(pdf(y - delta)))
        log_likelihood_pdf = to_torch(0, device = self.device, grad = True)
        if len(y_single_value) > 0:
            log_likelihood_pdf = t.sum(((y_single_value - x_single_value) ** 2) / 2)

        # Step 2: compute loss for left censored data:
        # -sum(ln(cdf(y - delta) - cdf(truncation - delta)))
        log_likelihood_cdf = to_torch(0, device = self.device, grad = True)
        if len(y_left_censored) > 0:
            truncation_low_penalty = 0 if not self.truncated_low else cdf(self.truncated_low - x_left_censored)
            log_likelihood_cdf = -t.sum(t.log(cdf(y_left_censored - x_left_censored) - truncation_low_penalty + self.epsilon))

        # Step 3: compute the loss for right censored data:
        # -sum(ln(cdf(delta - y) - cdf(delta - truncation)))
        # Notice that: log(1 - cdf(x)) = log(cdf(-x)), thus the swapped signs
        log_likelihood_1_minus_cdf = to_torch(0, device = self.device, grad = True)
        if len(y_right_censored) > 0:
            truncation_high_penalty = 0 if not self.truncated_high else cdf(x_right_censored - self.truncated_high)
            log_likelihood_1_minus_cdf = -t.sum(t.log(cdf(x_right_censored - y_right_censored) - truncation_high_penalty + self.epsilon))

        log_likelihood = log_likelihood_pdf + log_likelihood_cdf + log_likelihood_1_minus_cdf

        return log_likelihood
Exemple #3
0
    def forward(self, x: Tuple[t.Tensor, t.Tensor, t.Tensor], y: Tuple[t.Tensor, t.Tensor, t.Tensor], gamma: Tuple[t.Tensor, t.Tensor, t.Tensor]) -> t.Tensor:
        x_single_value, x_left_censored, x_right_censored = x
        y_single_value, y_left_censored, y_right_censored = y
        gamma_single_value, gamma_left_censored, gamma_right_censored = gamma
        gamma_single_value, gamma_left_censored, gamma_right_censored = t.abs(gamma_single_value), t.abs(gamma_left_censored), t.abs(gamma_right_censored)
        N = len(y_single_value) + len(y_left_censored) + len(y_right_censored)

        # Step 1: compute loss for uncensored data based on pdf:
        # -sum(ln(gamma) + ln(pdf(gamma * y - x)))
        log_likelihood_pdf = to_torch(0, device = self.device, grad = True)
        if len(y_single_value) > 0:
            log_likelihood_pdf = -t.sum(t.log(gamma_single_value + self.epsilon) - ((gamma_single_value * y_single_value - x_single_value) ** 2) / 2)

        # Step 2: compute loss for left censored data:
        # -sum(ln(cdf(gamma * y - x) - cdf(gamma * truncation - x)))
        log_likelihood_cdf = to_torch(0, device = self.device, grad = True)
        if len(y_left_censored) > 0:
            truncation_low_penalty = 0 if not self.truncated_low else cdf(gamma_left_censored * self.truncated_low - x_left_censored)
            log_likelihood_cdf = -t.sum(t.log(cdf(gamma_left_censored * y_left_censored - x_left_censored) - truncation_low_penalty + self.epsilon))

        # Step 3: compute the loss for right censored data:
        # -sum(ln(cdf(x - gamma * y) - cdf(x - gamma * truncation)))
        # Notice that: log(1 - cdf(z)) = log(cdf(-z)), thus compared to step 2, the signs for gamma and x are swapped
        log_likelihood_1_minus_cdf = to_torch(0, device = self.device, grad = True)
        if len(y_right_censored) > 0:
            truncation_high_penalty = 0 if not self.truncated_high else cdf(-gamma_right_censored * self.truncated_high + x_right_censored)
            log_likelihood_1_minus_cdf = -t.sum(t.log(cdf(-gamma_right_censored * y_right_censored + x_right_censored) - truncation_high_penalty + self.epsilon))

        log_likelihood = log_likelihood_pdf + log_likelihood_cdf + log_likelihood_1_minus_cdf

        return log_likelihood
Exemple #4
0
    def test_cdf_gradient(self):
        input = [10, 15, 20, 25, 30]

        # manual gradient computing
        x = np.array(input)
        mean, std = x.mean(), x.std()
        x_normalized = normalize(x, mean, std)
        expected_cdf = norm.cdf(x_normalized)
        expected_log_likelihood = np.log(expected_cdf)
        expected_grad_log_likelihood_by_x = norm.pdf(x_normalized) / (expected_cdf * std)

        # automatic gradient computing
        x = to_torch(input, grad = True)
        # in this test mean & std are considered constants
        x_normalized = normalize(x, mean, std)
        cdf_result = cdf(x_normalized)
        assert_almost_equal(to_numpy(cdf_result), expected_cdf)

        log_likelihood_result = t.log(cdf_result)
        assert_almost_equal(to_numpy(log_likelihood_result), expected_log_likelihood)

        loss = t.sum(log_likelihood_result)
        loss.backward()
        assert_almost_equal(to_numpy(x.grad), expected_grad_log_likelihood_by_x)