Пример #1
0
def compute_downstream_task(ground_truth_data,
                            representation_function,
                            random_state,
                            artifact_dir=None,
                            num_train=gin.REQUIRED,
                            num_test=gin.REQUIRED,
                            batch_size=16):
    """Computes loss of downstream task.

  Args:
    ground_truth_data: GroundTruthData to be sampled from.
    representation_function: Function that takes observations as input and
      outputs a dim_representation sized representation for each observation.
    random_state: Numpy random state used for randomness.
    artifact_dir: Optional path to directory where artifacts can be saved.
    num_train: Number of points used for training.
    num_test: Number of points used for testing.
    batch_size: Batch size for sampling.

  Returns:
    Dictionary with scores.
  """
    del artifact_dir
    scores = {}
    for train_size in num_train:
        mus_train, ys_train = utils.generate_batch_factor_code(
            ground_truth_data, representation_function, train_size,
            random_state, batch_size)
        mus_test, ys_test = utils.generate_batch_factor_code(
            ground_truth_data, representation_function, num_test, random_state,
            batch_size)
        predictor_model = utils.make_predictor_fn()

        print(mus_train.shape, ys_train.shape)
        train_err, test_err = _compute_loss(np.transpose(mus_train), ys_train,
                                            np.transpose(mus_test), ys_test,
                                            predictor_model)
        size_string = str(train_size)
        scores[size_string + ":mean_train_accuracy"] = np.mean(train_err)
        scores[size_string + ":mean_test_accuracy"] = np.mean(test_err)
        scores[size_string + ":min_train_accuracy"] = np.min(train_err)
        scores[size_string + ":min_test_accuracy"] = np.min(test_err)
        for i in range(len(train_err)):
            scores[size_string +
                   ":train_accuracy_factor_{}".format(i)] = train_err[i]
            scores[size_string +
                   ":test_accuracy_factor_{}".format(i)] = test_err[i]

    return scores
Пример #2
0
def compute_fairness(ground_truth_data,
                     representation_function,
                     random_state,
                     artifact_dir=None,
                     num_train=gin.REQUIRED,
                     num_test_points_per_class=gin.REQUIRED,
                     batch_size=16):
    """Computes unfairness scores.

  We first compute either the mean or maximum total variation for a given
  sensitive and target variable. Then, we either average or take the maximum
  with respect to target and sensitive variable. For convenience, we compute and
  save all combinations. The score used in Section 4 of the paper is here called
  mean_fairness:mean_pred:mean_sens.

  Args:
    ground_truth_data: GroundTruthData to be sampled from.
    representation_function: Function that takes observations as input and
      outputs a dim_representation sized representation for each observation.
    random_state: Numpy random state used for randomness.
    artifact_dir: Optional path to directory where artifacts can be saved.
    num_train: Number of points used for training.
    num_test_points_per_class: Number of points used for testing.
    batch_size: Batch size for sampling.

  Returns:
    Dictionary with scores.
  """
    del artifact_dir
    factor_counts = ground_truth_data.factors_num_values
    num_factors = len(factor_counts)

    scores = {}
    # Training a predictive model.
    mus_train, ys_train = utils.generate_batch_factor_code(
        ground_truth_data, representation_function, num_train, random_state,
        batch_size)
    predictor_model_fn = utils.make_predictor_fn()

    # For each factor train a single predictive model.
    mean_fairness = np.zeros((num_factors, num_factors), dtype=np.float64)
    max_fairness = np.zeros((num_factors, num_factors), dtype=np.float64)
    for i in range(num_factors):
        model = predictor_model_fn()
        model.fit(np.transpose(mus_train), ys_train[i, :])

        for j in range(num_factors):
            if i == j:
                continue
            # Sample a random set of factors once.
            original_factors = ground_truth_data.sample_factors(
                num_test_points_per_class, random_state)
            counts = np.zeros((factor_counts[i], factor_counts[j]),
                              dtype=np.int64)
            for c in range(factor_counts[j]):
                # Intervene on the sensitive attribute.
                intervened_factors = np.copy(original_factors)
                intervened_factors[:, j] = c
                # Obtain the batched observations.
                observations = ground_truth_data.sample_observations_from_factors(
                    intervened_factors, random_state)
                representations = utils.obtain_representation(
                    observations, representation_function, batch_size)
                # Get the predictions.
                predictions = model.predict(np.transpose(representations))
                # Update the counts.
                counts[:, c] = np.bincount(predictions,
                                           minlength=factor_counts[i])
            mean_fairness[i, j], max_fairness[i,
                                              j] = inter_group_fairness(counts)

    # Report the scores.
    scores.update(compute_scores_dict(mean_fairness, "mean_fairness"))
    scores.update(compute_scores_dict(max_fairness, "max_fairness"))
    return scores
