<jupyter_start><jupyter_text>**Introduction to the Federated Core**The Federated Core (FC) is a set of lower-level interfaces that serve as the foundation for the `tff.learning` API. However, these interfaces are not limited to learning. In fact, they can be used for analytics and many other computations over distributed data.At a high-level, the federated core is a development environment that enables compactly expressed program logic to combine TensorFlow code with distributed communication operators (such as distributed sums and broadcasts). The goal is to give researchers and practitioners expliict control over the distributed communication in their systems, without requiring system implementation details (such as specifying point-to-point network message exchanges).One key point is that TFF is designed for privacy-preservation. Therefore, it allows explicit control over where data resides, to prevent unwanted accumulation of data at the centralized server location.  **Federated data**A key concept in TFF is "federated data", which refers to a collection of data items hosted across a group of devices in a distributed system (eg. client datasets, or the server model weights). We model the entire collection of data items across all devices as a single *federated value*.For example, suppose we have client devices that each have a float representing the temperature of a sensor. We could represent it as a *federated float* by<jupyter_code>federated_float_on_clients = tff.FederatedType(tf.float32, tff.CLIENTS)<jupyter_output><empty_output><jupyter_text>Federated types are specified by a type `T` of its member constituents (eg. `tf.float32`) and a group `G` of devices. We will focus on the cases where `G` is either `tff.CLIENTS` or `tff.SERVER`. Such a federated type is represented as `{T}@G`, as shown below.<jupyter_code>str(federated_float_on_clients)<jupyter_output><empty_output><jupyter_text>Why do we care so much about placements? A key goal of TFF is to enable writing code that could be deployed on a real distributed system. This means that it is vital to reason about which subsets of devices execute which code, and where different pieces of data reside.**TFF focuses on three things: data, where the data is placed, and how the data is being transformed**. The first two are encapsulated in federated types, while the last is encapsulated in federated computations.  **Federated computations**TFF is a strongly-typed functional programming environment whose basic units are **federated computations. These are pieces of logic that accept federated values as input, and return federated values as output.**For example, suppose we wanted to average the temperatures on our client sensors. We could define the following (using our federated float):<jupyter_code>@tff.federated_computation(tff.FederatedType(tf.float32, tff.CLIENTS))
def get_average_temperature(client_temperatures):
  return tff.federated_mean(client_temperatures)<jupyter_output><empty_output><jupyter_text>You might ask, how is this different from the `tf.function` decorator in TensorFlow? The key answer is that the code generated by `tff.federated_computation` is neither TensorFlow nor Python code; It is a specification of a distributed system in an internal platform-independent **glue language**.While this may sound complicated, you can think of TFF computations as functions with well-defined type signatures. These type signatures can be directly queried.<jupyter_code>str(get_average_temperature.type_signature)<jupyter_output><empty_output><jupyter_text>This `tff.federated_computation` accepts arguments of federated type `{float32}@CLIENTS`, and returns values of federated type `{float32}@SERVER`. Federated computations may also go from server to client, from client to client, or from server to server. Federated computations can also be composed like normal functions, as long as their type signatures match up.To support development, TFF allows you to invoke a `tff.federated_computation` as a Python function. For example, we can call<jupyter_code>get_average_temperature([68.5, 70.3, 69.8])<jupyter_output><empty_output><jupyter_text>**Non-eager computations and TensorFlow** There are two key restrictions to be aware of. 1.   When the Python interpreter encounters a `tff.federated_computation` decorator, the function is traced once and serialized for future use. Due to the decentralized nature of Federated Learning, this future usage may occur elsewhere, such as a remote execution environment. Therefore, TFF computations are fundamentally *non-eager*. This behavior is somewhat analogous to that of the `tf.function` decorator in TensorFlow.2. A federated computation can only consist of federated operators (such as `tff.federated_mean`), they cannot contain TensorFlow operations. TensorFlow code must be confined to blocks decorated with `tff.tf_computation`. Most ordinary TensorFlow code can be directly decorated.<jupyter_code>@tff.tf_computation(tf.float32)
def add_half(x):
  return tf.add(x, 0.5)<jupyter_output><empty_output><jupyter_text>These also have type signatures, but *without placements*. For example, we can call<jupyter_code>str(add_half.type_signature)<jupyter_output><empty_output><jupyter_text>We can use `tff.tf_computation` blocks in federated computations by specifying placements. Let's create a function that adds half, but only to federated floats at the clients. We can do this by using `tff.federated_map`, which applies a given `tff.tf_computation`, while preserving the placement.<jupyter_code>@tff.federated_computation(tff.FederatedType(tf.float32, tff.CLIENTS))
def add_half_on_clients(x):
  return tff.federated_map(add_half, x)<jupyter_output><empty_output><jupyter_text>This function is almost identical to `add_half`, except that it only accepts values with placement at `tff.CLIENTS`, and returns values with the same placement. We can see this in its type signature:<jupyter_code>str(add_half_on_clients.type_signature)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.060872449825841765, 'fraction_numerical': 0.0044783546193398575, 'mean_word_length': 6.247596153846154, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '187297', 'license': 'Apache-2.0', 'n_tokens_mistral': 1630, 'n_tokens_neox': 1542, 'n_words': 729, 'path': 'Building Your Own Federated Learning Algorithm/Introduction to Federated Core.ipynb', 'repo_name': 'DeepaliKushwaha/TensorFlow-Federated', 'size': '6029'}