หน้านี้ได้รับการแปลโดย Cloud Translation API
Switch to English

การเรียนรู้แบบรวมศูนย์สำหรับการสร้างข้อความ

ดูใน TensorFlow.org เรียกใช้ใน Google Colab ดูแหล่งที่มาบน GitHub

บทช่วยสอนนี้สร้างขึ้นจากแนวคิดในแบบฝึกหัดการเรียนรู้แบบรวม ศูนย์สำหรับการจัดประเภทรูปภาพ และแสดงให้เห็นถึงแนวทางอื่น ๆ ที่เป็นประโยชน์สำหรับการเรียนรู้แบบรวมศูนย์

โดยเฉพาะอย่างยิ่งเราโหลดโมเดล Keras ที่ได้รับการฝึกฝนมาก่อนหน้านี้และปรับแต่งโดยใช้การฝึกอบรมแบบรวมศูนย์ในชุดข้อมูลแบบกระจายอำนาจ (จำลอง) สิ่งนี้มีความสำคัญในทางปฏิบัติด้วยเหตุผลหลายประการ ความสามารถในการใช้แบบจำลองอนุกรมทำให้ง่ายต่อการผสมผสานการเรียนรู้แบบรวมศูนย์กับวิธี ML อื่น ๆ นอกจากนี้ยังช่วยให้สามารถใช้โมเดลที่ได้รับการฝึกฝนมาแล้วที่หลากหลายมากขึ้นตัวอย่างเช่นโมเดลภาษาสำหรับการฝึกตั้งแต่เริ่มต้นนั้นแทบไม่จำเป็นเนื่องจากขณะนี้โมเดลที่ได้รับการฝึกฝนมาแล้วจำนวนมากมีวางจำหน่ายอย่างแพร่หลาย (ดูเช่น TF Hub ) ในทางกลับกันควรเริ่มจากแบบจำลองที่ได้รับการฝึกฝนมาก่อนและปรับแต่งโดยใช้การเรียนรู้แบบรวมศูนย์โดยปรับให้เข้ากับลักษณะเฉพาะของข้อมูลที่กระจายอำนาจสำหรับแอปพลิเคชันเฉพาะ

สำหรับบทช่วยสอนนี้เราเริ่มต้นด้วย RNN ที่สร้างอักขระ ASCII และปรับแต่งผ่านการเรียนรู้แบบรวมศูนย์ นอกจากนี้เรายังแสดงให้เห็นว่าน้ำหนักสุดท้ายสามารถป้อนกลับไปยังโมเดล Keras ดั้งเดิมได้อย่างไรทำให้สามารถประเมินและสร้างข้อความได้ง่ายโดยใช้เครื่องมือมาตรฐาน

!pip install --quiet --upgrade tensorflow_federated_nightly
!pip install --quiet --upgrade nest_asyncio

import nest_asyncio
nest_asyncio.apply()
import collections
import functools
import os
import time

import numpy as np
import tensorflow as tf
import tensorflow_federated as tff

np.random.seed(0)

# Test the TFF is working:
tff.federated_computation(lambda: 'Hello, World!')()
b'Hello, World!'

โหลดโมเดลที่ผ่านการฝึกอบรมมาแล้ว

เราโหลดแบบจำลองที่ได้รับการฝึกฝนมาก่อนตามบทช่วยสอน TensorFlow การ สร้างข้อความโดยใช้ RNN ด้วยการดำเนินการอย่างกระตือรือร้น อย่างไรก็ตามแทนที่จะได้รับการฝึกฝนเกี่ยวกับ The Complete Works of Shakespeare เราได้ฝึกแบบจำลองล่วงหน้าบนข้อความจาก A Tale of Two Cities และ A Christmas Carol ของ Charles Dickens

นอกเหนือจากการขยายคำศัพท์เราไม่ได้ปรับเปลี่ยนบทช่วยสอนดั้งเดิมดังนั้นโมเดลเริ่มต้นนี้จึงไม่ทันสมัย ​​แต่เป็นการคาดเดาที่สมเหตุสมผลและเพียงพอสำหรับจุดประสงค์ในการสอนของเรา โมเดลสุดท้ายถูกบันทึกด้วย tf.keras.models.save_model(include_optimizer=False)

เราจะใช้การเรียนรู้แบบรวมศูนย์เพื่อปรับโมเดลนี้สำหรับเชกสเปียร์ในบทช่วยสอนนี้โดยใช้ข้อมูลเวอร์ชันรวมที่ TFF ให้มา

