def test_calls_inner_query(self):
        t = tf.constant([1, 2], dtype=tf.float32)
        record = [t, t]
        sample_size = 2
        sample = [record] * sample_size

        # Mock inner query to check that the methods get called.
        in_q = ddg_sum_query(l2_norm_bound=self.DEFAULT_L2_NORM_BOUND,
                             local_scale=0.0)
        in_q.initial_sample_state = mock.MagicMock(
            wraps=in_q.initial_sample_state)
        in_q.initial_global_state = mock.MagicMock(
            wraps=in_q.initial_global_state)
        in_q.derive_sample_params = mock.MagicMock(
            wraps=in_q.derive_sample_params)
        in_q.preprocess_record = mock.MagicMock(wraps=in_q.preprocess_record)
        in_q.get_noised_result = mock.MagicMock(wraps=in_q.get_noised_result)

        comp_query = compression_query.CompressionSumQuery(
            quantization_params=self.DEFAULT_QUANTIZATION_PARAMS,
            inner_query=in_q,
            record_template=record)

        query_result, _ = test_utils.run_query(comp_query, sample)
        result = self.evaluate(query_result)
        expected = self.evaluate([t * sample_size, t * sample_size])
        self.assertAllClose(result, expected, atol=0)

        # Check calls
        self.assertEqual(in_q.initial_sample_state.call_count, 1)
        self.assertEqual(in_q.initial_global_state.call_count, 1)
        self.assertEqual(in_q.derive_sample_params.call_count, 1)
        self.assertEqual(in_q.preprocess_record.call_count, sample_size)
        self.assertEqual(in_q.get_noised_result.call_count, 1)
Beispiel #2
0
def build_compressed_dp_query(mechanism, clip, padded_dim, gamma, stddev, beta,
                              client_template):
  """Construct a DPQuery with quantization operations."""
  # Scaling up the noise for the quantized query.
  scaled_stddev = np.ceil(stddev / gamma)
  # Compute the (scaled) inflated norm bound after random Hadamard transform.
  sq_l2_norm_bound = accounting_utils.compute_l2_sensitivy_squared(
      l2_clip_norm=clip, gamma=gamma, beta=beta, dimension=padded_dim)
  # Add some norm leeway to peacefully allow for numerical/precision errors.
  scaled_l2_norm_bound = (np.sqrt(sq_l2_norm_bound) + 1e-4) / gamma

  discrete_query = dp_query_factory(
      mechanism=mechanism,
      noise_stddev=scaled_stddev,
      quantized_l2_norm_bound=scaled_l2_norm_bound)

  quantize_scale = 1.0 / gamma
  beta = beta or 0
  conditional = beta > 0
  logging.info('Conditional rounding set to %s (beta = %f)', conditional, beta)

  quantization_params = compression_query.ScaledQuantizationParams(
      stochastic=True,
      conditional=conditional,
      l2_norm_bound=clip,
      beta=beta,
      quantize_scale=quantize_scale)

  # Wrap the discrete query with compression operations.
  compressed_query = compression_query.CompressionSumQuery(
      quantization_params=quantization_params,
      inner_query=discrete_query,
      record_template=client_template)

  return compressed_query
Beispiel #3
0
def build_quantized_dp_query(mechanism, c, padded_d, gamma, stddev, beta,
                             client_template):
  """Construct a DPQuery with quantization operations."""
  # The implementation adds noise on scaled records, and takes integer scales
  gamma, stddev, padded_d, c, beta = map(np.float64,
                                         [gamma, stddev, padded_d, c, beta])
  # Take ceil as DGauss impl only supports integer scales for now.
  scaled_stddev = np.ceil(stddev / gamma)

  # L2 norm bound: The DPQuery implementations expect scaled norm bounds.
  sq_l2_norm_bound = compute_l2_sensitivy_squared(
      l2_clip_norm=c, gamma=gamma, beta=beta, dimension=padded_d)
  # Add some norm leeway to peacefully allow for numerical/precision errors.
  scaled_l2_norm_bound = (np.sqrt(sq_l2_norm_bound) + 1e-4) / gamma

  # Construct DPQuery
  discrete_query = get_dp_query(
      mechanism, l2_norm_bound=scaled_l2_norm_bound, noise_scale=scaled_stddev)

  # Wrap the discrete DPQuery with CompressionSumQuery.
  quantize_scale = 1.0 / gamma
  quantization_params = compression_query.ScaledQuantizationParams(
      stochastic=True,
      conditional=True,
      l2_norm_bound=c,
      beta=beta,
      quantize_scale=quantize_scale)

  compression_dp_query = compression_query.CompressionSumQuery(
      quantization_params=quantization_params,
      inner_query=discrete_query,
      record_template=client_template)

  return compression_dp_query
    def test_inner_query_no_noise_sum(self, sample_size):
        t1 = tf.constant([1, 2], dtype=tf.float32)
        t2 = tf.constant([3], dtype=tf.float32)
        record = [t1, t2]
        sample = [record] * sample_size

        comp_query = compression_query.CompressionSumQuery(
            quantization_params=self.DEFAULT_QUANTIZATION_PARAMS,
            inner_query=self.DEFAULT_INNER_QUERY,
            record_template=record)

        query_result, _ = test_utils.run_query(comp_query, sample)
        result = self.evaluate(query_result)
        expected = self.evaluate([t1 * sample_size, t2 * sample_size])
        self.assertAllClose(result, expected, atol=0)
    def test_inner_query_no_noise_dtypes(self, dtype):
        t1 = tf.constant([-2, 4], dtype=dtype)
        t2 = tf.constant([-4, 2], dtype=dtype)
        record = [t1, t2]
        sample = [record]

        # Use a noiseless discrete sum query.
        comp_query = compression_query.CompressionSumQuery(
            quantization_params=self.DEFAULT_QUANTIZATION_PARAMS,
            inner_query=self.DEFAULT_INNER_QUERY,
            record_template=record)

        query_result, _ = test_utils.run_query(comp_query, sample)
        result = self.evaluate(query_result)
        expected = self.evaluate([t1, t2])

        self.assertAllClose(result, expected, atol=0)
    def test_inner_query_no_noise_sum_nested(self, sample_size):
        t1 = tf.constant([1, 0], dtype=tf.int32)
        t2 = tf.constant([1, 1, 1], dtype=tf.int32)
        t3 = tf.constant([1], dtype=tf.int32)
        t4 = tf.constant([[1, 1], [1, 1]], dtype=tf.int32)
        record = [t1, dict(a=t2, b=[t3, (t4, t1)])]
        sample = [record] * sample_size

        compress_query = compression_query.CompressionSumQuery(
            quantization_params=self.DEFAULT_QUANTIZATION_PARAMS,
            inner_query=self.DEFAULT_INNER_QUERY,
            record_template=record)

        query_result, _ = test_utils.run_query(compress_query, sample)
        result = self.evaluate(query_result)

        s = sample_size
        expected = [t1 * s, dict(a=t2 * s, b=[t3 * s, (t4 * s, t1 * s)])]
        # Use `assertAllClose` to compare structures
        self.assertAllClose(result, expected, atol=0)