도움말 Kaggle에 TensorFlow과 그레이트 배리어 리프 (Great Barrier Reef)를 보호하기 도전에 참여

나만의 연합 학습 알고리즘 구축

TensorFlow.org에서 보기 Google Colab에서 실행 GitHub에서 소스 보기 노트북 다운로드

시작하기 전에

시작하기 전에 다음을 실행하여 환경이 올바르게 설정되었는지 확인하십시오. 당신이 인사말을 표시되지 않는 경우를 참조하십시오 설치 지침은 가이드.

!pip install --quiet --upgrade tensorflow-federated-nightly
!pip install --quiet --upgrade nest-asyncio

import nest_asyncio
nest_asyncio.apply()
import tensorflow as tf
import tensorflow_federated as tff

에서 이미지 분류텍스트 세대 튜토리얼, 우리는 연합 학습 (FL) 모델과 데이터 파이프 라인을 설정하는 방법을 학습하고,를 통해 연합 훈련을 수행 tff.learning TFF의 API 층.

이것은 FL 연구와 관련하여 빙산의 일각에 불과합니다. 이 튜토리얼에서, 우리는에 연기없이 연합 학습 알고리즘을 구현하는 방법에 대해 설명 tff.learning API. 우리는 다음을 달성하는 것을 목표로 합니다:

목표:

  • 연합 학습 알고리즘의 일반적인 구조를 이해합니다.
  • TFF의 연합 핵심을 탐험 해보세요.
  • Federated Core를 사용하여 Federated Averaging을 직접 구현합니다.

이 튜토리얼은 독립적이지만, 우리는 읽는 첫번째 추천 영상 분류텍스트 생성 자습서.

입력 데이터 준비

먼저 TFF에 포함된 EMNIST 데이터 세트를 로드하고 전처리합니다. 자세한 내용은 참조 이미지 분류 자습서를.

emnist_train, emnist_test = tff.simulation.datasets.emnist.load_data()

우리의 모델에 데이터 집합을 공급하기 위해, 우리는 데이터를 평평하게하고, 형태의 튜플로 각 예제를 변환 (flattened_image_vector, label) .

NUM_CLIENTS = 10
BATCH_SIZE = 20

def preprocess(dataset):

  def batch_format_fn(element):
    """Flatten a batch of EMNIST data and return a (features, label) tuple."""
    return (tf.reshape(element['pixels'], [-1, 784]), 
            tf.reshape(element['label'], [-1, 1]))

  return dataset.batch(BATCH_SIZE).map(batch_format_fn)

이제 소수의 클라이언트를 선택하고 위의 전처리를 데이터 세트에 적용합니다.

client_ids = sorted(emnist_train.client_ids)[:NUM_CLIENTS]
federated_train_data = [preprocess(emnist_train.create_tf_dataset_for_client(x))
  for x in client_ids
]

모델 준비

우리는에서와 동일한 모델을 사용하여 이미지 분류 자습서. (이 모델을 통해 구현 tf.keras )는이 softmax 층 뒤에 숨겨진 단일 층을 갖는다.

def create_keras_model():
  initializer = tf.keras.initializers.GlorotNormal(seed=0)
  return tf.keras.models.Sequential([
      tf.keras.layers.Input(shape=(784,)),
      tf.keras.layers.Dense(10, kernel_initializer=initializer),
      tf.keras.layers.Softmax(),
  ])

TFF에서이 모델을 사용하기 위해, 우리는 같은 Keras 모델 포장 tff.learning.Model . 이것은 우리가 모델의 수행 할 수 있도록 앞으로 패스를 TFF 내에서, 그리고 추출 모델 출력 . 자세한 내용은 또한 참조 이미지 분류 자습서를.

def model_fn():
  keras_model = create_keras_model()
  return tff.learning.from_keras_model(
      keras_model,
      input_spec=federated_train_data[0].element_spec,
      loss=tf.keras.losses.SparseCategoricalCrossentropy(),
      metrics=[tf.keras.metrics.SparseCategoricalAccuracy()])