สร้างตารางการค้นหาคำศัพท์

# A fixed vocabularly of ASCII chars that occur in the works of Shakespeare and Dickens:
vocab = list('dhlptx@DHLPTX $(,048cgkoswCGKOSW[_#\'/37;?bfjnrvzBFJNRVZ"&*.26:\naeimquyAEIMQUY]!%)-159\r')

# Creating a mapping from unique characters to indices
char2idx = {u:i for i, u in enumerate(vocab)}
idx2char = np.array(vocab)

โหลดแบบจำลองที่ผ่านการฝึกอบรมมาแล้วและสร้างข้อความ

def load_model(batch_size):
  urls = {
      1: 'https://storage.googleapis.com/tff-models-public/dickens_rnn.batch1.kerasmodel',
      8: 'https://storage.googleapis.com/tff-models-public/dickens_rnn.batch8.kerasmodel'}
  assert batch_size in urls, 'batch_size must be in ' + str(urls.keys())
  url = urls[batch_size]
  local_file = tf.keras.utils.get_file(os.path.basename(url), origin=url)  
  return tf.keras.models.load_model(local_file, compile=False)
def generate_text(model, start_string):
  # From https://www.tensorflow.org/tutorials/sequences/text_generation
  num_generate = 200
  input_eval = [char2idx[s] for s in start_string]
  input_eval = tf.expand_dims(input_eval, 0)
  text_generated = []
  temperature = 1.0

  model.reset_states()
  for i in range(num_generate):
    predictions = model(input_eval)
    predictions = tf.squeeze(predictions, 0)
    predictions = predictions / temperature
    predicted_id = tf.random.categorical(
        predictions, num_samples=1)[-1, 0].numpy()
    input_eval = tf.expand_dims([predicted_id], 0)
    text_generated.append(idx2char[predicted_id])

  return (start_string + ''.join(text_generated))
# Text generation requires a batch_size=1 model.
keras_model_batch1 = load_model(batch_size=1)
print(generate_text(keras_model_batch1, 'What of TensorFlow Federated, you ask? '))
Downloading data from https://storage.googleapis.com/tff-models-public/dickens_rnn.batch1.kerasmodel
16195584/16193984 [==============================] - 0s 0us/step
16203776/16193984 [==============================] - 0s 0us/step
What of TensorFlow Federated, you ask? Sall
yesterday. Received the Bailey."

"Mr. Lorry, grimmering himself, or low varked thends the winter, and the eyes of Monsieur
Defarge. "Let his mind, hon in his
life and message; four declare 

โหลดและประมวลผลข้อมูลเช็คสเปียร์รวมล่วงหน้า

แพ็กเกจ tff.simulation.datasets มีชุดข้อมูลที่หลากหลายซึ่งแบ่งออกเป็น "ไคลเอนต์" โดยที่ไคลเอ็นต์แต่ละตัวจะสอดคล้องกับชุดข้อมูลบนอุปกรณ์เฉพาะที่อาจเข้าร่วมในการเรียนรู้แบบรวมศูนย์

ชุดข้อมูลเหล่านี้ให้การกระจายข้อมูลที่ไม่ใช่ IID ที่เหมือนจริงซึ่งจำลองแบบจำลองความท้าทายในการฝึกอบรมกับข้อมูลที่กระจายอำนาจจริง การประมวลผลข้อมูลล่วงหน้าบางส่วนทำได้โดยใช้เครื่องมือจาก โครงการ Leaf ( github )

train_data, test_data = tff.simulation.datasets.shakespeare.load_data()

ชุดข้อมูลที่จัดทำโดย shakespeare.load_data() ประกอบด้วยลำดับของสตริง Tensors หนึ่งชุดสำหรับแต่ละบรรทัดที่พูดโดยอักขระเฉพาะในบทละครของเช็คสเปียร์ คีย์ไคลเอ็นต์ประกอบด้วยชื่อของการเล่นที่รวมเข้ากับชื่อของตัวละครตัวอย่างเช่น MUCH_ADO_ABOUT_NOTHING_OTHELLO สอดคล้องกับบรรทัดสำหรับอักขระ Othello ในบทละคร เรื่อง Much Ado About Nothing โปรดทราบว่าในสถานการณ์จำลองการเรียนรู้แบบรวมจริงไคลเอ็นต์จะไม่ถูกระบุหรือติดตามโดยรหัส แต่สำหรับการจำลองจะมีประโยชน์ในการทำงานกับชุดข้อมูลที่มีคีย์

