Kendi Birleştirilmiş Öğrenme Algoritmanızı Oluşturma

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın Kaynağı GitHub'da görüntüleyin Not defterini indir

Başlamadan önce

Başlamadan önce, ortamınızın doğru şekilde kurulduğundan emin olmak için lütfen aşağıdakileri çalıştırın. Eğer bir selamlama görmüyorsanız, bakınız Kurulum talimatları için rehber.

!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

In görüntü sınıflandırma ve metin oluşturma öğreticiler, biz Federe Öğrenme (FL) modeli ve veri boru hatlarını kurmak öğrendim ve üzeri federe eğitimi gerçekleştirilen tff.learning TFF API katmanı.

FL araştırması söz konusu olduğunda bu sadece buzdağının görünen kısmı. Bu eğitimde, ertelemek olmadan federe öğrenme algoritmaları nasıl uygulanacağını tartışmak tff.learning API. Aşağıdakileri gerçekleştirmeyi amaçlıyoruz:

Hedefler:

  • Birleşik öğrenme algoritmalarının genel yapısını anlayın.
  • TFF Federe Çekirdek keşfedin.
  • Birleşik Ortalamayı doğrudan uygulamak için Federated Core'u kullanın.

Bu öğretici kendine yeten olmasına rağmen, biz okuma ilk tavsiye görüntü sınıflandırma ve metin oluşturma öğreticiler.

Giriş verilerinin hazırlanması

Önce TFF'de bulunan EMNIST veri setini yükleyip ön işleme alıyoruz. Daha fazla ayrıntı için bkz görüntü sınıflandırma öğretici.

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

Bizim modeli veri kümesi beslemek için, veriler düzleştirmek ve formun bir başlığın her bir örnek dönüştürmek (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)

Şimdi az sayıda müşteri seçiyoruz ve yukarıdaki ön işlemeyi veri kümelerine uyguluyoruz.

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
]

Modelin hazırlanması

Biz de aynı modeli kullanmak görüntü sınıflandırma öğretici. (Yoluyla uygulanan Bu model tf.keras ) bir SoftMax katman takip tek bir gizli tabakası vardır.

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'nin bu modeli kullanmak için, bir şekilde Keras modeli sarın tff.learning.Model . Bu bize modelin gerçekleştirmesini sağlar ileriye pas TFF içinde ve özü model çıktıları . Daha fazla ayrıntı için ayrıca bkz görüntü sınıflandırma öğretici.

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()])

Kullandığımız iken tf.keras bir oluşturmak için tff.learning.Model , TFF çok daha genel modellerini destekler. Bu modeller, model ağırlıklarını yakalayan aşağıdaki ilgili özelliklere sahiptir:

  • trainable_variables : trainable tabakalarına tekabül eden tansörleri bir iterable.
  • non_trainable_variables : olmayan eğitilebilen tabakalarına tekabül eden tansörleri bir iterable.

Bizim için, sadece kullanacağı trainable_variables . (çünkü bizim modelimizde sadece bunlar var!).

Kendi Birleştirilmiş Öğrenim algoritmanızı oluşturma

İken tff.learning API biri Federe Ortalaması Alma pek çok çeşidi oluşturmanıza olanak sağlar, bu çerçevede içine düzgünce sığmayan diğer federe algoritması vardır. Örneğin, aşağıdakiler gibi düzene koymayı, kırpma, ya da daha karmaşık algoritmalar eklemek isteyebilirsiniz federe GAN eğitimi . Ayrıca yerine ilginizi edilebilir federe analitik .

Bu daha gelişmiş algoritmalar için TFF kullanarak kendi özel algoritmamızı yazmamız gerekecek. Çoğu durumda, birleşik algoritmaların 4 ana bileşeni vardır:

  1. Sunucudan istemciye bir yayın adımı.
  2. Yerel bir istemci güncelleme adımı.
  3. İstemciden sunucuya yükleme adımı.
  4. Bir sunucu güncelleme adımı.

TFF, biz genellikle olarak federe algoritmaları temsil tff.templates.IterativeProcess (biz sadece bir dediğimiz IterativeProcess boyunca). Bu içeren bir sınıftır initialize ve next işlevleri. Burada, initialize sunucuyu başlatmak için kullanılır ve next federe algoritmanın bir haberleşme yuvarlak gerçekleştirecektir. FedAvg için yinelemeli sürecimizin nasıl görünmesi gerektiğine dair bir iskelet yazalım.