우리가 사용하는 동안 tf.keras 만들 tff.learning.Model , TFF는 훨씬 더 일반적인 모델을 지원합니다. 이러한 모델에는 모델 가중치를 캡처하는 다음과 같은 관련 속성이 있습니다.

  • trainable_variables : 학습 가능한 층에 대응 텐서의 반복 가능.
  • non_trainable_variables : 비 학습 가능한 층에 대응 텐서의 반복 가능.

우리의 목적을 위해, 우리는 단지 사용 trainable_variables . (저희 모델은 그것들만 가지고 있습니다!).

나만의 연합 학습 알고리즘 구축

그동안 tff.learning API는 하나의 연합 평균화의 많은 변종을 만들 수 있습니다,이 프레임 워크에 깔끔하게 맞지 않는 다른 연합 알고리즘이 있습니다. 예를 들어, 같은 정규화, 클리핑, 또는 좀 더 복잡한 알고리즘을 추가 할 수 있습니다 연합 GAN 훈련 . 당신은 대신에 관심이있을 수 있습니다 연합 분석 .

이러한 고급 알고리즘의 경우 TFF를 사용하여 자체 사용자 지정 알고리즘을 작성해야 합니다. 많은 경우 연합 알고리즘에는 4가지 주요 구성 요소가 있습니다.

  1. 서버-클라이언트 브로드캐스트 단계.
  2. 로컬 클라이언트 업데이트 단계.
  3. 클라이언트에서 서버로의 업로드 단계.
  4. 서버 업데이트 단계입니다.

TFF, 우리는 일반적으로 같은 연합 알고리즘 나타내는 tff.templates.IterativeProcess (우리는 단지로 참조 IterativeProcess 걸쳐 참조). 이것은 포함하는 클래스 initialize 하고 next 기능을. 여기서, initialize 서버를 초기화하는데 사용되며, next 연합 알고리즘의 하나의 통신 라운드를 수행한다. FedAvg에 대한 반복 프로세스가 어떻게 생겼는지에 대한 골격을 작성해 보겠습니다.

첫째, 우리는 단순히이 생성한다는 초기화 기능이 tff.learning.Model , 그 학습 가능한 가중치를 반환합니다.

def initialize_fn():
  model = model_fn()
  return model.trainable_variables

이 기능은 좋아 보이지만 나중에 보게 되겠지만 "TFF 계산"이 되도록 약간 수정해야 합니다.

우리는 또한 스케치 할 next_fn .

def next_fn(server_weights, federated_dataset):
  # Broadcast the server weights to the clients.
  server_weights_at_client = broadcast(server_weights)

  # Each client computes their updated weights.
  client_weights = client_update(federated_dataset, server_weights_at_client)

  # The server averages these updates.
  mean_client_weights = mean(client_weights)

  # The server updates its model.
  server_weights = server_update(mean_client_weights)

  return server_weights

이 네 가지 구성 요소를 개별적으로 구현하는 데 중점을 둘 것입니다. 먼저 순수 TensorFlow에서 구현할 수 있는 부분, 즉 클라이언트 및 서버 업데이트 단계에 중점을 둡니다.

텐서플로우 블록

클라이언트 업데이트

우리는 우리의 사용 tff.learning.Model 당신이 TensorFlow 모델을 훈련하는 것이 본질적으로 같은 방법으로 클라이언트 훈련을 할 수 있습니다. 특히, 우리는 사용 tf.GradientTape 한 후, 데이터의 일괄 처리에 그라데이션을 계산 사용하여 이러한 그라데이션을 적용 client_optimizer . 우리는 훈련 가능한 가중치에만 초점을 맞춥니다.