def compute_strong_downstream_task(ground_truth_data,
                                   representation_function,
                                   random_state,
                                   artifact_dir=None,
                                   num_train=gin.REQUIRED,
                                   num_test=gin.REQUIRED,
                                   n_experiment=gin.REQUIRED):
  """Computes loss of downstream task.

  This task is about strong generalization under covariate shifts. We first
  perform an intervention fixing a value for a factor in the whole training set.
  Then, we train a GBT classifier, and at test time, we consider all other
  values for that factor. We repeat the experiment n_experiment times, to ensure
  robustness.

  Args:
    ground_truth_data: GroundTruthData to be sampled from.
    representation_function: Function that takes observations as input and
      outputs a dim_representation sized representation for each observation.
    random_state: Numpy random state used for randomness.
    artifact_dir: Optional path to directory where artifacts can be saved.
    num_train: Number of points used for training.
    num_test: Number of points used for testing.
    n_experiment: Number of repetitions of the experiment.

  Returns:
    Dictionary with scores.
  """
  del artifact_dir
  scores = {}
  for train_size in num_train:
    # sample factors
    factors_train = ground_truth_data.sample_factors(train_size, random_state)
    factors_test = ground_truth_data.sample_factors(num_test, random_state)
    # obtain_observations without intervention
    x_train = ground_truth_data.sample_observations_from_factors(
        factors_train, random_state)
    x_test = ground_truth_data.sample_observations_from_factors(
        factors_test, random_state)
    mus_train = representation_function(x_train)
    mus_test = representation_function(x_test)
    # train predictor on data without interbention
    predictor_model = utils.make_predictor_fn()
    y_train = np.transpose(factors_train)
    y_test = np.transpose(factors_test)
    train_err, test_err = _compute_loss(
        mus_train, y_train, mus_test,
        y_test, predictor_model)

    # train predictor on data with interventions
    train_err_int, test_err_int = _compute_loss_intervene(
        factors_train, factors_test, predictor_model, ground_truth_data,
        representation_function, random_state, n_experiment)

    size_string = str(train_size)
    scores[size_string +
           ":mean_train_accuracy"] = np.mean(train_err)
    scores[size_string +
           ":mean_test_accuracy"] = np.mean(test_err)
    scores[size_string +
           ":mean_strong_train_accuracy"] = np.mean(train_err_int)
    scores[size_string +
           ":mean_strong_test_accuracy"] = np.mean(test_err_int)
    scores[size_string + ":strong_generalization_gap"] = 1. - (
        scores[size_string + ":mean_strong_test_accuracy"] /
        scores[size_string + ":mean_test_accuracy"])
  return scores
Пример #4
0
def compute_downstream_regression_on_representations(
        ground_truth_data,
        representation_function,
        random_state,
        holdout_dataset_name=gin.REQUIRED,
        artifact_dir=None,
        num_train=gin.REQUIRED,
        num_test=gin.REQUIRED,
        num_holdout=gin.REQUIRED,
        batch_size=16):
    """Computes loss of downstream task on representations.

  Args:
    ground_truth_data: GroundTruthData to be sampled from.
    representation_function: Function that takes observations as input and
      outputs a dim_representation sized representation for each observation.
    random_state: Numpy random state used for randomness.
    artifact_dir: Optional path to directory where artifacts can be saved.
    num_train: Number of points used for training.
    num_test: Number of points used for testing.
    batch_size: Batch size for sampling.

  Returns:
    Dictionary with scores.
  """
    del artifact_dir
    ground_truth_train_data, ground_truth_test_data = ground_truth_data
    ground_truth_holdout_data = named_data.get_named_ground_truth_data(
        holdout_dataset_name)
    scores = {}
    for train_size in num_train:
        mus_train, ys_train = utils.generate_batch_label_code(
            ground_truth_train_data, representation_function, train_size,
            random_state, batch_size)
        mus_test, ys_test = utils.generate_batch_label_code(
            ground_truth_test_data, representation_function, num_test,
            random_state, batch_size)
        mus_holdout, ys_holdout = utils.generate_batch_label_code(
            ground_truth_holdout_data, representation_function, num_holdout,
            random_state, batch_size)

        predictor_model = utils.make_predictor_fn()

        train_err, test_err, holdout_err, random_normal_err, random_uniform_err = \
          _compute_mse_loss(
            np.transpose(mus_train), ys_train, np.transpose(mus_test),
            ys_test, np.transpose(mus_holdout), ys_holdout, predictor_model)
        size_string = str(train_size)
        scores[size_string + ":mean_train_mse"] = np.mean(train_err)
        scores[size_string + ":mean_test_mse"] = np.mean(test_err)
        scores[size_string + ":mean_holdout_mse"] = np.mean(holdout_err)
        scores[size_string +
               ":mean_random_normal_mse"] = np.mean(random_normal_err)
        scores[size_string +
               ":mean_random_uniform_mse"] = np.mean(random_uniform_err)
        scores[size_string + ":min_train_mse"] = np.min(train_err)
        scores[size_string + ":min_test_mse"] = np.min(test_err)
        scores[size_string + ":min_holdout_mse"] = np.min(holdout_err)
        scores[size_string +
               ":min_random_normal_mse"] = np.min(random_normal_err)
        scores[size_string +
               ":min_random_uniform_mse"] = np.min(random_uniform_err)
        for i in range(len(train_err)):
            scores[size_string +
                   ":train_mse_factor_{}".format(i)] = train_err[i]
            scores[size_string + ":test_mse_factor_{}".format(i)] = test_err[i]
            scores[size_string +
                   ":holdout_mse_factor_{}".format(i)] = holdout_err[i]
            scores[size_string + ":random_normal_mse_factor_{}".format(
                i)] = random_normal_err[i]
            scores[size_string + ":random_uniform_mse_factor_{}".format(
                i)] = random_uniform_err[i]
    return scores