ตัวอย่างเช่นที่นี่เราสามารถดูข้อมูลบางส่วนจาก King Lear:

# Here the play is "The Tragedy of King Lear" and the character is "King".
raw_example_dataset = train_data.create_tf_dataset_for_client(
    'THE_TRAGEDY_OF_KING_LEAR_KING')
# To allow for future extensions, each entry x
# is an OrderedDict with a single key 'snippets' which contains the text.
for x in raw_example_dataset.take(2):
  print(x['snippets'])
tf.Tensor(b'', shape=(), dtype=string)
tf.Tensor(b'What?', shape=(), dtype=string)

ตอนนี้เราใช้การแปลงtf.data.Dataset เพื่อเตรียมข้อมูลนี้สำหรับการฝึกถ่าน RNN ที่โหลดไว้ด้านบน

# Input pre-processing parameters
SEQ_LENGTH = 100
BATCH_SIZE = 8
BUFFER_SIZE = 100  # For dataset shuffling
# Construct a lookup table to map string chars to indexes,
# using the vocab loaded above:
table = tf.lookup.StaticHashTable(
    tf.lookup.KeyValueTensorInitializer(
        keys=vocab, values=tf.constant(list(range(len(vocab))),
                                       dtype=tf.int64)),
    default_value=0)


def to_ids(x):
  s = tf.reshape(x['snippets'], shape=[1])
  chars = tf.strings.bytes_split(s).values
  ids = table.lookup(chars)
  return ids


def split_input_target(chunk):
  input_text = tf.map_fn(lambda x: x[:-1], chunk)
  target_text = tf.map_fn(lambda x: x[1:], chunk)
  return (input_text, target_text)


def preprocess(dataset):
  return (
      # Map ASCII chars to int64 indexes using the vocab
      dataset.map(to_ids)
      # Split into individual chars
      .unbatch()
      # Form example sequences of SEQ_LENGTH +1
      .batch(SEQ_LENGTH + 1, drop_remainder=True)
      # Shuffle and form minibatches
      .shuffle(BUFFER_SIZE).batch(BATCH_SIZE, drop_remainder=True)
      # And finally split into (input, target) tuples,
      # each of length SEQ_LENGTH.
      .map(split_input_target))

โปรดทราบว่าในการสร้างลำดับดั้งเดิมและในการสร้างแบทช์ด้านบนเราใช้ drop_remainder=True เพื่อความเรียบง่าย ซึ่งหมายความว่าอักขระใด ๆ (ไคลเอนต์) ที่ไม่มีอย่างน้อย (SEQ_LENGTH + 1) * BATCH_SIZE ตัวอักษร (SEQ_LENGTH + 1) * BATCH_SIZE ของข้อความจะมีชุดข้อมูลว่างเปล่า วิธีการทั่วไปในการจัดการกับปัญหานี้คือการเติมแบทช์ด้วยโทเค็นพิเศษจากนั้นปกปิดการสูญเสียเพื่อไม่ให้คำนึงถึงโทเค็นการเติม

สิ่งนี้จะทำให้ตัวอย่างค่อนข้างซับซ้อนดังนั้นสำหรับบทช่วยสอนนี้เราจะใช้เฉพาะแบทช์แบบเต็มเช่นเดียวกับใน บทช่วยสอนมาตรฐาน อย่างไรก็ตามในการตั้งค่าแบบรวมศูนย์ปัญหานี้สำคัญกว่าเนื่องจากผู้ใช้หลายคนอาจมีชุดข้อมูลขนาดเล็ก

ตอนนี้เราสามารถประมวลผล raw_example_dataset ของเรา raw_example_dataset และตรวจสอบประเภท:

example_dataset = preprocess(raw_example_dataset)
print(example_dataset.element_spec)
(TensorSpec(shape=(8, 100), dtype=tf.int64, name=None), TensorSpec(shape=(8, 100), dtype=tf.int64, name=None))

รวบรวมแบบจำลองและทดสอบกับข้อมูลที่ประมวลผลล่วงหน้า

เราโหลดแบบจำลอง keras_model.evaluate ไม่ได้คอมไพล์ แต่ในการเรียกใช้ keras_model.evaluate เราจำเป็นต้องรวบรวมด้วยการสูญเสียและเมตริก นอกจากนี้เราจะรวบรวมในเครื่องมือเพิ่มประสิทธิภาพซึ่งจะใช้เป็นเครื่องมือเพิ่มประสิทธิภาพบนอุปกรณ์ในการเรียนรู้แบบรวมศูนย์