@tf.function
def client_update(model, dataset, server_weights, client_optimizer):
  """Performs training (using the server model weights) on the client's dataset."""
  # Initialize the client model with the current server weights.
  client_weights = model.trainable_variables
  # Assign the server weights to the client model.
  tf.nest.map_structure(lambda x, y: x.assign(y),
                        client_weights, server_weights)

  # Use the client_optimizer to update the local model.
  for batch in dataset:
    with tf.GradientTape() as tape:
      # Compute a forward pass on the batch of data
      outputs = model.forward_pass(batch)

    # Compute the corresponding gradient
    grads = tape.gradient(outputs.loss, client_weights)
    grads_and_vars = zip(grads, client_weights)

    # Apply the gradient using a client optimizer.
    client_optimizer.apply_gradients(grads_and_vars)

  return client_weights

서버 업데이트

FedAvg에 대한 서버 업데이트는 클라이언트 업데이트보다 간단합니다. 우리는 단순히 서버 모델 가중치를 클라이언트 모델 가중치의 평균으로 바꾸는 "바닐라" 연합 평균을 구현할 것입니다. 다시 말하지만, 우리는 훈련 가능한 가중치에만 초점을 맞춥니다.

@tf.function
def server_update(model, mean_client_weights):
  """Updates the server model weights as the average of the client model weights."""
  model_weights = model.trainable_variables
  # Assign the mean client weights to the server model.
  tf.nest.map_structure(lambda x, y: x.assign(y),
                        model_weights, mean_client_weights)
  return model_weights

코드 조각은 단순히 반환하여 단순화 할 수 mean_client_weights . 그러나 연합 평균화 사용의 고급 구현 mean_client_weights 등의 모멘텀이나 적응성과 같은보다 정교한 기술과.

과제 : 버전 구현 server_update model_weights 및 mean_client_weights의 중간 점으로 서버의 가중치를 업데이트합니다. (참고 : "중간"이런 종류의 접근법이에 대한 최근의 연구와 유사 내다 최적화 !).

지금까지는 순수한 TensorFlow 코드만 작성했습니다. TFF를 사용하면 이미 친숙한 TensorFlow 코드를 많이 사용할 수 있기 때문에 이것은 의도적으로 설계된 것입니다. 그러나 지금 우리는 오케스트레이션 로직, 지시 클라이언트에 어떤 서버 방송, 어떤 클라이언트 업로드하는 서버에 대한 논리를 지정해야합니다.

이 TFF의 연합 코어가 필요합니다.

Federated Core 소개

연합 코어 (FC)을위한 기반으로서 봉사 하위 레벨 인터페이스의 집합 tff.learning API. 그러나 이러한 인터페이스는 학습에만 국한되지 않습니다. 실제로 분산 데이터에 대한 분석 및 기타 여러 계산에 사용할 수 있습니다.

상위 수준에서 연합 코어는 압축적으로 표현된 프로그램 논리가 TensorFlow 코드를 분산 통신 연산자(예: 분산 합계 및 브로드캐스트)와 결합할 수 있도록 하는 개발 환경입니다. 목표는 연구자와 실무자가 시스템 구현 세부 사항(예: 지점 간 네트워크 메시지 교환 지정)을 요구하지 않고 시스템의 분산 통신을 명시적으로 제어할 수 있도록 하는 것입니다.

한 가지 요점은 TFF가 개인 정보 보호를 위해 설계되었다는 것입니다. 따라서 데이터가 있는 위치를 명시적으로 제어하여 중앙 서버 위치에서 원치 않는 데이터 축적을 방지할 수 있습니다.

연합 데이터

TFF의 핵심 개념은 "연합 데이터"로, 분산 시스템의 장치 그룹(예: 클라이언트 데이터 세트 또는 서버 모델 가중치)에 걸쳐 호스팅되는 데이터 항목 모음을 나타냅니다. 우리는 하나의 연합 값으로 모든 장치에서 데이터 항목의 전체 컬렉션을 모델링.

예를 들어 각각 센서의 온도를 나타내는 부동 소수점이 있는 클라이언트 장치가 있다고 가정합니다. 우리는에 의해 연합 플로트로 나타낼 수