İlk olarak, sadece bir oluşturur başlat işlevini var tff.learning.Model ve bunun eğitilebilir ağırlıkları döndürür.

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

Bu fonksiyon iyi görünüyor, ancak daha sonra göreceğimiz gibi, onu bir "TFF hesaplaması" yapmak için küçük bir değişiklik yapmamız gerekecek.

Biz de eskiz istiyoruz 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

Bu dört bileşeni ayrı ayrı uygulamaya odaklanacağız. İlk önce salt TensorFlow'da uygulanabilecek kısımlara, yani istemci ve sunucu güncelleme adımlarına odaklanıyoruz.

TensorFlow Blokları

İstemci güncellemesi

Bizim kullanacağız tff.learning.Model bir TensorFlow modeli eğitim vereceğini temelde aynı şekilde istemci eğitim yapmak için. Özellikle, kullanacağız tf.GradientTape sonra, verilerin seri üzerinde gradyan hesaplamak bir kullanarak bu degrade uygulamak için client_optimizer . Sadece eğitilebilir ağırlıklara odaklanıyoruz.

@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

Sunucu Güncellemesi

FedAvg için sunucu güncellemesi, istemci güncellemesinden daha basittir. Sunucu modeli ağırlıklarını istemci model ağırlıklarının ortalamasıyla değiştirdiğimiz "vanilya" birleşik ortalamasını uygulayacağız. Yine, sadece eğitilebilir ağırlıklara odaklanıyoruz.

@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

Pasajı basitçe döndürerek basitleştirilmiş olabilir mean_client_weights . Ancak, Federe Averaging kullanımı daha gelişmiş uygulamaları mean_client_weights böyle momentum veya adaptivity gibi daha sofistike teknikler ile.

Zorluk: bir sürümünü uygulamak server_update model_weights ve mean_client_weights orta olmak için sunucu ağırlıklarını günceller. (Not: "orta nokta" Bu tarz yaklaşım üzerine son çalışmasında benzer olduğunu Lookahead optimizer !).

Şimdiye kadar sadece saf TensorFlow kodu yazdık. TFF, zaten aşina olduğunuz TensorFlow kodunun çoğunu kullanmanıza izin verdiğinden, bu tasarım gereğidir. Ancak, şimdi biz ise orkestrasyon mantığını, dikte müşteriye hangi sunucuda yayınları ve ne istemci yüklemeler o sunucuya mantığı belirtmek gerekir.

Bu TFF Federe Çekirdek gerektirecektir.

Federe Çekirdeğe Giriş

Federe Çekirdek (FC) için temel olarak hizmet alt düzey arabirimler kümesidir tff.learning API. Ancak, bu arayüzler öğrenme ile sınırlı değildir. Aslında, dağıtılmış veriler üzerinde analitik ve diğer birçok hesaplama için kullanılabilirler.

Üst düzeyde, birleşik çekirdek, TensorFlow kodunu dağıtılmış iletişim operatörleri (dağıtılmış toplamlar ve yayınlar gibi) ile birleştirmek için kompakt bir şekilde ifade edilen program mantığına olanak tanıyan bir geliştirme ortamıdır. Amaç, araştırmacılara ve uygulayıcılara, sistem uygulama ayrıntılarına ihtiyaç duymadan (örneğin, noktadan noktaya ağ mesaj alışverişlerini belirtmek gibi) sistemlerindeki dağıtılmış iletişim üzerinde açık bir kontrol sağlamaktır.

Önemli bir nokta, TFF'nin mahremiyetin korunması için tasarlanmış olmasıdır. Bu nedenle, merkezi sunucu konumunda istenmeyen veri birikimini önlemek için verilerin nerede bulunduğu üzerinde açık kontrol sağlar.

Birleşik veriler

TFF'deki anahtar kavram, dağıtılmış bir sistemde bir grup cihazda barındırılan veri öğelerinin bir koleksiyonunu ifade eden "federe veri"dir (örneğin, istemci veri kümeleri veya sunucu modeli ağırlıkları). Biz tek bir federasyon değer olarak tüm cihazlarda veri öğelerinin tüm koleksiyonu modellemek.

