Questa pagina descrive come utilizzare le API di apprendimento federato fornite dalla personalizzazione sul dispositivo per addestrare un modello con una procedura di apprendimento basata su medie federate e rumore gaussiano fisso.
Prima di iniziare
Prima di iniziare, completa i seguenti passaggi sul dispositivo di test:
Assicurati che il modulo OnDevicePersonalization sia installato. Il modulo è diventato disponibile come aggiornamento automatico ad aprile 2024.
# List the modules installed on the device adb shell pm list packages --apex-only --show-versioncode
Assicurati che il seguente modulo sia elencato con un codice di versione pari o superiore a 341717000:
package:com.google.android.ondevicepersonalization versionCode:341717000
Se il modulo non è presente nell'elenco, vai a Impostazioni > Sicurezza e privacy > Aggiornamenti > Aggiornamento di sistema Google Play per assicurarti che il dispositivo sia aggiornato. Seleziona Aggiorna se necessario.
Abilita tutte le nuove funzionalità relative all'apprendimento federato.
# Enable On-Device Personalization apk. adb shell device_config put on_device_personalization global_kill_switch false # Enable On-Device Personalization APIs. adb shell device_config put on_device_personalization enable_ondevicepersonalization_apis true # Enable On-Device Personalization overriding. adb shell device_config put on_device_personalization enable_personalization_status_override true adb shell device_config put on_device_personalization personalization_status_override_value true # Enable Federated Compute apk. adb shell device_config put on_device_personalization federated_compute_kill_switch false
Crea un'attività di apprendimento federato
I numeri nel diagramma sono spiegati in maggiore dettaglio nei seguenti otto passaggi.
Configura un server di calcolo federato
L'apprendimento federato è un'operazione MapReduce eseguita su Federated Compute Server (il riduttore) e su un insieme di client (i mappatori). Il server Federated Compute gestisce i metadati e le informazioni sui modelli in esecuzione di ogni attività di Federated Learning. A livello generale:
- Uno sviluppatore di Federated Learning crea una nuova attività e carica sul server sia i metadati di esecuzione dell'attività sia le informazioni sul modello.
- Quando un client di calcolo federato avvia una nuova richiesta di assegnazione di attività al server, il server ne controlla l'idoneità e restituisce le informazioni sulle attività idonee.
- Una volta che un client Federated Compute termina i calcoli locali, invia questi risultati al server. Il server esegue quindi l'aggregazione e l'inserimento del rumore sui risultati del calcolo e applica il risultato al modello finale.
Per saperne di più su questi concetti, consulta:
- Apprendimento federato: machine learning collaborativo senza dati di addestramento centralizzati
- Towards Federated Learning at Scale: System Design (SysML 2019)
ODP utilizza una versione avanzata dell'apprendimento federato, in cui il rumore calibrato (centralizzato) viene applicato agli aggregati prima di applicarlo al modello. L'entità del rumore garantisce che gli aggregati conservino la privacy differenziale.
Passaggio 1: Crea un server di calcolo federato
Segui le istruzioni riportate nel progetto Federated Compute per configurare il tuo Federated Compute Server.
Passaggio 2: Preparare un FunctionalModel salvato
Prepara un file "FunctionalModel" salvato. Puoi utilizzare 'functional_model_from_keras' per convertire un 'Model' in 'FunctionalModel' e 'save_functional_model' per serializzare questo 'FunctionalModel' come 'SavedModel'.
functional_model = tff.learning.models.functional_model_from_keras(keras_model=model)
tff.learning.models.save_functional_model(functional_model, saved_model_path)
Passaggio 3: Crea una configurazione di Federated Compute Server
Prepara un fcp_server_config.json
che includa criteri, configurazione dell'apprendimento federato e configurazione della privacy differenziale. Esempio:
# Identifies the set of client devices that will participate.
population_name: "my_new_population"
# Options you can choose:
# * TRAINING_ONLY: Only one training task will be generated under this
# population.
# * TRAINING_AND_EVAL: One training task and one evaluation task will be
# generated under this population.
# * EVAL_ONLY: Only one evaluation task will be generated under this
# population.
mode: TRAINING_AND_EVAL
policies {
# Policy for sampling on-device examples. It is checked every time a
# device attempts to start a new training.
min_separation_policy {
# The minimum number of rounds before the same client participated.
minimum_separation: 3
}
# Policy for releasing training results to developers. It is checked
# when uploading a new task to the Federated Compute Server.
model_release_policy {
# Server stops training when number of training rounds reaches this
# number.
num_max_training_rounds: 1000
}
}
# Federated learning setups. They are applied inside Task Builder.
federated_learning {
learning_process {
# Use FED_AVG to build federated learning process. Options you can
# choose:
# * FED_AVG: Federated Averaging algorithm
# (https://arxiv.org/abs/2003.00295)
# * FED_SDG: Federated SGD algorithm
# (https://arxiv.org/abs/1602.05629)
type: FED_AVG
# Optimizer used at client side training. Options you can choose:
# * ADAM
# * SGD
client_optimizer: SGD
# Learning rate used at client side training.
client_learning_rate: 0.01
# Optimizer used at server side training. Options you can choose:
# * ADAM
# * SGD
server_optimizer: ADAM
# Learning rate used at server side training.
sever_learning_rate: 1
runtime_config {
# Number of participating devices for each round of training.
report_goal: 2000
}
# List of metrics to be evaluated by the model during training and
# evaluation. Federated Compute Server provides a list of allowed
# metrics.
metrics {
name: "auc-roc"
}
metrics {
name: "binary_accuracy"
}
}
# Whether or not to generate a corresponding evaluation task under the same
# population. If this field isn't set, only one training task is
# generated under this population.
evaluation {
# The task id under the same population of the source training task that
# this evaluation task evaluates.
source_training_task_id: 1
# Decides how checkpoints from the training task are chosen for
# evaluation.
# * every_k_round: the evaluation task randomly picks one checkpoint
# from the past k rounds of training task checkpoints.
# * every_k_hour: the evaluation task randomly picks one checkpoint
# from the past k hours of training task checkpoints.
checkpoint_selector: "every_1_round"
# The traffic of this evaluation task in this population.
evaluation_traffic: 0.1
# Number of participating devices for each round of evaluation.
report_goal: 200
}
}
# Differential Privacy setups. They are applied inside the Task Builder.
differential_privacy {
# The DP aggregation algorithm you want to use. Options you can choose:
# * FIXED_GAUSSIAN: Federated Learning DP-SGD with fixed clipping norm
# described in "Learning Differentially Private Recurrent
# Language Models" (https://arxiv.org/abs/1710.06963).
# * ADAPTIVE_GAUSSIAN: Federated Learning DP-SGD with quantile-based clip
# norm estimation described in "Differentially Private
# Learning with Adaptive Clipping"
# (https://arxiv.org/abs/1905.03871).
# * TREE: DP-FTRL algorithm described in "Practical and Private (Deep)
# Learning without Sampling or Shuffling"
# (https://arxiv.org/abs/2103.00039).
# * ADADPTIVE_TREE: DP-FTRL with adaptive clipping norm descirbed in
# "Differentially Private Learning with Adaptive Clipping"
# (https://arxiv.org/abs/1905.03871).
type: FIXED_GAUSSIAN
# Noise multiplier for the Gaussian noise.
noise_multiplier: 0.1
# The value of the clipping norm.
clip_norm: 0.1
}
Passaggio 4: Invia la configurazione zip al server Federated Compute.
Invia il file ZIP e fcp_server_config.json
al server di calcolo federato.
task_builder_client --task_builder_server='http://{federated_compute_server_endpoint}' --saved_model='saved_model' --task_config='fcp_server_config.json'
L'endpoint di Federated Compute Server è il server che hai configurato nel passaggio 1.
La libreria di operatori integrata LiteRT supporta solo un numero limitato di operatori TensorFlow (Seleziona operatori TensorFlow). L'insieme di operatori supportati può variare in base alle diverse versioni del modulo OnDevicePersonalization. Per garantire la compatibilità, durante la creazione dell'attività viene condotto un processo di verifica dell'operatore all'interno del generatore di attività.
La versione minima supportata del modulo OnDevicePersonalization verrà inclusa nei metadati dell'attività. Queste informazioni sono disponibili nel messaggio informativo del generatore di attività.
I1023 22:16:53.058027 139653371516736 task_builder_client.py:109] Success! Tasks are built, and artifacts are uploaded to the cloud. I1023 22:16:53.058399 139653371516736 task_builder_client.py:112] applied_algorithms { learning_algo: FED_AVG client_optimizer: SGD server_optimizer: SGD dp_aggregator: FIXED_GAUSSIAN } metric_results { accepted_metrics: "binary_accuracy, binary_crossentropy, recall, precision, auc-roc, auc-pr" } dp_hyperparameters { dp_delta: 0.000001 dp_epsilon: 6.4 noise_multiplier: 1.0 dp_clip_norm: 1.0 num_training_rounds: 10000 } I1023 22:16:53.058594 139653371516736 task_builder_client.py:113] training_task { min_client_version: "341912000" } eval_task { min_client_version: "341812000" }
Il server di calcolo federato assegnerà questa attività a tutti i dispositivi dotati di un modulo OnDevicePersonalization con una versione superiore a 341812000.
Se il modello include operazioni non supportate da alcun modulo OnDevicePersonalization, verrà generato un messaggio di errore durante la creazione dell'attività.
common.TaskBuilderException: Cannot build the ClientOnlyPlan: Please contact Google to register these ops: {'L2Loss': 'L2LossOp<CPUDevice, float>'} . Stop building remaining artifacts.
Puoi trovare un elenco dettagliato delle operazioni flessibili supportate in GitHub.
Creare un APK di calcolo federato Android
Per creare un APK di Federated Compute per Android, devi specificare l'endpoint URL del server Federated Compute in AndroidManifest.xml
, a cui si connette il client Federated Compute.
Passaggio 5: Specifica l'endpoint URL di Federated Compute Server
Specifica l'endpoint URL del server di calcolo federato (configurato nel passaggio 1) in AndroidManifest.xml
, a cui si connette il client di calcolo federato.
<!-- Contents of AndroidManifest.xml -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.odpsample" >
<application android:label="OdpSample">
<!-- XML resource that contains other ODP settings. -->
<property android:name="android.ondevicepersonalization.ON_DEVICE_PERSONALIZATION_CONFIG"
android:resource="@xml/OdpSettings"></property>
<!-- The service that ODP will bind to. -->
<service android:name="com.example.odpsample.SampleService"
android:exported="true" android:isolatedProcess="true" />
</application>
</manifest>
Il file di risorse XML specificato nel tag <property>
deve anche dichiarare la classe di servizio in un tag <service>
e specificare l'endpoint URL del server di calcolo federato a cui si connetterà il client di calcolo federato:
<!-- Contents of res/xml/OdpSettings.xml -->
<on-device-personalization>
<!-- Name of the service subclass -->
<service name="com.example.odpsample.SampleService">
<!-- If you want to use federated compute feature to train a model,
specify this tag. -->
<federated-compute-settings url="https://fcpserver.com/" />
</service>
</on-device-personalization>
Passaggio 6: Implementa l'API IsolatedWorker#onTrainingExample
Implementa l'API pubblica On-Device Personalization IsolatedWorker#onTrainingExample
per generare dati di addestramento.
Il codice in esecuzione in IsolatedProcess
non ha accesso diretto alla rete, ai dischi locali o ad altri servizi in esecuzione sul dispositivo. Tuttavia, sono disponibili le seguenti API:
- 'getRemoteData': dati immutabili delle coppie chiave-valore scaricati da backend remoti gestiti dagli sviluppatori, se applicabile.
- 'getLocalData': dati chiave-valore mutabili memorizzati localmente dagli sviluppatori, se applicabili.
- 'UserData': dati utente forniti dalla piattaforma.
- 'getLogReader' - Restituisce un DAO per le tabelle REQUESTS ed EVENTS.
Esempio:
@Override public void onTrainingExample(
@NonNull TrainingExampleInput input,
@NonNull Consumer<TrainingExampleOutput> consumer) {
// Check if the incoming training task is the task we want.
if (input.getPopulationName() == "my_new_population") {
TrainingExampleOutput result = new TrainingExampleOutput.Builder():
RequestLogRecord record = this.getLogReader().getRequestLogRecord(1);
int count = 1;
// Iterate logging event table.
for (ContentValues contentValues: record.rows()) {
Features features = Features.newBuilder()
// Retrieve carrier from user info.
.putFeature("carrier", buildFeature(mUserData.getCarrier()))
// Retrieve features from logging info.
.putFeature("int_feature_1",
buildFeature(contentValues.get("int_feature_1")
result.addTrainingExample(
Example.newBuilder()
.setFeatures(features).build().toByteArray())
.addResumptionToken(
String.format("token%d", count).getBytes()))
.build();
count++;
}
consumer.accept(result.build());
}
}
Passaggio 7: Pianifica un'attività di addestramento ricorrente.
La personalizzazione sul dispositivo fornisce un FederatedComputeScheduler
per consentire agli sviluppatori di pianificare o annullare i job di calcolo federati. Esistono diverse opzioni per chiamarlo tramite IsolatedWorker
, in base a una pianificazione o al completamento di un download asincrono. Di seguito sono riportati alcuni esempi di entrambi.
opzione basata sulla pianificazione. Chiama
FederatedComputeScheduler#schedule
aIsolatedWorker#onExecute
.@Override public void onExecute( @NonNull ExecuteInput input, @NonNull Consumer<ExecuteOutput> consumer ) { if (input != null && input.getAppParams() != null && input.getAppParams().getString("schedule_training") != null) { if (input.getAppParams().getString("schedule_training").isEmpty()) { consumer.accept(null); return; } TrainingInterval interval = new TrainingInterval.Builder() .setMinimumInterval(Duration.ofSeconds(10)) .setSchedulingMode(2) .build(); FederatedComputeScheduler.Params params = new FederatedComputeScheduler .Params(interval); FederatedComputeInput fcInput = new FederatedComputeInput.Builder() .setPopulationName( input.getAppParams().getString("schedule_training")).build(); mFCScheduler.schedule(params, fcInput); ExecuteOutput result = new ExecuteOutput.Builder().build(); consumer.accept(result); } }
Scarica opzione completa. Chiama
FederatedComputeScheduler#schedule
inIsolatedWorker#onDownloadCompleted
se la pianificazione di un'attività di addestramento dipende da dati o processi asincroni.
Convalida
I passaggi seguenti spiegano come verificare se l'attività di apprendimento federato funziona correttamente.
Passaggio 8: Verifica che l'attività di apprendimento federato funzioni correttamente.
A ogni ciclo di aggregazione lato server vengono generati un nuovo checkpoint del modello e un nuovo file delle metriche.
Le metriche si trovano in un file di coppie chiave-valore in formato JSON. Il file viene generato dall'elenco di Metrics
definito nel passaggio 3. Un esempio di file JSON delle metriche rappresentative è il seguente:
{"server/client_work/train/binary_accuracy":0.5384615659713745, "server/client_work/train/binary_crossentropy":0.694046676158905, "server/client_work/train/recall":0.20000000298023224, "server/client_work/train/precision":0.3333333432674408, "server/client_work/train/auc-roc":0.3500000238418579, "server/client_work/train/auc-pr":0.44386863708496094, "server/finalizer/update_non_finite":0.0}
Per ottenere le metriche del modello e monitorare le prestazioni dell'addestramento, puoi utilizzare uno script simile al seguente:
import collections
import json
import matplotlib.pyplot as plt
from google.cloud import storage
# The population_name you set in fcp_server_config.json in Step 3.
POPULATION_NAME = 'my_new_population'
# The Google Cloud storage you set in Step 1.
GCS_BUCKET_NAME = 'fcp-gcs'
NUM_TRAINING_ROUND = 1000
storage_client = storage.Client()
bucket = storage_client.bucket(GCS_BUCKET_NAME)
metrics = collections.defaultdict(list)
for i in range(NUM_TRAINING_ROUND):
blob = bucket.blob('{}/{}/1/{}/s/0/metrics'.format(GCS_BUCKET_NAME, POPULATION_NAME, i+1))
with blob.open("r") as f:
metric = json.loads(f.read())
for metric_name in metric.keys():
metrics[metric_name].append(metric[metric_name])
for metric_name in metrics:
print(metric_name)
plt.plot(metrics[metric_name])
plt.show()
Tieni presente che nel grafico dell'esempio precedente:
- L'asse x indica il numero di round di addestramento.
- L'asse y è il valore dell'AUC-ROC di ogni round.
Addestramento di un modello di classificazione delle immagini sulla personalizzazione sul dispositivo
In questo tutorial, il set di dati EMNIST viene utilizzato per dimostrare come eseguire un'attività di apprendimento federato su ODP.
Passaggio 1: Crea un tff.learning.models.FunctionalModel
def get_image_classification_input_spec():
return (
tf.TensorSpec([None, 28, 28, 1], tf.float32),
tf.TensorSpec([None, 1], tf.int64),
)
def create_and_save_image_classification_functional_model(
model_path: str,
) -> None:
keras_model = emnist_models.create_original_fedavg_cnn_model(
only_digits=True
)
functional_model = tff.learning.models.functional_model_from_keras(
keras_model=keras_model,
input_spec=get_image_classification_input_spec(),
loss_fn=tf.keras.losses.SparseCategoricalCrossentropy(),
)
tff.learning.models.save_functional_model(functional_model, model_path)
- Puoi trovare i dettagli del modello emnist keras in emnist_models.
- TfLite non offre ancora un buon supporto per tf.sparse.SparseTensor o tf.RaggedTensor. Cerca di utilizzare tf.Tensor il più possibile durante la creazione del modello.
- Il Task Builder di ODP sovrascriverà tutte le metriche durante la creazione del processo di apprendimento; non è necessario specificare alcuna metrica. Questo argomento verrà trattato più nel dettaglio nel passaggio 2. Crea la configurazione del generatore di attività.
Sono supportati due tipi di input del modello:
Tipo 1. Una tupla (tensore_caratteristiche, tensore_etichetta).
- Quando crei il modello, input_spec ha il seguente aspetto:
def get_input_spec(): return ( tf.TensorSpec([None, 28, 28, 1], tf.float32), tf.TensorSpec([None, 1], tf.int64), )
- Abbina la precedente alla seguente implementazione dell'API pubblica ODP IsolatedWorker#onTrainingExamples per generare dati di addestramento sul dispositivo:
return tf.train.Example( features=tf.train.Features( feature={ 'x': tf.train.Feature( float_list=tf.train.FloatList(value=[1.0] * 784) ), 'y': tf.train.Feature( int64_list=tf.train.Int64List( value=[1] ) ), } ) ).SerializeToString()
Tipo 2. Un
Tuple(Dict[feature_name, feature_tensor], label_tensor)
- Quando crei il modello, input_spec ha il seguente aspetto:
def get_input_spec() -> ( Tuple[collections.OrderedDict[str, tf.TensorSpec], tf.TensorSpec] ): return ( collections.OrderedDict( [('feature-1', tf.TensorSpec([None, 1], tf.float32)), ('feature-2', tf.TensorSpec([None, 1], tf.float32))] ), tf.TensorSpec([None, 1], tf.int64), )
- Abbina quanto precede alla seguente implementazione dell'API pubblica ODP IsolatedWorker#onTrainingExamples per generare dati di addestramento:
return tf.train.Example( features=tf.train.Features( feature={ 'feature-1': tf.train.Feature( float_list=tf.train.FloatList(value=[1.0]) ), 'feature-2': tf.train.Feature( float_list=tf.train.FloatList(value=[2.0]) ), 'my_label': tf.train.Feature( int64_list=tf.train.Int64List( value=[1] ) ), } ) ).SerializeToString()
- Non dimenticare di registrare label_name nella configurazione del generatore di attività.
mode: TRAINING_AND_EVAL # Task execution mode population_name: "my_example_model" label_name: "my_label"
ODP gestisce automaticamente il DP durante la creazione del processo di apprendimento. Pertanto, non è necessario aggiungere rumore durante la creazione del modello funzionale.
L'output di questo modello funzionale salvato dovrebbe essere simile all'esempio nel nostro repository GitHub.
Passaggio 2: Crea la configurazione del generatore di attività
Puoi trovare esempi della configurazione del generatore di attività nel nostro repository GitHub.
Metriche di addestramento e valutazione
Poiché le metriche potrebbero divulgare dati utente, lo strumento Task Builder avrà un elenco di metriche che il processo di apprendimento può generare e rilasciare. Puoi trovare l'elenco completo nel nostro repository GitHub.
Ecco un elenco di metriche di esempio per la creazione di una nuova configurazione del generatore di attività:
federated_learning { learning_process { metrics { name: "binary_accuracy" } metrics { name: "binary_crossentropy" } metrics { name: "recall" } metrics { name: "precision" } metrics { name: "auc-roc" } metrics { name: "auc-pr" } } }
Se le metriche di tuo interesse non sono presenti nell'elenco presente, contattaci.
Configurazioni DP
Esistono alcune configurazioni relative ai DP che devono essere specificate:
policies { min_separation_policy { minimum_separation: 1 } model_release_policy { num_max_training_rounds: 1000 dp_target_epsilon: 10 dp_delta: 0.000001 } } differential_privacy { type: FIXED_GAUSSIAN clip_norm: 0.1 noise_multiplier: 0.1 }
- Per superare la convalida, è presente
dp_target_epsilon
onoise_mulitipiler
: (noise_to_epsilon
epislon_to_noise
). - Puoi trovare queste impostazioni predefinite nel nostro repository GitHub.
- Per superare la convalida, è presente
Passaggio 3: Carica il modello salvato e la configurazione del generatore di attività nello spazio di archiviazione sul cloud di qualsiasi sviluppatore
Ricorda di aggiornare i campi artifact_building quando carichi la configurazione del generatore di attività.
Passaggio 4: (Facoltativo) Testa la creazione degli artefatti senza creare una nuova attività
cd ${odp_fcp_github_repo}/python
bazel run //python/taskbuilder:task_builder_client -- --saved_model=${path_of_cloud_storage}/mnist_model/ --task_config=${path_of_cloud_storage}/mnist_cnn_task_config_build_artifact_only.pbtxt --build_artifact_only=true --task_builder_server=${task_builder_server_endpoint}
Il modello di esempio viene convalidato sia tramite il controllo delle operazioni flessibili sia tramite il controllo dp. Puoi aggiungere skip_flex_ops_check
e skip_dp_check
per eseguire il bypass durante la convalida (questo modello non può essere implementato nella versione corrente del client ODP a causa di alcune operazioni flessibili mancanti).
cd ${odp_fcp_github_repo}/python
bazel run //python/taskbuilder:task_builder_client -- --saved_model=${path_of_cloud_storage}/mnist_model/ --task_config=${path_of_cloud_storage}/mnist_cnn_task_config_build_artifact_only.pbtxt --build_artifact_only=true --task_builder_server=${task_builder_server_endpoint} --skip_flex_ops_check=True --skip_dp_check=True
flex_ops_check: la libreria di operatori integrata di TensorFlow Lite supporta solo un numero limitato di operatori TensorFlow (Compatibilità degli operatori TensorFlow Lite e TensorFlow). Tutte le operazioni tensorflow incompatibili devono essere installate utilizzando il delegato flex (Android.bp). Se un modello contiene operazioni non supportate, contattaci per registrarle:
Cannot build the ClientOnlyPlan: Please contact Google to register these ops: {...}
Il modo migliore per eseguire il debug di un generatore di attività è avviarne uno in locale:
# Starts a server at localhost:5000 bazel run //python/taskbuilder:task_builder # Links to a server at localhost:5000 by removing task_builder_server flag bazel run //python/taskbuilder:task_builder_client -- --saved_model=${path_of_cloud_storage}/mnist_model/ --task_config=${path_of_cloud_storage}/mnist_cnn_task_config_build_artifact_only.pbtxt --build_artifact_only=true --skip_flex_ops_check=True --skip_dp_check=True
Puoi trovare gli artefatti risultanti nello spazio di archiviazione sul cloud specificato nella configurazione. Dovrebbe essere simile a l'esempio nel nostro repository GitHub.
Passaggio 5: Crea artefatti e crea una nuova coppia di attività di addestramento e valutazione sul server FCP.
Rimuovi il flag build_artifact_only
e gli elementi compilati verranno caricati sul server FCP. Devi verificare che una coppia di attività di addestramento e valutazione sia stata creata correttamente
cd ${odp_fcp_github_repo}/python
bazel run //python/taskbuilder:task_builder_client -- --saved_model=${path_of_cloud_storage}/mnist_model/ --task_config=${path_of_cloud_storage}/mnist_cnn_task_config.pbtxt --task_builder_server=${task_builder_server_endpoint}
Passaggio 6: Prepara il lato client di FCP
- Implementa l'API pubblica ODP
IsolatedWorker#onTrainingExamples
per generare dati di addestramento. - Chiama il numero
FederatedComputeScheduler#schedule
. - Trova alcuni esempi nel nostro repository di codice Android.
Passaggio 7: Monitoraggio
Metriche del server
Trova le istruzioni di configurazione nel nostro repository GitHub.
- Metriche del modello
È possibile confrontare le metriche di esecuzioni diverse in un unico diagramma. Ad esempio:
- La linea viola è con
noise_multiplier
0,1 - La linea rosa è con
noise_multipiler
0,3