federated_float_on_clients = tff.FederatedType(tf.float32, tff.CLIENTS)

연합 타입의 타입에 의해 지정된 T 멤버의 성분 (예. tf.float32 ) 및 그룹 G 장치. 우리는 경우에 초점을 맞출 것이다 G 중입니다 tff.CLIENTS 또는 tff.SERVER . 이러한 연합 유형으로 표시된다 {T}@G 아래와 같이.

str(federated_float_on_clients)
'{float32}@CLIENTS'

왜 우리는 배치에 그렇게 많은 관심을 가집니까? TFF의 주요 목표는 실제 분산 시스템에 배포할 수 있는 코드 작성을 가능하게 하는 것입니다. 즉, 장치의 어떤 하위 집합이 어떤 코드를 실행하고 다른 데이터 조각이 있는 위치에 대해 추론하는 것이 중요합니다.

TFF는 세 가지에 초점을 맞추고 : 데이터, 데이터가 배치되고, 데이터가 어떻게 변화되고있다. 마지막이 연합 계산 캡슐화 동안 처음 두는 연합 타입에서 캡슐화된다.

연합 계산

TFF는 그 기본 단위 연합 계산이다 강력한 형식의 함수형 프로그래밍 환경입니다. 이들은 연합 값을 입력으로 받아들이고 연합 값을 출력으로 반환하는 논리 조각입니다.

예를 들어 클라이언트 센서의 평균 온도를 원한다고 가정합니다. 다음을 정의할 수 있습니다(연합 부동 소수점 사용).

@tff.federated_computation(tff.FederatedType(tf.float32, tff.CLIENTS))
def get_average_temperature(client_temperatures):
  return tff.federated_mean(client_temperatures)

당신은에서이 어떻게 다른지, 요청할 수 있습니다 tf.function TensorFlow에 장식? 주요 대답은에 의해 생성 된 코드이다 tff.federated_computation 도 TensorFlow도 파이썬 코드; 그것은 내부 플랫폼에 독립적 인 접착제 언어의 분산 시스템의 사양입니다.

복잡하게 들릴 수 있지만 TFF 계산은 잘 정의된 유형 서명이 있는 함수로 생각할 수 있습니다. 이러한 유형 서명은 직접 쿼리할 수 있습니다.

str(get_average_temperature.type_signature)
'({float32}@CLIENTS -> float32@SERVER)'

tff.federated_computation 연합 형의 인수를 받아들이는 {float32}@CLIENTS 및 연합 유형의 반환 값 {float32}@SERVER . 연합 계산은 또한 서버에서 클라이언트로, 클라이언트에서 클라이언트로 또는 서버에서 서버로 이동할 수 있습니다. 연합 계산은 유형 서명이 일치하는 한 일반 함수처럼 구성될 수도 있습니다.

개발을 지원하기 위해, TFF 당신이 호출 할 수 tff.federated_computation 파이썬 함수를. 예를 들어

get_average_temperature([68.5, 70.3, 69.8])
69.53334

비 열망 계산 및 TensorFlow

두 가지 주요 제한 사항을 알고 있어야 합니다. 파이썬 인터프리터가 발생하면 먼저, tff.federated_computation 장식을, 함수는 한 번 추적 및 향후 사용을 위해 직렬화됩니다. 연합 학습의 분산된 특성으로 인해 이러한 미래의 사용은 원격 실행 환경과 같은 다른 곳에서 발생할 수 있습니다. 따라서, TFF 연산은 기본적으로 비 열망. 이 동작은의 그것과 다소 유사하다 tf.function TensorFlow에 장식.

둘째, 연합 연산 만 (예 연합 오퍼레이터 구성 가능 tff.federated_mean )들은 TensorFlow 동작들을 포함 할 수 없다. TensorFlow 코드는 장식 블록에 국한해야 tff.tf_computation . 대부분의 일반 TensorFlow 코드를 직접적 번호를 받아 다음을 추가 함수로 장식 할 수 있습니다 0.5 그것.