Örneğin, her biri bir sensörün sıcaklığını temsil eden bir şamandıraya sahip istemci cihazlarımız olduğunu varsayalım. Biz tarafından federe şamandıra olarak temsil edebilir

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

Federal tip bir tür tarafından belirtilen T üye bileşenleri (ör. tf.float32 ) ve bir grup G cihazları. Vakaların üzerinde durulacak G ya olduğu tff.CLIENTS veya tff.SERVER . Böyle bir birleşik türü olarak temsil edilir {T}@G , aşağıda gösterildiği gibi,.

str(federated_float_on_clients)
'{float32}@CLIENTS'

Yerleşimleri neden bu kadar önemsiyoruz? TFF'nin temel amacı, gerçek bir dağıtılmış sistemde konuşlandırılabilecek kod yazmayı sağlamaktır. Bu, hangi aygıt alt kümelerinin hangi kodu çalıştırdığı ve farklı veri parçalarının nerede bulunduğu hakkında akıl yürütmenin hayati önem taşıdığı anlamına gelir.

TFF üç şey odaklanır: veriler, veri yerleştirilir ve veri nasıl bir dönüşüm içerisindedir. Son birleşik hesaplamalarda içinde kapsüllenir ise ilk iki, birleşik türleri içinde kapsüllenir.

Birleşik hesaplamalar

TFF kimin temel birimler federe hesaplamaları olan özellikle yazılan fonksiyonel programlama ortamıdır. Bunlar, birleşik değerleri girdi olarak kabul eden ve birleşik değerleri çıktı olarak döndüren mantık parçalarıdır.

Örneğin, istemci sensörlerimizdeki sıcaklıkların ortalamasını almak istediğimizi varsayalım. Aşağıdakileri tanımlayabiliriz (federe kayan noktamızı kullanarak):

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

Sen bu farklı olduğunu sorabilir tf.function TensorFlow içinde dekoratör? Anahtar cevap tarafından oluşturulan kod olmasıdır tff.federated_computation ne TensorFlow ne de Python kodudur; Bu bir iç platformdan bağımsız yapıştırıcı dilde dağıtılmış bir sistem bir özelliğidir.

Bu kulağa karmaşık gelse de, TFF hesaplamalarını iyi tanımlanmış tip imzaları olan işlevler olarak düşünebilirsiniz. Bu tip imzalar doğrudan sorgulanabilir.

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

Bu tff.federated_computation birleşik Çeşidi bağımsız değişkenleri kabul {float32}@CLIENTS ve birleşik Çeşidi döner değerleri {float32}@SERVER . Birleştirilmiş hesaplamalar ayrıca sunucudan istemciye, istemciden istemciye veya sunucudan sunucuya gidebilir. Birleştirilmiş hesaplamalar, tür imzaları eşleştiği sürece normal işlevler gibi oluşturulabilir.

Gelişimini desteklemek için, TFF bir çağırmaya sağlayan tff.federated_computation bir Python fonksiyonu olarak. Örneğin, arayabiliriz

get_average_temperature([68.5, 70.3, 69.8])
69.53334

İsteksiz hesaplamalar ve TensorFlow

Dikkat edilmesi gereken iki önemli kısıtlama vardır. Python yorumlayıcısı bir karşılaştığında Birincisi, tff.federated_computation dekoratör, fonksiyon bir kez izlenebilir ve ileride kullanmak üzere tefrika edilir. Federated Learning'in merkezi olmayan yapısı nedeniyle, gelecekteki bu kullanım, uzaktan yürütme ortamı gibi başka bir yerde gerçekleşebilir. Bu nedenle, TFF hesaplamaları temelde olmayan isteklidir. Bu davranış o kadar benzer olmalarına tf.function TensorFlow içinde dekoratör.

İkinci olarak, bir birleşik hesaplama sadece (örneğin birleşik operatörlerin oluşabilir tff.federated_mean ), bunlar TensorFlow işlemleri içeremez. TensorFlow kodu ile dekore blokların içinde kalmalıdır tff.tf_computation . Çoğu sıradan TensorFlow kodu doğrudan böyle bir sayı alır ve ekler aşağıdaki fonksiyonu olarak dekore edilebilir 0.5 ona.

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