บทช่วยสอนดั้งเดิมไม่มีความแม่นยำระดับถ่าน (เศษของการคาดการณ์ที่ความน่าจะเป็นสูงสุดถูกใส่ลงในอักขระถัดไปที่ถูกต้อง) นี่เป็นเมตริกที่มีประโยชน์ดังนั้นเราจึงเพิ่มมันเข้าไป อย่างไรก็ตามเราจำเป็นต้องกำหนดคลาสเมตริกใหม่สำหรับสิ่งนี้เนื่องจากการคาดการณ์ของเรามีอันดับ 3 (เวกเตอร์ของบันทึกสำหรับการคาดการณ์ BATCH_SIZE * SEQ_LENGTH ) และ SparseCategoricalAccuracy คาดว่าจะมีการคาดการณ์อันดับ 2 เท่านั้น

class FlattenedCategoricalAccuracy(tf.keras.metrics.SparseCategoricalAccuracy):

  def __init__(self, name='accuracy', dtype=tf.float32):
    super().__init__(name, dtype=dtype)

  def update_state(self, y_true, y_pred, sample_weight=None):
    y_true = tf.reshape(y_true, [-1, 1])
    y_pred = tf.reshape(y_pred, [-1, len(vocab), 1])
    return super().update_state(y_true, y_pred, sample_weight)

ตอนนี้เราสามารถรวบรวมแบบจำลองและประเมินได้จาก example_dataset ของเรา

BATCH_SIZE = 8  # The training and eval batch size for the rest of this tutorial.
keras_model = load_model(batch_size=BATCH_SIZE)
keras_model.compile(
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=[FlattenedCategoricalAccuracy()])

# Confirm that loss is much lower on Shakespeare than on random data
loss, accuracy = keras_model.evaluate(example_dataset.take(5), verbose=0)
print(
    'Evaluating on an example Shakespeare character: {a:3f}'.format(a=accuracy))

# As a sanity check, we can construct some completely random data, where we expect
# the accuracy to be essentially random:
random_guessed_accuracy = 1.0 / len(vocab)
print('Expected accuracy for random guessing: {a:.3f}'.format(
    a=random_guessed_accuracy))
random_indexes = np.random.randint(
    low=0, high=len(vocab), size=1 * BATCH_SIZE * (SEQ_LENGTH + 1))
data = collections.OrderedDict(
    snippets=tf.constant(
        ''.join(np.array(vocab)[random_indexes]), shape=[1, 1]))
random_dataset = preprocess(tf.data.Dataset.from_tensor_slices(data))
loss, accuracy = keras_model.evaluate(random_dataset, steps=10, verbose=0)
print('Evaluating on completely random data: {a:.3f}'.format(a=accuracy))
Downloading data from https://storage.googleapis.com/tff-models-public/dickens_rnn.batch8.kerasmodel
16195584/16193984 [==============================] - 0s 0us/step
16203776/16193984 [==============================] - 0s 0us/step
Evaluating on an example Shakespeare character: 0.402000
Expected accuracy for random guessing: 0.012
Evaluating on completely random data: 0.011

ปรับโมเดลอย่างละเอียดด้วยการเรียนรู้แบบรวมศูนย์

TFF จัดลำดับการคำนวณ TensorFlow ทั้งหมดเพื่อให้สามารถทำงานได้ในสภาพแวดล้อมที่ไม่ใช่ Python (แม้ว่าในขณะนี้จะมีเพียงรันไทม์จำลองที่ใช้ใน Python เท่านั้น) แม้ว่าเราจะทำงานในโหมดกระตือรือร้น (TF 2.0) แต่ปัจจุบัน TFF ทำให้การคำนวณ TensorFlow เป็นอนุกรมโดยการสร้างหน่วยปฏิบัติการที่จำเป็นภายในบริบทของคำสั่ง " with tf.Graph.as_default() " ดังนั้นเราต้องจัดเตรียมฟังก์ชันที่ TFF สามารถใช้เพื่อแนะนำโมเดลของเราในกราฟที่ควบคุมได้ เราดำเนินการดังต่อไปนี้:

# Clone the keras_model inside `create_tff_model()`, which TFF will
# call to produce a new copy of the model inside the graph that it will 
# serialize. Note: we want to construct all the necessary objects we'll need 
# _inside_ this method.
def create_tff_model():
  # TFF uses an `input_spec` so it knows the types and shapes
  # that your model expects.
  input_spec = example_dataset.element_spec
  keras_model_clone = tf.keras.models.clone_model(keras_model)
  return tff.learning.from_keras_model(
      keras_model_clone,
      input_spec=input_spec,
      loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
      metrics=[FlattenedCategoricalAccuracy()])

ตอนนี้เราพร้อมที่จะสร้างกระบวนการวนซ้ำแบบรวมศูนย์ซึ่งเราจะใช้ในการปรับปรุงโมเดล (สำหรับรายละเอียดเกี่ยวกับอัลกอริทึมการเฉลี่ยแบบรวมศูนย์โปรดดูเอกสาร การเรียนรู้การสื่อสารที่มีประสิทธิภาพของเครือข่ายเชิงลึกจากข้อมูลที่กระจายอำนาจ )

เราใช้แบบจำลอง Keras ที่คอมไพล์แล้วเพื่อทำการประเมินผลมาตรฐาน (ไม่รวมศูนย์) หลังการฝึกอบรมแบบรวมศูนย์ในแต่ละรอบ สิ่งนี้มีประโยชน์สำหรับวัตถุประสงค์ในการวิจัยเมื่อทำการเรียนรู้แบบสหพันธ์จำลองและมีชุดข้อมูลการทดสอบมาตรฐาน

ในการตั้งค่าการผลิตที่เหมือนจริงอาจใช้เทคนิคเดียวกันนี้เพื่อนำแบบจำลองที่ได้รับการฝึกฝนด้วยการเรียนรู้แบบรวมศูนย์และประเมินโดยใช้ชุดข้อมูลมาตรฐานจากส่วนกลางเพื่อวัตถุประสงค์ในการทดสอบหรือการประกันคุณภาพ

# This command builds all the TensorFlow graphs and serializes them: 
fed_avg = tff.learning.build_federated_averaging_process(
    model_fn=create_tff_model,
    client_optimizer_fn=lambda: tf.keras.optimizers.SGD(lr=0.5))

นี่คือลูปที่ง่ายที่สุดที่เป็นไปได้โดยที่เรารันการหาค่าเฉลี่ยแบบรวมสำหรับหนึ่งรอบบนไคลเอนต์เดียวในแบทช์เดียว:

state = fed_avg.initialize()
state, metrics = fed_avg.next(state, [example_dataset.take(5)])
train_metrics = metrics['train']
print('loss={l:.3f}, accuracy={a:.3f}'.format(
    l=train_metrics['loss'], a=train_metrics['accuracy']))
loss=4.403, accuracy=0.132

ตอนนี้เรามาเขียนลูปการฝึกอบรมและการประเมินผลที่น่าสนใจกว่าเล็กน้อย

เพื่อให้การจำลองนี้ยังคงดำเนินไปค่อนข้างเร็วเราจึงฝึกอบรมลูกค้าสามคนเดียวกันในแต่ละรอบโดยพิจารณาเฉพาะมินิแบทช์สองตัวสำหรับแต่ละคน

def data(client, source=train_data):
  return preprocess(source.create_tf_dataset_for_client(client)).take(5)


clients = [
    'ALL_S_WELL_THAT_ENDS_WELL_CELIA', 'MUCH_ADO_ABOUT_NOTHING_OTHELLO',
]

train_datasets = [data(client) for client in clients]

# We concatenate the test datasets for evaluation with Keras by creating a 
# Dataset of Datasets, and then identity flat mapping across all the examples.
test_dataset = tf.data.Dataset.from_tensor_slices(
    [data(client, test_data) for client in clients]).flat_map(lambda x: x)

สถานะเริ่มต้นของโมเดลที่สร้างโดย fed_avg.initialize() ขึ้นอยู่กับตัวเริ่มต้นแบบสุ่มสำหรับโมเดล Keras ไม่ใช่น้ำหนักที่โหลดเนื่องจาก clone_model() ไม่ได้โคลนน้ำหนัก ในการเริ่มต้นการฝึกอบรมจากโมเดลที่ผ่านการฝึกอบรมมาแล้วเราตั้งค่าน้ำหนักของโมเดลในสถานะเซิร์ฟเวอร์โดยตรงจากโมเดลที่โหลด

NUM_ROUNDS = 5

# The state of the FL server, containing the model and optimization state.
state = fed_avg.initialize()