@tff.tf_computation(tf.float32)
def add_half(x):
  return tf.add(x, 0.5)

이들은 또한 있지만, 게재 위치에없이 입력 서명을해야합니다. 예를 들어,

str(add_half.type_signature)
'(float32 -> float32)'

여기에서 우리는 사이에는 중요한 차이를 볼 수 tff.federated_computationtff.tf_computation . 전자는 명시적 배치가 있지만 후자는 그렇지 않습니다.

우리는 사용할 수 tff.tf_computation 게재 위치를 지정하여 연합 계산에서 블록을. 절반을 추가하지만 클라이언트에서 연합 부동 소수점에만 추가하는 함수를 만들어 보겠습니다. 우리는 사용하여이 작업을 수행 할 수 tff.federated_map 주어진 적용 tff.tf_computation 위치를 유지하면서.

@tff.federated_computation(tff.FederatedType(tf.float32, tff.CLIENTS))
def add_half_on_clients(x):
  return tff.federated_map(add_half, x)

이 기능은 거의 동일 add_half , 그것은 단지에서 위치와 값을 받아들이는 것을 제외하고 tff.CLIENTS 같은 배치로, 반환 값을 설정합니다. 유형 서명에서 이를 확인할 수 있습니다.

str(add_half_on_clients.type_signature)
'({float32}@CLIENTS -> {float32}@CLIENTS)'

요약해서 말하자면:

  • TFF는 연합 값에서 작동합니다.
  • 각 연합 값은 유형 (예.와 연합 형 갖는다 tf.float32 ) 및 위치 (예. tff.CLIENTS ).
  • 연합 값 장식해야 티드 계산 이용한 변형 될 수 tff.federated_computation 과 연합 형 서명.
  • TensorFlow 코드와 블록에 포함되어야합니다 tff.tf_computation 장식.
  • 그런 다음 이러한 블록을 연합 계산에 통합할 수 있습니다.

나만의 연합 학습 알고리즘 구축, 재검토

이제 Federated Core를 살펴보았으므로 자체적인 연합 학습 알고리즘을 구축할 수 있습니다. 우리는 정의, 위의 그 기억 initialize_fn 하고 next_fn 우리의 알고리즘. next_fn 의 사용하게됩니다 client_update 하고 server_update 우리가 순수 TensorFlow 코드를 사용하여 정의.

그러나, 우리의 알고리즘 연합 계산하게하기 위해, 우리는 둘 다 필요합니다 next_fninitialize_fn 각각 수에 tff.federated_computation .

TensorFlow 연합 블록

초기화 계산 생성

초기화 기능은 매우 간단합니다 : 우리는 사용하여 모델을 생성합니다 model_fn . 그러나, 우리가 사용하는 우리의 TensorFlow 코드를 분리해야한다는 것을 기억 tff.tf_computation .

@tff.tf_computation
def server_init():
  model = model_fn()
  return model.trainable_variables

우리는 다음 사용하여 연합 계산에 직접 전달할 수 있습니다 tff.federated_value .

@tff.federated_computation
def initialize_fn():
  return tff.federated_value(server_init(), tff.SERVER)

만들기] next_fn

이제 클라이언트 및 서버 업데이트 코드를 사용하여 실제 알고리즘을 작성합니다. 우리는 먼저 우리의 켜집니다 client_updatetff.tf_computation 클라이언트 데이터 셋 및 서버 가중치를 받아들이고, 업데이트 된 클라이언트 무게 텐서를 출력합니다.

함수를 적절하게 장식하려면 해당 유형이 필요합니다. 운 좋게도 서버 가중치 유형은 모델에서 직접 추출할 수 있습니다.

whimsy_model = model_fn()
tf_dataset_type = tff.SequenceType(whimsy_model.input_spec)