Bunlar da ancak yerleşimlere olmadan, tip imzaları var. Örneğin, arayabiliriz

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

Burada arasında önemli farkı görmek tff.federated_computation ve tff.tf_computation . Birincisinde açık yerleşimler bulunurken, ikincisi yoktur.

Biz kullanabilirsiniz tff.tf_computation yerleşimleri belirterek federe hesaplamalarda blokları. İstemcilerde yalnızca birleştirilmiş kayan noktalara yarısını ekleyen bir işlev oluşturalım. Biz kullanarak bunu yapabilirsiniz tff.federated_map verilen bir uygular, tff.tf_computation yerleştirme korurken,.

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

Bu fonksiyon ile hemen hemen aynıdır add_half , sadece en yerleşimiyle değerlerini kabul ettiğini hariç tff.CLIENTS aynı yerleşim ile birlikte ve iadeler değerleri. Bunu tür imzasında görebiliriz:

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

Özetle:

  • TFF, federe değerlere göre çalışır.
  • Her bir birleşik değeri, bir tür (örneğin. Birlikte birleşik bir türü vardır tf.float32 ) ve bir yerleştirme (örneğin. tff.CLIENTS ).
  • Federe değerler ile dekore edilmelidir federe hesaplamaları kullanılarak dönüştürülebilir tff.federated_computation ve federe tip imza.
  • TensorFlow kodu ile bloklarda yer almalıdır tff.tf_computation dekoratörler.
  • Bu bloklar daha sonra birleşik hesaplamalara dahil edilebilir.

Kendi Federated Learning algoritmanızı oluşturma, tekrar ziyaret edildi

Artık Federe Çekirdeğe bir göz attığımıza göre, kendi birleşik öğrenme algoritmamızı oluşturabiliriz. Biz tanımlanmış, yukarıda unutmayın initialize_fn ve next_fn bizim algoritması için. next_fn kullanımı yapacak client_update ve server_update biz saf TensorFlow kodu kullanarak tanımlanır.

Ancak, bizim algoritma federe hesaplama yapmak için, biz de gerekecektir next_fn ve initialize_fn her bir olmak tff.federated_computation .

TensorFlow Birleşik blokları

Başlatma hesaplamasını oluşturma

İnitialize fonksiyonu oldukça basit olacaktır: Biz kullanarak bir model oluşturur model_fn . Ancak, biz kullanarak bizim TensorFlow kodunu ayırmak gerektiğini unutmayın tff.tf_computation .

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

Sonra kullanarak federe hesaplama doğrudan bu geçebilir tff.federated_value .

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

oluşturma next_fn

Artık gerçek algoritmayı yazmak için istemci ve sunucu güncelleme kodumuzu kullanıyoruz. Biz ilk bizim dönecek client_update bir içine tff.tf_computation bir istemci veri kümelerini ve sunucu ağırlıklarını kabul eder ve güncelleştirilmiş istemci ağırlıkları tensörünü çıkarır.

İşlevimizi uygun şekilde dekore etmek için ilgili türlere ihtiyacımız olacak. Neyse ki, sunucu ağırlıklarının türü doğrudan modelimizden çıkarılabilir.

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

Veri kümesi tipi imzasına bakalım. 28'e 28 görüntü (tamsayı etiketli) çektiğimizi ve düzleştirdiğimizi unutmayın.

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

Biz de bizim kullanarak Model ağırlıkları tipini çıkarabilir server_init yukarıdaki fonksiyonu.

model_weights_type = server_init.type_signature.result

Tip imzasını inceleyerek modelimizin mimarisini görebileceğiz!

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

Biz şimdi bizim oluşturabilir tff.tf_computation istemci güncelleme için.

@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 sunucusu güncellemenin sürüm zaten çıkarılan ettik türleri kullanarak, benzer şekilde tanımlanabilir.

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

Son fakat en az değil, biz oluşturmak için gereken tff.federated_computation bu her buluşmanızı getiriyor. Bu fonksiyon iki birleşik değerleri, bir (yerleşim sunucu ağırlıklarına karşılık gelen kabul tff.SERVER ) ve (yerleşim istemci veri setleri karşı gelen tff.CLIENTS ).

Her iki türün de yukarıda tanımlandığına dikkat edin! Biz sadece onlara kullanarak uygun yerleşimi vermek gerekir tff.FederatedType .

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

