2019-01-14 17:02:14 -07:00
|
|
|
# Copyright 2018, The TensorFlow Authors.
|
|
|
|
#
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
# You may obtain a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
# limitations under the License.
|
2019-01-23 14:51:58 -07:00
|
|
|
"""Implements DPQuery interface for no privacy average queries."""
|
2019-01-14 17:02:14 -07:00
|
|
|
|
|
|
|
from __future__ import absolute_import
|
|
|
|
from __future__ import division
|
|
|
|
from __future__ import print_function
|
|
|
|
|
2019-03-18 12:51:21 -06:00
|
|
|
from distutils.version import LooseVersion
|
2019-01-14 17:02:14 -07:00
|
|
|
import tensorflow as tf
|
|
|
|
|
2019-03-25 11:20:41 -06:00
|
|
|
from privacy.dp_query import dp_query
|
2019-01-14 17:02:14 -07:00
|
|
|
|
2019-03-18 12:51:21 -06:00
|
|
|
if LooseVersion(tf.__version__) < LooseVersion('2.0.0'):
|
|
|
|
nest = tf.contrib.framework.nest
|
|
|
|
else:
|
|
|
|
nest = tf.nest
|
2019-01-14 17:02:14 -07:00
|
|
|
|
|
|
|
|
2019-05-13 12:28:33 -06:00
|
|
|
class NoPrivacySumQuery(dp_query.SumAggregationDPQuery):
|
2019-01-23 14:51:58 -07:00
|
|
|
"""Implements DPQuery interface for a sum query with no privacy.
|
2019-01-14 17:02:14 -07:00
|
|
|
|
|
|
|
Accumulates vectors without clipping or adding noise.
|
|
|
|
"""
|
|
|
|
|
2019-01-23 14:51:58 -07:00
|
|
|
def get_noised_result(self, sample_state, global_state):
|
2019-01-14 17:02:14 -07:00
|
|
|
"""See base class."""
|
|
|
|
return sample_state, global_state
|
|
|
|
|
|
|
|
|
2019-05-13 12:28:33 -06:00
|
|
|
class NoPrivacyAverageQuery(dp_query.SumAggregationDPQuery):
|
2019-01-23 14:51:58 -07:00
|
|
|
"""Implements DPQuery interface for an average query with no privacy.
|
2019-01-14 17:02:14 -07:00
|
|
|
|
|
|
|
Accumulates vectors and normalizes by the total number of accumulated vectors.
|
|
|
|
"""
|
|
|
|
|
2019-05-13 12:28:33 -06:00
|
|
|
def initial_sample_state(self, global_state, template):
|
2019-01-14 17:02:14 -07:00
|
|
|
"""See base class."""
|
2019-05-13 12:28:33 -06:00
|
|
|
return (
|
|
|
|
super(NoPrivacyAverageQuery, self).initial_sample_state(
|
|
|
|
global_state, template),
|
|
|
|
tf.constant(0.0))
|
2019-01-14 17:02:14 -07:00
|
|
|
|
2019-05-13 12:28:33 -06:00
|
|
|
def preprocess_record(self, params, record, weight=1):
|
|
|
|
"""Multiplies record by weight."""
|
|
|
|
weighted_record = nest.map_structure(lambda t: weight * t, record)
|
2019-05-24 16:28:16 -06:00
|
|
|
return (weighted_record, tf.cast(weight, tf.float32))
|
2019-01-14 17:02:14 -07:00
|
|
|
|
2019-01-18 18:25:41 -07:00
|
|
|
def accumulate_record(self, params, sample_state, record, weight=1):
|
2019-05-13 12:28:33 -06:00
|
|
|
"""Accumulates record, multiplying by weight."""
|
|
|
|
weighted_record = nest.map_structure(lambda t: weight * t, record)
|
|
|
|
return self.accumulate_preprocessed_record(
|
2019-05-24 16:28:16 -06:00
|
|
|
sample_state, (weighted_record, tf.cast(weight, tf.float32)))
|
2019-01-14 17:02:14 -07:00
|
|
|
|
2019-01-23 14:51:58 -07:00
|
|
|
def get_noised_result(self, sample_state, global_state):
|
2019-01-14 17:02:14 -07:00
|
|
|
"""See base class."""
|
2019-05-13 12:28:33 -06:00
|
|
|
sum_state, denominator = sample_state
|
2019-01-14 17:02:14 -07:00
|
|
|
|
2019-05-13 12:28:33 -06:00
|
|
|
return nest.map_structure(
|
2019-05-24 16:28:16 -06:00
|
|
|
lambda t: tf.truediv(t, denominator), sum_state), global_state
|