데이터 세트 유형 서명을 살펴보겠습니다. 28 x 28 이미지(정수 레이블 포함)를 가져와 평면화했음을 기억하십시오.

str(tf_dataset_type)
'<float32[?,784],int32[?,1]>*'

우리는 또한 우리를 사용하여 모델의 무게 유형을 추출 할 수 있습니다 server_init 위의 기능을.

model_weights_type = server_init.type_signature.result

유형 서명을 조사하면 우리 모델의 아키텍처를 볼 수 있습니다!

str(model_weights_type)
'<float32[784,10],float32[10]>'

우리는 지금 우리의 만들 수 있습니다 tff.tf_computation 클라이언트 업데이트를.

@tff.tf_computation(tf_dataset_type, model_weights_type)
def client_update_fn(tf_dataset, server_weights):
  model = model_fn()
  client_optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
  return client_update(model, tf_dataset, server_weights, client_optimizer)

tff.tf_computation 서버 업데이트 버전은 우리가 이미 추출 된 한 유형을 사용하여, 비슷한 방법으로 정의 할 수 있습니다.

@tff.tf_computation(model_weights_type)
def server_update_fn(mean_client_weights):
  model = model_fn()
  return server_update(model, mean_client_weights)

마지막으로,하지만 적어도, 우리는 만들 필요가 tff.federated_computation 이 모두 함께 제공합니다. 이 함수는 두 연합 값, 하나 (배치하여 서버 가중치에 해당하는 받아 들일 것 tff.SERVER ) 및 (배치와 클라이언트 데이터 셋에 해당하는 다른 tff.CLIENTS ).

이 두 유형은 모두 위에서 정의되었습니다! 우리는 단순히 그들에게 사용하여 적절한 배치 줄 필요가 tff.FederatedType .

federated_server_type = tff.FederatedType(model_weights_type, tff.SERVER)
federated_dataset_type = tff.FederatedType(tf_dataset_type, tff.CLIENTS)

FL 알고리즘의 4가지 요소를 기억하십니까?

  1. 서버-클라이언트 브로드캐스트 단계.
  2. 로컬 클라이언트 업데이트 단계.
  3. 클라이언트에서 서버로의 업로드 단계.
  4. 서버 업데이트 단계입니다.

이제 위의 내용을 작성했으므로 각 부분을 TFF 코드의 한 줄로 간결하게 표현할 수 있습니다. 이 단순함 때문에 연합 유형과 같은 항목을 지정하는 데 각별한 주의를 기울여야 했습니다!

@tff.federated_computation(federated_server_type, federated_dataset_type)
def next_fn(server_weights, federated_dataset):
  # Broadcast the server weights to the clients.
  server_weights_at_client = tff.federated_broadcast(server_weights)

  # Each client computes their updated weights.
  client_weights = tff.federated_map(
      client_update_fn, (federated_dataset, server_weights_at_client))

  # The server averages these updates.
  mean_client_weights = tff.federated_mean(client_weights)

  # The server updates its model.
  server_weights = tff.federated_map(server_update_fn, mean_client_weights)

  return server_weights

우리는 지금이 tff.federated_computation 및 알고리즘의 한 단계를 실행하기위한 알고리즘을 초기화 모두를. 우리의 알고리즘을 완료하기 위해, 우리는에이 통과 tff.templates.IterativeProcess .

federated_algorithm = tff.templates.IterativeProcess(
    initialize_fn=initialize_fn,
    next_fn=next_fn
)

유형 서명에서 살펴 보자 initializenext 우리의 반복적 인 과정의 기능을합니다.

str(federated_algorithm.initialize.type_signature)
'( -> <float32[784,10],float32[10]>@SERVER)'

이 사실 반영 federated_algorithm.initialize 인수없는 기능이다자를 반환 (784 × 10 중량 행렬 및 10 개 바이어스 유닛) 단층 모델.