Bir FL algoritmasının 4 öğesini hatırlıyor musunuz?

  1. Sunucudan istemciye bir yayın adımı.
  2. Yerel bir istemci güncelleme adımı.
  3. İstemciden sunucuya yükleme adımı.
  4. Bir sunucu güncelleme adımı.

Yukarıdakileri oluşturduğumuza göre, her parça kompakt bir şekilde tek bir TFF kodu satırı olarak temsil edilebilir. Bu basitlik, birleşik türler gibi şeyleri belirtmek için ekstra özen göstermemiz gerekti!

@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

Şimdi bir var tff.federated_computation ve algoritmanın bir adım çalıştırmak için algoritma başlatma ikisi için. Algoritmayı bitirmek için, içine bu geçmesine tff.templates.IterativeProcess .

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

Tipi imza at atalım initialize ve next bizim iteratif sürecin fonksiyonları.

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

Bu gerçeğini yansıtır federated_algorithm.initialize no-Arg fonksiyonudur döndürdüğü (bir 784-ile-10 ağırlık matrisi ile ve 10 ön gerilim birimleri) tek katmanlı modeli.

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)'

İşte bunu görmek federated_algorithm.next bir sunucu modelini ve istemci verileri ve döner güncellenmiş bir sunucu modeli kabul eder.

Algoritmayı değerlendirmek

Birkaç tur koşalım ve kaybın nasıl değiştiğini görelim. İlk olarak, ikinci öğretici tartışılan merkezi bir yaklaşım kullanarak bir değerlendirme fonksiyonu tanımlayacaktır.

Önce merkezi bir değerlendirme veri seti oluşturuyoruz ve ardından eğitim verileri için kullandığımız ön işlemenin aynısını uyguluyoruz.

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

Ardından, bir sunucu durumunu kabul eden ve test veri kümesinde değerlendirmek için Keras'ı kullanan bir işlev yazıyoruz. Eğer aşina iseniz tf.Keras , bu irade bütün bakış tanıdık, nota rağmen kullanım 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)

Şimdi algoritmamızı başlatalım ve test seti üzerinde değerlendirelim.

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

Birkaç tur antrenman yapalım ve değişen bir şey var mı görelim.

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

Kayıp fonksiyonunda hafif bir düşüş görüyoruz. Sıçrayış küçük olsa da, sadece 15 eğitim turu ve küçük bir müşteri alt kümesi üzerinde gerçekleştirdik. Daha iyi sonuçlar görmek için binlerce olmasa da yüzlerce tur yapmamız gerekebilir.

Algoritmamızı değiştirme

Bu noktada duralım ve başardıklarımızı düşünelim. Saf TensorFlow kodunu (istemci ve sunucu güncellemeleri için) TFF'nin Federated Core'undan birleştirilmiş hesaplamalarla birleştirerek doğrudan Federe Ortalamayı uyguladık.

Daha karmaşık öğrenme gerçekleştirmek için, yukarıda sahip olduklarımızı basitçe değiştirebiliriz. Özellikle, yukarıdaki saf TF kodunu düzenleyerek, müşterinin eğitimi nasıl gerçekleştirdiğini veya sunucunun modelini nasıl güncellediğini değiştirebiliriz.

Hedef: Ekle gradyan kırpma için client_update fonksiyonu.

Daha büyük değişiklikler yapmak isteseydik, sunucunun daha fazla veri depolamasını ve yayınlamasını da sağlayabilirdik. Örneğin, sunucu ayrıca istemci öğrenme oranını da saklayabilir ve zamanla azalmasını sağlayabilir! Bu kullanılan tip imzaları değişiklik gerektireceğini Not tff.tf_computation yukarıda çağırır.

Harder Zorluk: istemcilerde oranı çürüme öğrenme ile Federe ortalamasını uygulayın.

Bu noktada, bu çerçevede uygulayabileceğiniz şeylerde ne kadar esneklik olduğunu fark etmeye başlayabilirsiniz. (Yukarıda sert bir meydan okuma cevap dahil) ilişkin fikirler için kaynak kodunu görebilirsiniz tff.learning.build_federated_averaging_process veya çeşitli kontrol araştırma projeleri TFF kullanılarak.