Пример #5
0
def compute_reduced_downstream_task(ground_truth_data,
                                    representation_function,
                                    random_state,
                                    artifact_dir=None,
                                    num_factors_to_remove=gin.REQUIRED,
                                    num_train=gin.REQUIRED,
                                    num_test=gin.REQUIRED,
                                    batch_size=16):
  """Computes loss of a reduced downstream task.

  Measure the information leakage in each latent component after removing the
  k ("factors_to_remove") most informative features for the prediction task.

  Args:
    ground_truth_data: GroundTruthData to be sampled from.
    representation_function: Function that takes observations as input and
      outputs a dim_representation sized representation for each observation.
    random_state: Numpy random state used for randomness.
    artifact_dir: Optional path to directory where artifacts can be saved.
    num_factors_to_remove: Number of factors to remove from the latent
      representation.
    num_train: Number of points used for training.
    num_test: Number of points used for testing.
    batch_size: Batch size for sampling.

  Returns:
    Dictionary with scores.
  """
  del artifact_dir
  scores = {}
  # Loop on different sizes of the training 'batch', as specified with gin.
  for train_size in num_train:
    size_string = str(train_size)
    mus_train, ys_train = utils.generate_batch_factor_code(
        ground_truth_data, representation_function, train_size, random_state,
        batch_size)
    mus_test, ys_test = utils.generate_batch_factor_code(
        ground_truth_data, representation_function, num_test, random_state,
        batch_size)
    # Create variables for aggregated scores.
    reduced_factor_train_scores = []
    other_factors_train_scores = []
    reduced_factor_test_scores = []
    other_factors_test_scores = []
    # Compute the reduced representation and test it for each factor of
    # variation.
    for factor_of_interest in range(ground_truth_data.num_factors):
      # Copy the training data and eliminate the k most informative factors.
      reduced_mus_train = mus_train.copy()
      reduced_mus_test = mus_test.copy()
      for _ in range(num_factors_to_remove):
        reduced_mus_train, reduced_mus_test =\
          compute_reduced_representation(reduced_mus_train, ys_train,
                                         reduced_mus_test, ys_test,
                                         factor_of_interest)
      predictor_model = utils.make_predictor_fn()
      train_acc, test_acc = compute_predictive_accuracy(
          np.transpose(reduced_mus_train), ys_train,
          np.transpose(reduced_mus_test), ys_test, predictor_model)
      # Save scores for reduced factor.
      scores[size_string +
             ":reduced_factor_{}:mean_train_accuracy_reduced_factor".format(
                 factor_of_interest)] = train_acc[factor_of_interest]
      scores[size_string +
             ":reduced_factor_{}:mean_test_accuracy_reduced_factor".format(
                 factor_of_interest)] = test_acc[factor_of_interest]
      reduced_factor_train_scores.append(train_acc[factor_of_interest])
      reduced_factor_test_scores.append(test_acc[factor_of_interest])

      # Save the scores (accuracies) in the score dictionary.
      local_other_factors_train_scores = []
      local_other_factors_test_scores = []
      for i in range(len(train_acc)):
        scores[size_string +
               ":reduced_factor_{}:mean_train_accuracy_factor_{}".format(
                   factor_of_interest, i)] = train_acc[i]
        scores[size_string +
               ":reduced_factor_{}:mean_test_accuracy_factor_{}".format(
                   factor_of_interest, i)] = test_acc[i]
        if i != factor_of_interest:
          local_other_factors_train_scores.append(train_acc[i])
          local_other_factors_test_scores.append(test_acc[i])
      # Save mean score for non-reduced factors.
      scores[size_string +
             ":reduced_factor_{}:mean_train_accuracy_non_reduced_factor".format(
                 factor_of_interest)] = np.mean(
                     local_other_factors_train_scores)
      scores[size_string +
             ":reduced_factor_{}:mean_test_accuracy_non_reduced_factor".format(
                 factor_of_interest)] = np.mean(local_other_factors_test_scores)
      other_factors_train_scores.append(
          np.mean(local_other_factors_train_scores))
      other_factors_test_scores.append(np.mean(local_other_factors_test_scores))

    # Compute the aggregate scores.
    scores[size_string + ":mean_train_accuracy_reduced_factor"] = np.mean(
        reduced_factor_train_scores)
    scores[size_string + ":mean_test_accuracy_reduced_factor"] = np.mean(
        reduced_factor_test_scores)
    scores[size_string + ":mean_train_accuracy_other_factors"] = np.mean(
        other_factors_train_scores)
    scores[size_string + ":mean_test_accuracy_other_factors"] = np.mean(
        other_factors_test_scores)
  return scores