str(federated_algorithm.next.type_signature)
'(<server_weights=<float32[784,10],float32[10]>@SERVER,federated_dataset={<float32[?,784],int32[?,1]>*}@CLIENTS> -> <float32[784,10],float32[10]>@SERVER)'

여기, 우리가 볼 federated_algorithm.next 서버 모델과 클라이언트 데이터, 반환 업데이트 된 서버 모델을 받아들입니다.

알고리즘 평가

몇 라운드를 실행하고 손실이 어떻게 변하는지 봅시다. 첫째, 우리는 두 번째 가이드 논의 집중식 접근법을 사용하는 평가 함수를 정의한다.

먼저 중앙 집중식 평가 데이터 세트를 만든 다음 훈련 데이터에 사용한 것과 동일한 전처리를 적용합니다.

central_emnist_test = emnist_test.create_tf_dataset_from_all_clients()
central_emnist_test = preprocess(central_emnist_test)

다음으로, 서버 상태를 받아들이고 Keras를 사용하여 테스트 데이터 세트를 평가하는 함수를 작성합니다. 당신이 익숙하다면 tf.Keras ,이 모든 모습을 잘 알고, 참고하지만 사용 set_weights !

def evaluate(server_state):
  keras_model = create_keras_model()
  keras_model.compile(
      loss=tf.keras.losses.SparseCategoricalCrossentropy(),
      metrics=[tf.keras.metrics.SparseCategoricalAccuracy()]  
  )
  keras_model.set_weights(server_state)
  keras_model.evaluate(central_emnist_test)

이제 알고리즘을 초기화하고 테스트 세트에서 평가해 보겠습니다.

server_state = federated_algorithm.initialize()
evaluate(server_state)
2042/2042 [==============================] - 2s 767us/step - loss: 2.8479 - sparse_categorical_accuracy: 0.1027

몇 라운드 동안 훈련하고 변화가 있는지 살펴보겠습니다.

for round in range(15):
  server_state = federated_algorithm.next(server_state, federated_train_data)
evaluate(server_state)
2042/2042 [==============================] - 2s 738us/step - loss: 2.5867 - sparse_categorical_accuracy: 0.0980

손실 함수가 약간 감소하는 것을 볼 수 있습니다. 점프는 작지만 소수의 클라이언트에 대해 15번의 훈련 라운드만 수행했습니다. 더 나은 결과를 보려면 수천 번은 아니더라도 수백 번을 해야 할 수도 있습니다.

알고리즘 수정

이 시점에서 멈추고 우리가 성취한 것에 대해 생각해 봅시다. 우리는 순수 TensorFlow 코드(클라이언트 및 서버 업데이트용)를 TFF의 Federated Core에서 통합 계산과 결합하여 Federated Averaging을 직접 구현했습니다.

보다 정교한 학습을 ​​수행하기 위해 위에 있는 내용을 간단히 변경할 수 있습니다. 특히, 위의 순수 TF 코드를 편집하여 클라이언트가 훈련을 수행하는 방법이나 서버가 모델을 업데이트하는 방법을 변경할 수 있습니다.

과제 : 추가 그라데이션 클리핑을 받는 client_update 기능.

더 큰 변경을 원하면 서버를 저장하고 더 많은 데이터를 브로드캐스트할 수도 있습니다. 예를 들어, 서버는 클라이언트 학습률을 저장하고 시간이 지남에 따라 감소하게 만들 수도 있습니다! 이것은에 사용되는 유형 서명에 대한 변경이 필요하다고 참고 tff.tf_computation 위의 호출합니다.

세게 과제 : 클라이언트에 속도 붕괴 학습과 연합 평균을 구현합니다.

이 시점에서 이 프레임워크에서 구현할 수 있는 유연성이 얼마나 되는지 깨닫기 시작할 수 있습니다. (위의 열심히 도전에 대한 답 포함) 아이디어를 당신의 소스 코드를 볼 수 있습니다 tff.learning.build_federated_averaging_process , 또는 다양한 체크 아웃 연구 프로젝트를 TFF를 사용하여.