# Load our pre-trained Keras model weights into the global model state.
state = tff.learning.state_with_new_model_weights(
    state,
    trainable_weights=[v.numpy() for v in keras_model.trainable_weights],
    non_trainable_weights=[
        v.numpy() for v in keras_model.non_trainable_weights
    ])


def keras_evaluate(state, round_num):
  # Take our global model weights and push them back into a Keras model to
  # use its standard `.evaluate()` method.
  keras_model = load_model(batch_size=BATCH_SIZE)
  keras_model.compile(
      loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
      metrics=[FlattenedCategoricalAccuracy()])
  state.model.assign_weights_to(keras_model)
  loss, accuracy = keras_model.evaluate(example_dataset, steps=2, verbose=0)
  print('\tEval: loss={l:.3f}, accuracy={a:.3f}'.format(l=loss, a=accuracy))


for round_num in range(NUM_ROUNDS):
  print('Round {r}'.format(r=round_num))
  keras_evaluate(state, round_num)
  state, metrics = fed_avg.next(state, train_datasets)
  train_metrics = metrics['train']
  print('\tTrain: loss={l:.3f}, accuracy={a:.3f}'.format(
      l=train_metrics['loss'], a=train_metrics['accuracy']))

print('Final evaluation')
keras_evaluate(state, NUM_ROUNDS + 1)
Round 0
    Eval: loss=3.324, accuracy=0.401
    Train: loss=4.360, accuracy=0.155
Round 1
    Eval: loss=4.361, accuracy=0.049
    Train: loss=4.235, accuracy=0.164
Round 2
    Eval: loss=4.219, accuracy=0.177
    Train: loss=4.081, accuracy=0.221
Round 3
    Eval: loss=4.080, accuracy=0.174
    Train: loss=3.940, accuracy=0.226
Round 4
    Eval: loss=3.991, accuracy=0.176
    Train: loss=3.840, accuracy=0.226
Final evaluation
    Eval: loss=3.909, accuracy=0.171

ด้วยการเปลี่ยนแปลงเริ่มต้นเรายังไม่ได้ทำการฝึกอบรมมากพอที่จะสร้างความแตกต่างได้มาก แต่ถ้าคุณฝึกนานขึ้นกับข้อมูลของเชกสเปียร์มากขึ้นคุณจะเห็นความแตกต่างในรูปแบบของข้อความที่สร้างด้วยโมเดลที่อัปเดต

# Set our newly trained weights back in the originally created model.
keras_model_batch1.set_weights([v.numpy() for v in keras_model.weights])
# Text generation requires batch_size=1
print(generate_text(keras_model_batch1, 'What of TensorFlow Federated, you ask? '))
What of TensorFlow Federated, you ask? Shalways, I will call your
compet with any city brought their faces uncompany," besumed him. "When he
sticked Madame Defarge pushed the lamps.

"Have I often but no unison. She had probably come, 

ส่วนขยายที่แนะนำ

บทช่วยสอนนี้เป็นเพียงขั้นตอนแรก! ต่อไปนี้เป็นแนวคิดบางประการในการลองขยายสมุดบันทึกนี้:

  • เขียนลูปการฝึกอบรมที่เป็นจริงมากขึ้นซึ่งคุณสุ่มตัวอย่างลูกค้าเพื่อฝึกอบรมแบบสุ่ม
  • ใช้ ". .repeat(NUM_EPOCHS) " บนชุดข้อมูลไคลเอ็นต์เพื่อทดลองใช้การฝึกอบรมในพื้นที่หลาย ๆ ครั้ง (เช่นใน McMahan et. al. ) โปรดดูที่ Federated Learning for Image Classification ซึ่งทำเช่นนี้
  • เปลี่ยนคำสั่ง compile() เพื่อทดลองโดยใช้อัลกอริธึมการเพิ่มประสิทธิภาพที่แตกต่างกันบนไคลเอนต์
  • ลองใช้อาร์กิวเมนต์ server_optimizer เพื่อ build_federated_averaging_process เพื่อลองใช้อัลกอริทึมที่แตกต่างกันสำหรับการใช้การอัปเดตโมเดลบนเซิร์ฟเวอร์
  • ลองใช้อาร์กิวเมนต์ client_weight_fn เพื่อ build_federated_averaging_process เพื่อลองการให้น้ำหนักที่แตกต่างกันของไคลเอนต์ ไคลเอ็นต์น้ำหนักเริ่มต้นจะอัปเดตตามจำนวนตัวอย่างบนไคลเอนต์ แต่คุณสามารถทำได้เช่น client_weight_fn=lambda _: tf.constant(1.0)