示例#1
0
def _create_complex_computation():
    tensor_type = computation_types.TensorType(tf.int32)
    compiled = building_block_factory.create_compiled_identity(
        tensor_type, 'a')
    federated_type = computation_types.FederatedType(tf.int32,
                                                     placements.SERVER)
    arg_ref = building_blocks.Reference('arg', federated_type)
    bindings = []
    results = []

    def _bind(name, value):
        bindings.append((name, value))
        return building_blocks.Reference(name, value.type_signature)

    for i in range(2):
        called_federated_broadcast = building_block_factory.create_federated_broadcast(
            arg_ref)
        called_federated_map = building_block_factory.create_federated_map(
            compiled, _bind(f'broadcast_{i}', called_federated_broadcast))
        called_federated_mean = building_block_factory.create_federated_mean(
            _bind(f'map_{i}', called_federated_map), None)
        results.append(_bind(f'mean_{i}', called_federated_mean))
    result = building_blocks.Struct(results)
    block = building_blocks.Block(bindings, result)
    return building_blocks.Lambda('arg', tf.int32, block)
示例#2
0
def create_whimsy_called_federated_mean(value_type=tf.float32,
                                        weights_type=None):
    fed_value_type = computation_types.at_clients(value_type)
    values = building_blocks.Data('values', fed_value_type)
    if weights_type is not None:
        fed_weights_type = computation_types.at_clients(weights_type)
        weights = building_blocks.Data('weights', fed_weights_type)
    else:
        weights = None
    return building_block_factory.create_federated_mean(values, weights)
示例#3
0
    def federated_mean(self, value, weight):
        """Implements `federated_mean` as defined in `api/intrinsics.py`.

    Args:
      value: As in `api/intrinsics.py`.
      weight: As in `api/intrinsics.py`.

    Returns:
      As in `api/intrinsics.py`.

    Raises:
      TypeError: As in `api/intrinsics.py`.
    """
        # TODO(b/113112108): Possibly relax the constraints on numeric types, and
        # inject implicit casts where appropriate. For instance, we might want to
        # allow `tf.int32` values as the input, and automatically cast them to
        # `tf.float321 before invoking the average, thus producing a floating-point
        # result.

        # TODO(b/120439632): Possibly allow the weight to be either structured or
        # non-scalar, e.g., for the case of averaging a convolutional layer, when
        # we would want to use a different weight for every filter, and where it
        # might be cumbersome for users to have to manually slice and assemble a
        # variable.

        value = value_impl.to_value(value, None, self._context_stack)
        value_utils.check_federated_value_placement(value, placements.CLIENTS,
                                                    'value to be averaged')
        if not type_utils.is_average_compatible(value.type_signature):
            raise TypeError(
                'The value type {} is not compatible with the average operator.'
                .format(value.type_signature))

        if weight is not None:
            weight = value_impl.to_value(weight, None, self._context_stack)
            value_utils.check_federated_value_placement(
                weight, placements.CLIENTS, 'weight to use in averaging')
            py_typecheck.check_type(weight.type_signature.member,
                                    computation_types.TensorType)
            if weight.type_signature.member.shape.ndims != 0:
                raise TypeError(
                    'The weight type {} is not a federated scalar.'.format(
                        weight.type_signature))
            if not (weight.type_signature.member.dtype.is_integer
                    or weight.type_signature.member.dtype.is_floating):
                raise TypeError(
                    'The weight type {} is not a federated integer or floating-point '
                    'tensor.'.format(weight.type_signature))

        value = value_impl.ValueImpl.get_comp(value)
        if weight is not None:
            weight = value_impl.ValueImpl.get_comp(weight)
        comp = building_block_factory.create_federated_mean(value, weight)
        return value_impl.ValueImpl(comp, self._context_stack)
示例#4
0
def _create_complex_computation():
    compiled = building_block_factory.create_compiled_identity(tf.int32, 'a')
    federated_type = computation_types.FederatedType(tf.int32,
                                                     placements.SERVER)
    ref = building_blocks.Reference('b', federated_type)
    called_federated_broadcast = building_block_factory.create_federated_broadcast(
        ref)
    called_federated_map = building_block_factory.create_federated_map(
        compiled, called_federated_broadcast)
    called_federated_mean = building_block_factory.create_federated_mean(
        called_federated_map, None)
    tup = building_blocks.Tuple([called_federated_mean, called_federated_mean])
    return building_blocks.Lambda('b', tf.int32, tup)
示例#5
0
def federated_mean(value, weight=None):
    """Computes a `tff.SERVER` mean of `value` placed on `tff.CLIENTS`.

  For values `v_1, ..., v_k`, and weights `w_1, ..., w_k`, this means
  `sum_{i=1}^k (w_i * v_i) / sum_{i=1}^k w_i`.

  Args:
    value: The value of which the mean is to be computed. Must be of a TFF
      federated type placed at `tff.CLIENTS`. The value may be structured, e.g.,
      its member constituents can be named tuples. The tensor types that the
      value is composed of must be floating-point or complex.
    weight: An optional weight, a TFF federated integer or floating-point tensor
      value, also placed at `tff.CLIENTS`.

  Returns:
    A representation at the `tff.SERVER` of the mean of the member constituents
    of `value`, optionally weighted with `weight` if specified (otherwise, the
    member constituents contributed by all clients are equally weighted).

  Raises:
    TypeError: If `value` is not a federated TFF value placed at `tff.CLIENTS`,
      or if `weight` is not a federated integer or a floating-point tensor with
      the matching placement.
  """
    # TODO(b/113112108): Possibly relax the constraints on numeric types, and
    # inject implicit casts where appropriate. For instance, we might want to
    # allow `tf.int32` values as the input, and automatically cast them to
    # `tf.float321 before invoking the average, thus producing a floating-point
    # result.

    # TODO(b/120439632): Possibly allow the weight to be either structured or
    # non-scalar, e.g., for the case of averaging a convolutional layer, when
    # we would want to use a different weight for every filter, and where it
    # might be cumbersome for users to have to manually slice and assemble a
    # variable.

    value = value_impl.to_value(value, None)
    value = value_utils.ensure_federated_value(value, placements.CLIENTS,
                                               'value to be averaged')
    if not type_analysis.is_average_compatible(value.type_signature):
        raise TypeError(
            'The value type {} is not compatible with the average operator.'.
            format(value.type_signature))

    if weight is not None:
        weight = value_impl.to_value(weight, None)
        weight = value_utils.ensure_federated_value(
            weight, placements.CLIENTS, 'weight to use in averaging')
        py_typecheck.check_type(weight.type_signature.member,
                                computation_types.TensorType)
        if weight.type_signature.member.shape.ndims != 0:
            raise TypeError(
                'The weight type {} is not a federated scalar.'.format(
                    weight.type_signature))
        if not (weight.type_signature.member.dtype.is_integer
                or weight.type_signature.member.dtype.is_floating):
            raise TypeError(
                'The weight type {} is not a federated integer or floating-point '
                'tensor.'.format(weight.type_signature))

    weight_comp = None if weight is None else weight.comp
    comp = building_block_factory.create_federated_mean(
        value.comp, weight_comp)
    comp = _bind_comp_as_reference(comp)
    return value_impl.Value(comp)