চিত্র শ্রেণিবদ্ধকরণের জন্য ফেডারেটড লার্নিং

TensorFlow.org এ দেখুন Google Colab-এ চালান GitHub-এ উৎস দেখুন নোটবুক ডাউনলোড করুন

এই টিউটোরিয়ালে, আমরা ক্লাসিক MNIST প্রশিক্ষণ উদাহরণ ব্যবহার ফেডারেটেড শিক্ষণ (এফএল) TFF এর এপিআই স্তর, পরিচয় করিয়ে দিতে tff.learning - যে ফেডারেট লার্নিং কাজগুলো সাধারণ ধরনের সম্পাদন করতে ব্যবহার করা যেতে পারে উচ্চ স্তরের ইন্টারফেস একটি সেট যেমন ফেডারেটেড প্রশিক্ষণ, TensorFlow-এ বাস্তবায়িত ব্যবহারকারী-প্রদানকৃত মডেলগুলির বিরুদ্ধে।

এই টিউটোরিয়াল, এবং ফেডারেটেড লার্নিং এপিআই, মূলত এমন ব্যবহারকারীদের জন্য যারা তাদের নিজস্ব টেনসরফ্লো মডেলগুলিকে TFF-এ প্লাগ করতে চান, পরবর্তীটিকে বেশিরভাগই একটি ব্ল্যাক বক্স হিসাবে বিবেচনা করে। - TFF একটি মধ্যে গভীরতা বোঝার এবং কিভাবে আপনার নিজের ফেডারেট লার্নিং আলগোরিদিম বাস্তবায়ন করার জন্য, এফসি কোর API- এর উপর টিউটোরিয়াল দেখুন কাস্টম ফেডারেটেড আলগোরিদিম পার্ট 1 এবং পার্ট 2

আরো জানার জন্য tff.learning , অগ্রসর টেক্সট প্রজন্মের জন্য ফেডারেটেড শিক্ষণ , টিউটোরিয়াল পৌনঃপুনিক মডেলের আচ্ছাদন ছাড়াও, এছাড়াও মূল্যায়ন Keras ব্যবহার সঙ্গে মিলিত ফেডারেট লার্নিং সঙ্গে পরিশোধন জন্য একটি প্রাক প্রশিক্ষিত ধারাবাহিকভাবে Keras মডেল লোড প্রমান পারে।

আমরা শুরু করার আগে

আমরা শুরু করার আগে, আপনার পরিবেশ সঠিকভাবে সেটআপ করা হয়েছে তা নিশ্চিত করতে অনুগ্রহ করে নিম্নলিখিতটি চালান। আপনি যদি একটি অভিবাদন দেখতে না পান তাহলে, পড়ুন দয়া ইনস্টলেশন নির্দেশাবলীর জন্য গাইড।

# tensorflow_federated_nightly also bring in tf_nightly, which
# can causes a duplicate tensorboard install, leading to errors.
!pip uninstall --yes tensorboard tb-nightly

!pip install --quiet --upgrade tensorflow-federated-nightly
!pip install --quiet --upgrade nest-asyncio
!pip install --quiet --upgrade tb-nightly  # or tensorboard, but not both

import nest_asyncio
nest_asyncio.apply()
%load_ext tensorboard
import collections

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

np.random.seed(0)

tff.federated_computation(lambda: 'Hello, World!')()
b'Hello, World!'

ইনপুট ডেটা প্রস্তুত করা হচ্ছে

এর ডেটা দিয়ে শুরু করা যাক। ফেডারেটেড শেখার জন্য একটি ফেডারেটেড ডেটা সেট প্রয়োজন, অর্থাত্ একাধিক ব্যবহারকারীর ডেটা সংগ্রহ। ফেডারেটেড ডেটা সাধারণত অ হয় IID , যা চ্যালেঞ্জ একটি অনন্য সেট ভঙ্গি।

অর্ডার পরীক্ষা সহজতর করার জন্য, আমরা কয়েক ডেটাসেট সঙ্গে TFF সংগ্রহস্থলের যে একটি সংস্করণ রয়েছে MNIST একটি ফেডারেট সংস্করণ সহ বীজযুক্ত মূল, NIST ডেটা সেটটি ব্যবহার পুনরায় প্রক্রিয়াকরণ করা হয়েছে যে লিফ যাতে ডেটার মূল লেখক দ্বারা অস্থির হয় সংখ্যা যেহেতু প্রতিটি লেখকের একটি অনন্য শৈলী রয়েছে, তাই এই ডেটাসেটটি ফেডারেটেড ডেটাসেটের থেকে প্রত্যাশিত নন-আইআইডি আচরণ প্রদর্শন করে।

আমরা এটা কিভাবে লোড করতে পারি তা এখানে।

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

ডেটা সেট দ্বারা ফিরে load_data() উদাহরণ স্বরূপ ধরে tff.simulation.ClientData , একটি ইন্টারফেস যে আপনি ব্যবহারকারীদের সেট গনা, একটি গঠন করা করার অনুমতি দেয় tf.data.Dataset করে একটি নির্দিষ্ট ব্যবহারকারীর ডাটা প্রতিনিধিত্ব করে আর ক্যোয়ারীতে পৃথক উপাদানের গঠন। ডেটা সেটের বিষয়বস্তু অন্বেষণ করতে আপনি কীভাবে এই ইন্টারফেসটি ব্যবহার করতে পারেন তা এখানে। মনে রাখবেন যে এই ইন্টারফেসটি আপনাকে ক্লায়েন্ট আইডিগুলির উপর পুনরাবৃত্তি করতে দেয়, এটি শুধুমাত্র সিমুলেশন ডেটার একটি বৈশিষ্ট্য। আপনি শীঘ্রই দেখতে পাবেন, ক্লায়েন্ট আইডেন্টিটি ফেডারেটেড লার্নিং ফ্রেমওয়ার্ক দ্বারা ব্যবহৃত হয় না - তাদের একমাত্র উদ্দেশ্য হল আপনাকে সিমুলেশনের জন্য ডেটার উপসেট নির্বাচন করার অনুমতি দেওয়া।

len(emnist_train.client_ids)
3383
emnist_train.element_type_structure
OrderedDict([('label', TensorSpec(shape=(), dtype=tf.int32, name=None)), ('pixels', TensorSpec(shape=(28, 28), dtype=tf.float32, name=None))])
example_dataset = emnist_train.create_tf_dataset_for_client(
    emnist_train.client_ids[0])

example_element = next(iter(example_dataset))

example_element['label'].numpy()
1
from matplotlib import pyplot as plt
plt.imshow(example_element['pixels'].numpy(), cmap='gray', aspect='equal')
plt.grid(False)
_ = plt.show()

png

ফেডারেটেড ডেটাতে ভিন্নতা অন্বেষণ করা

ফেডারেটেড ডেটা সাধারণত অ হয় IID , ব্যবহারকারীরা সাধারণত ব্যবহার নিদর্শন উপর নির্ভর করে ডেটার বিভিন্ন ডিস্ট্রিবিউশন আছে। কিছু ক্লায়েন্টের ডিভাইসে কম প্রশিক্ষণের উদাহরণ থাকতে পারে, স্থানীয়ভাবে ডেটা স্বল্পতায় ভুগছে, যখন কিছু ক্লায়েন্টের যথেষ্ট প্রশিক্ষণের উদাহরণ রয়েছে। আমাদের উপলব্ধ EMNIST ডেটার সাথে একটি ফেডারেটেড সিস্টেমের সাধারণ ডেটা বৈচিত্র্যের এই ধারণাটি অন্বেষণ করা যাক। এটি লক্ষ্য করা গুরুত্বপূর্ণ যে একটি ক্লায়েন্টের ডেটার এই গভীর বিশ্লেষণ শুধুমাত্র আমাদের জন্য উপলব্ধ কারণ এটি একটি সিমুলেশন পরিবেশ যেখানে সমস্ত ডেটা স্থানীয়ভাবে আমাদের কাছে উপলব্ধ। একটি বাস্তব উত্পাদন ফেডারেটেড পরিবেশে আপনি একটি একক ক্লায়েন্টের ডেটা পরিদর্শন করতে সক্ষম হবেন না।

প্রথমে, আসুন একটি সিমুলেটেড ডিভাইসে উদাহরণগুলির জন্য একটি অনুভূতি পেতে একটি ক্লায়েন্টের ডেটার একটি নমুনা গ্রহণ করি৷ যেহেতু আমরা যে ডেটাসেটটি ব্যবহার করছি তা অনন্য লেখক দ্বারা চাবিকাঠি করা হয়েছে, একজন ক্লায়েন্টের ডেটা 0 থেকে 9 সংখ্যার একটি নমুনার জন্য একজন ব্যক্তির হাতের লেখার প্রতিনিধিত্ব করে, একজন ব্যবহারকারীর অনন্য "ব্যবহারের ধরণ" অনুকরণ করে।

## Example MNIST digits for one client
figure = plt.figure(figsize=(20, 4))
j = 0

for example in example_dataset.take(40):
  plt.subplot(4, 10, j+1)
  plt.imshow(example['pixels'].numpy(), cmap='gray', aspect='equal')
  plt.axis('off')
  j += 1

png

এখন প্রতিটি MNIST ডিজিটের লেবেলের জন্য প্রতিটি ক্লায়েন্টে উদাহরণের সংখ্যা কল্পনা করা যাক। ফেডারেটেড পরিবেশে, ব্যবহারকারীর আচরণের উপর নির্ভর করে প্রতিটি ক্লায়েন্টের উদাহরণের সংখ্যা বেশ কিছুটা পরিবর্তিত হতে পারে।

# Number of examples per layer for a sample of clients
f = plt.figure(figsize=(12, 7))
f.suptitle('Label Counts for a Sample of Clients')
for i in range(6):
  client_dataset = emnist_train.create_tf_dataset_for_client(
      emnist_train.client_ids[i])
  plot_data = collections.defaultdict(list)
  for example in client_dataset:
    # Append counts individually per label to make plots
    # more colorful instead of one color per plot.
    label = example['label'].numpy()
    plot_data[label].append(label)
  plt.subplot(2, 3, i+1)
  plt.title('Client {}'.format(i))
  for j in range(10):
    plt.hist(
        plot_data[j],
        density=False,
        bins=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

png

এখন প্রতিটি MNIST লেবেলের জন্য প্রতি ক্লায়েন্টের গড় চিত্রটি কল্পনা করা যাক। এই কোডটি একটি লেবেলের জন্য ব্যবহারকারীর সমস্ত উদাহরণের জন্য প্রতিটি পিক্সেল মানের গড় তৈরি করবে। আমরা দেখব যে প্রতিটি ব্যক্তির অনন্য হস্তাক্ষর শৈলীর কারণে একটি অঙ্কের জন্য একজন ক্লায়েন্টের গড় চিত্রটি একই অঙ্কের জন্য অন্য ক্লায়েন্টের গড় চিত্রের চেয়ে আলাদা দেখাবে। প্রতিটি স্থানীয় প্রশিক্ষণ রাউন্ড প্রতিটি ক্লায়েন্টে মডেলটিকে ভিন্ন দিকে নিয়ে যাবে সে সম্পর্কে আমরা ভাবতে পারি, কারণ আমরা সেই স্থানীয় রাউন্ডে সেই ব্যবহারকারীর নিজস্ব অনন্য ডেটা থেকে শিখছি। পরবর্তীতে টিউটোরিয়ালে আমরা দেখব কিভাবে আমরা সমস্ত ক্লায়েন্টের কাছ থেকে মডেলের প্রতিটি আপডেট নিতে পারি এবং তাদের একসাথে আমাদের নতুন গ্লোবাল মডেলে একত্রিত করতে পারি, যা আমাদের প্রতিটি ক্লায়েন্টের নিজস্ব অনন্য ডেটা থেকে শিখেছে।

# Each client has different mean images, meaning each client will be nudging
# the model in their own directions locally.

for i in range(5):
  client_dataset = emnist_train.create_tf_dataset_for_client(
      emnist_train.client_ids[i])
  plot_data = collections.defaultdict(list)
  for example in client_dataset:
    plot_data[example['label'].numpy()].append(example['pixels'].numpy())
  f = plt.figure(i, figsize=(12, 5))
  f.suptitle("Client #{}'s Mean Image Per Label".format(i))
  for j in range(10):
    mean_img = np.mean(plot_data[j], 0)
    plt.subplot(2, 5, j+1)
    plt.imshow(mean_img.reshape((28, 28)))
    plt.axis('off')

png

png

png

png

png

ব্যবহারকারীর ডেটা গোলমাল এবং অবিশ্বাস্যভাবে লেবেলযুক্ত হতে পারে। উদাহরণ স্বরূপ, উপরে ক্লায়েন্ট #2-এর ডেটা দেখে, আমরা দেখতে পাচ্ছি যে লেবেল 2-এর জন্য, এটা সম্ভব যে কিছু ভুল লেবেলযুক্ত উদাহরণ থাকতে পারে যা একটি শব্দের গড় চিত্র তৈরি করে।

ইনপুট ডেটা প্রিপ্রসেস করা হচ্ছে

যেহেতু ডেটা ইতিমধ্যে একটি হল tf.data.Dataset , প্রাক-প্রক্রিয়াকরণ ডেটা সেটটি রূপান্তরের ব্যবহার করা সম্ভব। এখানে, আমরা চেপ্টা 28x28 মধ্যে চিত্র 784 -element অ্যারে ব্যক্তি উদাহরণ এলোমেলো, তাদের ব্যাচে মধ্যে সংগঠিত, এবং থেকে বৈশিষ্ট্যগুলি নামান্তর pixels এবং label করার জন্য x এবং y Keras সাথে ব্যবহারের জন্য। এছাড়াও আমরা একটি মধ্যে নিক্ষেপ repeat বিভিন্ন সময়কাল চালানোর জন্য ডেটা সেট করে।

NUM_CLIENTS = 10
NUM_EPOCHS = 5
BATCH_SIZE = 20
SHUFFLE_BUFFER = 100
PREFETCH_BUFFER = 10

def preprocess(dataset):

  def batch_format_fn(element):
    """Flatten a batch `pixels` and return the features as an `OrderedDict`."""
    return collections.OrderedDict(
        x=tf.reshape(element['pixels'], [-1, 784]),
        y=tf.reshape(element['label'], [-1, 1]))

  return dataset.repeat(NUM_EPOCHS).shuffle(SHUFFLE_BUFFER, seed=1).batch(
      BATCH_SIZE).map(batch_format_fn).prefetch(PREFETCH_BUFFER)

এর কাজ যাচাই করা যাক.

preprocessed_example_dataset = preprocess(example_dataset)

sample_batch = tf.nest.map_structure(lambda x: x.numpy(),
                                     next(iter(preprocessed_example_dataset)))

sample_batch
OrderedDict([('x', array([[1., 1., 1., ..., 1., 1., 1.],
       [1., 1., 1., ..., 1., 1., 1.],
       [1., 1., 1., ..., 1., 1., 1.],
       ...,
       [1., 1., 1., ..., 1., 1., 1.],
       [1., 1., 1., ..., 1., 1., 1.],
       [1., 1., 1., ..., 1., 1., 1.]], dtype=float32)), ('y', array([[2],
       [1],
       [5],
       [7],
       [1],
       [7],
       [7],
       [1],
       [4],
       [7],
       [4],
       [2],
       [2],
       [5],
       [4],
       [1],
       [1],
       [0],
       [0],
       [9]], dtype=int32))])

ফেডারেটেড ডেটা সেট তৈরি করার জন্য আমাদের কাছে প্রায় সমস্ত বিল্ডিং ব্লক রয়েছে।

উপায়ে সিমুলেশন মধ্যে TFF করার ফেডারেট তথ্য ভোজন এক কেবল একটি পাইথন তালিকা হিসাবে হয়, কিনা একটি তালিকা হিসাবে অথবা একটি হিসাবে, একজন ব্যক্তি ব্যবহারকারী ডাটা ধারণ তালিকাটির প্রতিটি উপাদান সঙ্গে tf.data.Dataset । যেহেতু আমাদের ইতিমধ্যেই একটি ইন্টারফেস রয়েছে যা পরবর্তীটি সরবরাহ করে, আসুন এটি ব্যবহার করি।

এখানে একটি সাধারণ সাহায্যকারী ফাংশন রয়েছে যা প্রশিক্ষণ বা মূল্যায়নের একটি রাউন্ডে ইনপুট হিসাবে ব্যবহারকারীদের প্রদত্ত সেট থেকে ডেটাসেটের একটি তালিকা তৈরি করবে।

def make_federated_data(client_data, client_ids):
  return [
      preprocess(client_data.create_tf_dataset_for_client(x))
      for x in client_ids
  ]

এখন, আমরা কিভাবে ক্লায়েন্ট নির্বাচন করব?

একটি সাধারণ ফেডারেটেড প্রশিক্ষণের পরিস্থিতিতে, আমরা সম্ভাব্য ব্যবহারকারী ডিভাইসগুলির একটি খুব বড় জনসংখ্যার সাথে কাজ করছি, যার শুধুমাত্র একটি ভগ্নাংশ একটি নির্দিষ্ট সময়ে প্রশিক্ষণের জন্য উপলব্ধ হতে পারে। এই ক্ষেত্রে, উদাহরণস্বরূপ, যখন ক্লায়েন্ট ডিভাইসগুলি মোবাইল ফোন হয় যেগুলি শুধুমাত্র পাওয়ার সোর্সে প্লাগ ইন করার সময়, মিটারযুক্ত নেটওয়ার্কের বাইরে থাকা অবস্থায় এবং অন্যথায় নিষ্ক্রিয় অবস্থায় প্রশিক্ষণে অংশগ্রহণ করে।

অবশ্যই, আমরা একটি সিমুলেশন পরিবেশে আছি, এবং সমস্ত ডেটা স্থানীয়ভাবে উপলব্ধ। সাধারণত তখন, সিমুলেশন চালানোর সময়, আমরা প্রতিটি রাউন্ডের প্রশিক্ষণে জড়িত থাকার জন্য ক্লায়েন্টদের একটি এলোমেলো উপসেট নমুনা করব, সাধারণত প্রতিটি রাউন্ডে আলাদা।

তাই বলা হয়, আপনার উপর কাগজ অধ্যয়নরত খুঁজে বের করতে পারেন যেমন ফেডারেটেড গড় অ্যালগরিদম, প্রতিটি রাউন্ডে গ্রাহকদের এলোমেলোভাবে নমুনা সাব-সেট নির্বাচন সহ একটি সিস্টেমের অভিসৃতি অর্জনের কিছু সময় লাগতে পারে, এবং এটি চক্রের শত শত চালানোর জন্য আছে অকার্যকর এই ইন্টারেক্টিভ টিউটোরিয়াল।

পরিবর্তে আমরা যা করব তা হ'ল ক্লায়েন্টদের সেটকে একবার নমুনা করা, এবং কনভারজেন্সের গতি বাড়ানোর জন্য রাউন্ড জুড়ে একই সেট পুনরায় ব্যবহার করা (ইচ্ছাকৃতভাবে এই কয়েকটি ব্যবহারকারীর ডেটাতে অতিরিক্ত ফিটিং)। র্যান্ডম স্যাম্পলিং অনুকরণ করার জন্য এই টিউটোরিয়ালটি পরিবর্তন করার জন্য আমরা পাঠকের জন্য একটি অনুশীলন হিসাবে এটি ছেড়ে দিই - এটি করা মোটামুটি সহজ (আপনি একবার করলে, মনে রাখবেন যে মডেলটি একত্রিত হতে কিছুটা সময় লাগতে পারে)।

sample_clients = emnist_train.client_ids[0:NUM_CLIENTS]

federated_train_data = make_federated_data(emnist_train, sample_clients)

print('Number of client datasets: {l}'.format(l=len(federated_train_data)))
print('First dataset: {d}'.format(d=federated_train_data[0]))
Number of client datasets: 10
First dataset: <DatasetV1Adapter shapes: OrderedDict([(x, (None, 784)), (y, (None, 1))]), types: OrderedDict([(x, tf.float32), (y, tf.int32)])>

কেরাসের সাথে একটি মডেল তৈরি করা

আপনি যদি কেরাস ব্যবহার করেন তবে আপনার সম্ভবত ইতিমধ্যেই কোড রয়েছে যা কেরাস মডেল তৈরি করে। এখানে একটি সাধারণ মডেলের একটি উদাহরণ যা আমাদের প্রয়োজনের জন্য যথেষ্ট হবে।

def create_keras_model():
  return tf.keras.models.Sequential([
      tf.keras.layers.InputLayer(input_shape=(784,)),
      tf.keras.layers.Dense(10, kernel_initializer='zeros'),
      tf.keras.layers.Softmax(),
  ])

অর্ডার TFF সঙ্গে কোনো মডেল ব্যবহার করার জন্য, এটি একটি দৃষ্টান্ত আবৃত করা প্রয়োজন tff.learning.Model ইন্টারফেস, যা পদ্ধতি অনাবৃত Keras চাই, মডেলের ফরওয়ার্ড পাস, মেটাডেটা বৈশিষ্ট্য, ইত্যাদি স্ট্যাম্প একইভাবে, কিন্তু অতিরিক্ত প্রবর্তন উপাদান, যেমন ফেডারেটেড মেট্রিক্স গণনা করার প্রক্রিয়া নিয়ন্ত্রণ করার উপায়। আসুন আপাতত এই নিয়ে চিন্তা না করি; যদি আপনি এক আমরা শুধু উপরে সংজ্ঞায়িত করেছি মত একটি Keras মডেল আছে, তবে আপনি TFF আবাহন করার মাধ্যমে এটা আপনার জন্য মোড়ানো থাকতে পারে tff.learning.from_keras_model , মডেল এবং আর্গুমেন্ট হিসাবে একটি নমুনা তথ্য ব্যাচ পাশ নিচের চিত্রের মতন।

def model_fn():
  # We _must_ create a new model here, and _not_ capture it from an external
  # scope. TFF will call this within different graph contexts.
  keras_model = create_keras_model()
  return tff.learning.from_keras_model(
      keras_model,
      input_spec=preprocessed_example_dataset.element_spec,
      loss=tf.keras.losses.SparseCategoricalCrossentropy(),
      metrics=[tf.keras.metrics.SparseCategoricalAccuracy()])

ফেডারেটেড ডেটাতে মডেলকে প্রশিক্ষণ দেওয়া

এখন যে আমরা একটি মডেল হিসেবে আবৃত আছে tff.learning.Model TFF সাথে ব্যবহারের জন্য, আমরা TFF সাহায্যকারী ফাংশন invoking দ্বারা একটি ফেডারেটেড গড় অ্যালগরিদম গঠন করা দেওয়া যাবে tff.learning.build_federated_averaging_process , যেমন অনুসরণ করে।

মনে রাখবেন যে যুক্তি (যেমন একটি কন্সট্রাকটর করা প্রয়োজন model_fn , উপরে), কোনো ইতিমধ্যেই নির্মাণ উদাহরণস্বরূপ, যাতে আপনার মডেল নির্মাণের (ক প্রসঙ্গ TFF দ্বারা নিয়ন্ত্রিত ঘটতে পারেন যদি আপনি কারণ চলেছেন জানতে আগ্রহী এই, আমরা ফলো-আপ টিউটোরিয়াল পড়তে উত্সাহিত কাস্টম আলগোরিদিম )।

একটি _client অপটিমাইজার এবং _SERVER অপটিমাইজার: নীচের ফেডারেটেড গড় আলগোরিদিমের এক সমালোচনামূলক নোট, সেখানে 2 optimizers হয়। _Client অপটিমাইজার শুধুমাত্র প্রতিটি ক্লায়েন্টের স্থানীয় মডেল আপডেট গনা করতে ব্যবহৃত হয়। _SERVER অপটিমাইজার সার্ভার বিশ্বব্যাপী মডেলের গড় আপডেট প্রযোজ্য। বিশেষ করে, এর মানে হল যে অপ্টিমাইজারের পছন্দ এবং শেখার হার ব্যবহার করা একটি আদর্শ আইআইডি ডেটাসেটে মডেলকে প্রশিক্ষণ দেওয়ার জন্য আপনি যেগুলি ব্যবহার করেছেন তার থেকে আলাদা হতে হবে। আমরা নিয়মিত SGD দিয়ে শুরু করার পরামর্শ দিই, সম্ভবত স্বাভাবিকের চেয়ে ছোট শেখার হার দিয়ে। আমরা যে শেখার হার ব্যবহার করি তা যত্ন সহকারে টিউন করা হয়নি, নির্দ্বিধায় পরীক্ষা করুন।

iterative_process = tff.learning.build_federated_averaging_process(
    model_fn,
    client_optimizer_fn=lambda: tf.keras.optimizers.SGD(learning_rate=0.02),
    server_optimizer_fn=lambda: tf.keras.optimizers.SGD(learning_rate=1.0))

এটা ঠিক কি ঘটল? TFF ফেডারেট কম্পিউটেশন একজোড়া নির্মাণ এবং তাদেরকে একটি মধ্যে প্যাকেজ করেছে tff.templates.IterativeProcess যেমন বৈশিষ্ট্য একজোড়া যা এই কম্পিউটেশন উপলভ্য initialize এবং next

সংক্ষেপে, সংযুক্ত কম্পিউটেশন TFF অভ্যন্তরীণ ভাষায় প্রোগ্রাম বিভিন্ন ফেডারেট আলগোরিদিম প্রকাশ করতে পারেন হয় (আপনি এই সম্পর্কে আরো জানতে পারেন কাস্টম আলগোরিদিম টিউটোরিয়াল)। এই ক্ষেত্রে, দুই কম্পিউটেশন তৈরি এবং বস্তাবন্দী মধ্যে iterative_process বাস্তবায়ন ফেডারেটেড গড়

TFF-এর লক্ষ্য হল গণনাগুলিকে এমনভাবে সংজ্ঞায়িত করা যাতে সেগুলি বাস্তব ফেডারেটেড লার্নিং সেটিংসে কার্যকর করা যায়, কিন্তু বর্তমানে শুধুমাত্র স্থানীয় এক্সিকিউশন সিমুলেশন রানটাইম প্রয়োগ করা হয়। একটি সিমুলেটরে একটি গণনা চালানোর জন্য, আপনি কেবল এটিকে পাইথন ফাংশনের মতো আহ্বান করেন। এই ডিফল্ট ব্যাখ্যা করা পরিবেশটি উচ্চ কার্যকারিতার জন্য ডিজাইন করা হয়নি, তবে এটি এই টিউটোরিয়ালের জন্য যথেষ্ট হবে; আমরা আশা করি ভবিষ্যতে রিলিজে বৃহত্তর গবেষণার সুবিধার্থে উচ্চ-কার্যক্ষমতা সম্পন্ন সিমুলেশন রানটাইম প্রদান করবে।

এর দিয়ে শুরু করা যাক initialize গণনার। সমস্ত ফেডারেটেড গণনার ক্ষেত্রে যেমন, আপনি এটিকে একটি ফাংশন হিসাবে ভাবতে পারেন। গণনা কোন যুক্তি নেয় না, এবং একটি ফলাফল প্রদান করে - সার্ভারে ফেডারেটেড গড় প্রক্রিয়ার অবস্থার প্রতিনিধিত্ব। যদিও আমরা TFF-এর বিশদ বিবরণে ডুব দিতে চাই না, তবে এই অবস্থাটি কেমন তা দেখতে শিক্ষণীয় হতে পারে। আপনি নিম্নলিখিত হিসাবে এটি কল্পনা করতে পারেন.

str(iterative_process.initialize.type_signature)
'( -> <model=<trainable=<float32[784,10],float32[10]>,non_trainable=<>>,optimizer_state=<int64>,delta_aggregate_state=<value_sum_process=<>,weight_sum_process=<>>,model_broadcast_state=<>>@SERVER)'

উপরে টাইপ স্বাক্ষর প্রথম একটু রহস্যপূর্ণ মনে হতে পারে, চিনতে পারে যে সার্ভার রাষ্ট্র একটি নিয়ে গঠিত model (MNIST জন্য প্রারম্ভিক মডেল প্যারামিটার সমস্ত ডিভাইসে বিতরণ করা হবে), এবং optimizer_state (অতিরিক্ত তথ্য সার্ভার দ্বারা পরিচালিত, যেমন হাইপারপ্যারামিটার সময়সূচীর জন্য ব্যবহার করার জন্য রাউন্ডের সংখ্যা, ইত্যাদি)।

ডাকা যাক initialize গণনার সার্ভারের রাষ্ট্রের গঠন করা।

state = iterative_process.initialize()

ফেডারেট কম্পিউটেশন জোড়া দ্বিতীয়, next , গ্রাহকদের ফেডারেটেড গড়, সার্ভার রাজ্য (মডেল পরামিতি সহ) ঠেলাঠেলি নিয়ে গঠিত যা একটি একক বৃত্তাকার প্রতিনিধিত্ব করে-ডিভাইস গড় মডেল আপডেট তাদের স্থানীয় ডেটার উপর প্রশিক্ষণ, সংগ্রহ ও , এবং সার্ভারে একটি নতুন আপডেট মডেল তৈরি করা।

ধারণার দিক থেকে, আপনি মনে করতে পারেন next একটি কার্মিক টাইপ স্বাক্ষর যে হচ্ছে নিম্নরূপ তার হিসাবে।

SERVER_STATE, FEDERATED_DATA -> SERVER_STATE, TRAINING_METRICS

বিশেষ করে, এক সম্পর্কে চিন্তা করা উচিত next() ইনপুট কিছু সার্ভার (দ্বারা উপলব্ধ করা হয় - একটি ফাংশন যা কোনো সার্ভারে রান, বরং সমগ্র বিকেন্দ্রীভূত গণনার একটি ঘোষণামূলক কার্মিক উপস্থাপনা হচ্ছে হচ্ছে না SERVER_STATE ), কিন্তু প্রতিটি অংশগ্রহণকারী ডিভাইস তার নিজস্ব স্থানীয় ডেটাসেটে অবদান রাখে।

আসুন প্রশিক্ষণের একটি একক রাউন্ড চালাই এবং ফলাফলগুলি কল্পনা করি। ব্যবহারকারীদের নমুনার জন্য আমরা ইতিমধ্যে উপরে তৈরি করা ফেডারেটেড ডেটা ব্যবহার করতে পারি।

state, metrics = iterative_process.next(state, federated_train_data)
print('round  1, metrics={}'.format(metrics))
round  1, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.12345679), ('loss', 3.1193738)])), ('stat', OrderedDict([('num_examples', 4860)]))])

এর আরো কয়েক রাউন্ড চালানো যাক. যেমনটি আগে উল্লেখ করা হয়েছে, সাধারণত এই মুহুর্তে আপনি প্রতিটি রাউন্ডের জন্য ব্যবহারকারীদের একটি নতুন এলোমেলোভাবে নির্বাচিত নমুনা থেকে আপনার সিমুলেশন ডেটার একটি উপসেট বেছে নেবেন যাতে একটি বাস্তবসম্মত স্থাপনার অনুকরণ করা যায় যাতে ব্যবহারকারীরা ক্রমাগত আসে এবং যায়, কিন্তু এই ইন্টারেক্টিভ নোটবুকে, প্রদর্শনের খাতিরে আমরা একই ব্যবহারকারীদের পুনরায় ব্যবহার করব, যাতে সিস্টেমটি দ্রুত একত্রিত হয়।

NUM_ROUNDS = 11
for round_num in range(2, NUM_ROUNDS):
  state, metrics = iterative_process.next(state, federated_train_data)
  print('round {:2d}, metrics={}'.format(round_num, metrics))
round  2, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.13518518), ('loss', 2.9834728)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round  3, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.14382716), ('loss', 2.861665)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round  4, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.17407407), ('loss', 2.7957022)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round  5, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.19917695), ('loss', 2.6146567)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round  6, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.21975309), ('loss', 2.529761)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round  7, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.2409465), ('loss', 2.4053504)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round  8, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.2611111), ('loss', 2.315389)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round  9, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.30823046), ('loss', 2.1240263)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round 10, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.33312756), ('loss', 2.1164262)])), ('stat', OrderedDict([('num_examples', 4860)]))])

ফেডারেটেড প্রশিক্ষণের প্রতিটি রাউন্ডের পরে প্রশিক্ষণের ক্ষতি হ্রাস পাচ্ছে, যা নির্দেশ করে যে মডেলটি একত্রিত হচ্ছে। এসব প্রশিক্ষণ বৈশিষ্ট্যের মান সঙ্গে কিছু গুরুত্বপূর্ণ আদেশ সহকারে হয়, তবে, পরে এই টিউটোরিয়ালে মূল্যায়ন উপর অধ্যায় দেখুন।

টেনসরবোর্ডে মডেল মেট্রিক্স প্রদর্শন করা হচ্ছে

এর পরে, আসুন টেনসরবোর্ড ব্যবহার করে এই ফেডারেটেড গণনাগুলি থেকে মেট্রিকগুলি কল্পনা করি।

মেট্রিক্স লিখতে নির্দেশিকা এবং সংশ্লিষ্ট সারাংশ লেখক তৈরি করে শুরু করা যাক।

logdir = "/tmp/logs/scalars/training/"
summary_writer = tf.summary.create_file_writer(logdir)
state = iterative_process.initialize()

একই সারাংশ লেখকের সাথে প্রাসঙ্গিক স্কেলার মেট্রিক্স প্লট করুন।

with summary_writer.as_default():
  for round_num in range(1, NUM_ROUNDS):
    state, metrics = iterative_process.next(state, federated_train_data)
    for name, value in metrics['train'].items():
      tf.summary.scalar(name, value, step=round_num)

উপরে উল্লিখিত রুট লগ ডিরেক্টরি দিয়ে TensorBoard শুরু করুন। ডেটা লোড হতে কয়েক সেকেন্ড সময় লাগতে পারে।

!ls {logdir}
%tensorboard --logdir {logdir} --port=0
events.out.tfevents.1629557449.ebe6e776479e64ea-4903924a278.borgtask.google.com.458912.1.v2
Launching TensorBoard...
Reusing TensorBoard on port 50681 (pid 292785), started 0:30:30 ago. (Use '!kill 292785' to kill it.)
<IPython.core.display.Javascript at 0x7fd6617e02d0>
# Uncomment and run this this cell to clean your directory of old output for
# future graphs from this directory. We don't run it by default so that if 
# you do a "Runtime > Run all" you don't lose your results.

# !rm -R /tmp/logs/scalars/*

একইভাবে মূল্যায়নের মেট্রিক্স দেখার জন্য, আপনি টেনসরবোর্ডে লিখতে "লগ/স্ক্যালার/ইভাল" এর মতো একটি পৃথক ইভাল ফোল্ডার তৈরি করতে পারেন।

মডেল বাস্তবায়ন কাস্টমাইজ করা

Keras হয় TensorFlow জন্য প্রস্তাবিত উচ্চ পর্যায়ের মডেল এপিআই , এবং আমরা Keras মডেল ব্যবহার করে (মাধ্যমে উৎসাহিত tff.learning.from_keras_model TFF মধ্যে) যখনই সম্ভব।

যাইহোক, tff.learning একটি নিম্ন স্তরের মডেল ইন্টারফেস, উপলব্ধ tff.learning.Model , যে সংক্ষিপ্ত কার্যকারিতা ফেডারেট শেখার জন্য একটি মডেল ব্যবহার করার জন্য প্রয়োজনীয় অনাবৃত। সরাসরি এই ইন্টারফেস বাস্তবায়ন (সম্ভবত এখনও মত ব্লক নির্মাণের ব্যবহার tf.keras.layers ) সর্বাধিক স্বনির্ধারণ জন্য ফেডারেট লার্নিং আলগোরিদিম অভ্যন্তরীণ পরিবর্তন ছাড়া পারেন।

সুতরাং এর স্ক্র্যাচ থেকে আবার সব এটা করা যাক.

মডেল ভেরিয়েবল, ফরোয়ার্ড পাস, এবং মেট্রিক্স সংজ্ঞায়িত করা

প্রথম ধাপ হল TensorFlow ভেরিয়েবলগুলিকে চিহ্নিত করা যার সাথে আমরা কাজ করতে যাচ্ছি। নিম্নলিখিত কোডটিকে আরও সুস্পষ্ট করার জন্য, পুরো সেটটিকে উপস্থাপন করার জন্য একটি ডেটা কাঠামো সংজ্ঞায়িত করা যাক। এই যেমন ভেরিয়েবল অন্তর্ভুক্ত করা হবে weights এবং bias যে আমরা শেখাতে হবে, সেইসাথে ভেরিয়েবল যে এই ধরনের বিভিন্ন ক্রমসঞ্চিত পরিসংখ্যান এবং কাউন্টারে আমরা প্রশিক্ষণের সময় আপডেট হবে, রাখা হবে loss_sum , accuracy_sum এবং num_examples

MnistVariables = collections.namedtuple(
    'MnistVariables', 'weights bias num_examples loss_sum accuracy_sum')

এখানে একটি পদ্ধতি যা ভেরিয়েবল তৈরি করে। সরলতা অনুরোধে জন্য, আমরা সব পরিসংখ্যান প্রতিনিধিত্ব tf.float32 , যেমন যে পরবর্তী পর্যায়ে টাইপ ধর্মান্তর প্রয়োজনীয়তা দূর হবে। Lambdas যেমন পরিবর্তনশীল initializers মোড়ানো প্রয়োজন দ্বারা আরোপিত হয় রিসোর্স ভেরিয়েবল

def create_mnist_variables():
  return MnistVariables(
      weights=tf.Variable(
          lambda: tf.zeros(dtype=tf.float32, shape=(784, 10)),
          name='weights',
          trainable=True),
      bias=tf.Variable(
          lambda: tf.zeros(dtype=tf.float32, shape=(10)),
          name='bias',
          trainable=True),
      num_examples=tf.Variable(0.0, name='num_examples', trainable=False),
      loss_sum=tf.Variable(0.0, name='loss_sum', trainable=False),
      accuracy_sum=tf.Variable(0.0, name='accuracy_sum', trainable=False))

মডেল প্যারামিটার এবং ক্রমবর্ধমান পরিসংখ্যানের ভেরিয়েবলের সাথে, আমরা এখন ফরওয়ার্ড পাস পদ্ধতিটি সংজ্ঞায়িত করতে পারি যা ক্ষতি গণনা করে, পূর্বাভাস নির্গত করে এবং ইনপুট ডেটার একক ব্যাচের জন্য ক্রমবর্ধমান পরিসংখ্যান আপডেট করে, নিম্নরূপ।

def predict_on_batch(variables, x):
  return tf.nn.softmax(tf.matmul(x, variables.weights) + variables.bias)

def mnist_forward_pass(variables, batch):
  y = predict_on_batch(variables, batch['x'])
  predictions = tf.cast(tf.argmax(y, 1), tf.int32)

  flat_labels = tf.reshape(batch['y'], [-1])
  loss = -tf.reduce_mean(
      tf.reduce_sum(tf.one_hot(flat_labels, 10) * tf.math.log(y), axis=[1]))
  accuracy = tf.reduce_mean(
      tf.cast(tf.equal(predictions, flat_labels), tf.float32))

  num_examples = tf.cast(tf.size(batch['y']), tf.float32)

  variables.num_examples.assign_add(num_examples)
  variables.loss_sum.assign_add(loss * num_examples)
  variables.accuracy_sum.assign_add(accuracy * num_examples)

  return loss, predictions

এর পরে, আমরা একটি ফাংশন সংজ্ঞায়িত করি যা স্থানীয় মেট্রিক্সের একটি সেট ফেরত দেয়, আবার TensorFlow ব্যবহার করে। এই মানগুলি (মডেল আপডেটগুলি ছাড়াও, যা স্বয়ংক্রিয়ভাবে পরিচালনা করা হয়) যা একটি ফেডারেটেড লার্নিং বা মূল্যায়ন প্রক্রিয়াতে সার্ভারে একত্রিত হওয়ার যোগ্য৷

এখানে, কেবলমাত্র আমরা গড় আসতে loss এবং accuracy , সেইসাথে num_examples , যা আমরা ফেডারেট দলা কম্পিউটিং যখন সঠিকভাবে বিভিন্ন ব্যবহারকারীদের কাছ থেকে অবদান ওজন করতে হবে।

def get_local_mnist_metrics(variables):
  return collections.OrderedDict(
      num_examples=variables.num_examples,
      loss=variables.loss_sum / variables.num_examples,
      accuracy=variables.accuracy_sum / variables.num_examples)

পরিশেষে, আমরা তা নির্ধারণ করতে স্থানীয় মাধ্যমে একে ডিভাইস দ্বারা নির্গত মেট্রিক্স সমষ্টি কিভাবে প্রয়োজন get_local_mnist_metrics । এই কোড যে TensorFlow লেখা নেই এমন একটি অংশ মাত্র - এটি একটি ফেডারেট গণনার TFF প্রকাশ করে। আপনি গভীর খনন করতে চান তাহলে, ওভার সর পড়া কাস্টম আলগোরিদিম টিউটোরিয়াল, কিন্তু অধিকাংশ অ্যাপ্লিকেশন, আপনি কি সত্যিই করার প্রয়োজন হবে না; নীচে দেখানো প্যাটার্নের বৈকল্পিক যথেষ্ট হওয়া উচিত। এটি দেখতে কেমন তা এখানে রয়েছে:

@tff.federated_computation
def aggregate_mnist_metrics_across_clients(metrics):
  return collections.OrderedDict(
      num_examples=tff.federated_sum(metrics.num_examples),
      loss=tff.federated_mean(metrics.loss, metrics.num_examples),
      accuracy=tff.federated_mean(metrics.accuracy, metrics.num_examples))

ইনপুট metrics আর্গুমেন্ট প্রাপ্ত করতে অনুরূপ OrderedDict দ্বারা ফিরে get_local_mnist_metrics উপরে কিন্তু সমালোচকদের মান আর হয় tf.Tensors - তারা হিসাবে "boxed" হয় tff.Value s, আমাদের আপনি আর TensorFlow ব্যবহার করে সেগুলি নিপূণভাবে পারে সেই বিষয়ে পরিস্কার করা, কিন্তু শুধুমাত্র মত TFF এর ফেডারেট অপারেটর ব্যবহার করে tff.federated_mean এবং tff.federated_sum । বিশ্বব্যাপী সমষ্টির প্রত্যাবর্তিত অভিধান সার্ভারে উপলব্ধ মেট্রিক্সের সেটকে সংজ্ঞায়িত করে।

এর একটি দৃষ্টান্ত নির্মাণের tff.learning.Model

উপরের সবকটি জায়গায় রেখে, আমরা TFF-এর সাথে ব্যবহারের জন্য একটি মডেল উপস্থাপনা তৈরি করতে প্রস্তুত যা আপনার জন্য তৈরি হয় যখন আপনি TFF কে কেরাস মডেল গ্রহণ করতে দেন।

from typing import Callable, List, OrderedDict

class MnistModel(tff.learning.Model):

  def __init__(self):
    self._variables = create_mnist_variables()

  @property
  def trainable_variables(self):
    return [self._variables.weights, self._variables.bias]

  @property
  def non_trainable_variables(self):
    return []

  @property
  def local_variables(self):
    return [
        self._variables.num_examples, self._variables.loss_sum,
        self._variables.accuracy_sum
    ]

  @property
  def input_spec(self):
    return collections.OrderedDict(
        x=tf.TensorSpec([None, 784], tf.float32),
        y=tf.TensorSpec([None, 1], tf.int32))

  @tf.function
  def predict_on_batch(self, x, training=True):
    del training
    return predict_on_batch(self._variables, x)

  @tf.function
  def forward_pass(self, batch, training=True):
    del training
    loss, predictions = mnist_forward_pass(self._variables, batch)
    num_exmaples = tf.shape(batch['x'])[0]
    return tff.learning.BatchOutput(
        loss=loss, predictions=predictions, num_examples=num_exmaples)

  @tf.function
  def report_local_outputs(self):
    return get_local_mnist_metrics(self._variables)

  @property
  def federated_output_computation(self):
    return aggregate_mnist_metrics_across_clients

  @tf.function
  def report_local_unfinalized_metrics(
      self) -> OrderedDict[str, List[tf.Tensor]]:
    """Creates an `OrderedDict` of metric names to unfinalized values."""
    return collections.OrderedDict(
        num_examples=[self._variables.num_examples],
        loss=[self._variables.loss_sum, self._variables.num_examples],
        accuracy=[self._variables.accuracy_sum, self._variables.num_examples])

  def metric_finalizers(
      self) -> OrderedDict[str, Callable[[List[tf.Tensor]], tf.Tensor]]:
    """Creates an `OrderedDict` of metric names to finalizers."""
    return collections.OrderedDict(
        num_examples=tf.function(func=lambda x: x[0]),
        loss=tf.function(func=lambda x: x[0] / x[1]),
        accuracy=tf.function(func=lambda x: x[0] / x[1]))

যেহেতু আপনি দেখতে পারেন, বিমূর্ত পদ্ধতি ও বৈশিষ্ট্য দ্বারা সংজ্ঞায়িত tff.learning.Model পূর্ববর্তী অধ্যায় যে ভেরিয়েবল চালু ও ক্ষতি ও পরিসংখ্যান সংজ্ঞায়িত কোড স্নিপেট অনুরূপ।

এখানে হাইলাইট করার মতো কয়েকটি পয়েন্ট রয়েছে:

  • সকল রাষ্ট্র যে আপনার মডেল, ব্যবহার করবে TensorFlow ভেরিয়েবল যেমন বন্দী করা আবশ্যক হিসাবে TFF (রানটাইম এ পাইথন ব্যবহার করে না আপনার কোড স্মরণ যাতে তা মোবাইল ডিভাইসে স্থাপন করা যাবে লিখতে হবে; দেখতে কাস্টম আলগোরিদিম একটি আরো গভীর জন্য টিউটোরিয়াল কারণ সম্পর্কে ভাষ্য)।
  • আপনার মডেল বর্ণনা করা উচিত ডেটার কি ফর্ম এটিকে স্বীকার করলে ( input_spec সাধারণভাবে), কারণ যে TFF একটি জোরালোভাবে টাইপ পরিবেশ এবং সব উপাদান জন্য টাইপ স্বাক্ষর নির্ধারণ করতে চায়। আপনার মডেলের ইনপুটের বিন্যাস ঘোষণা করা এটির একটি অপরিহার্য অংশ।
  • যদিও টেকনিক্যালি প্রয়োজন হয় না, আমরা সব TensorFlow যুক্তিবিজ্ঞান (ফরওয়ার্ড পাস, মেট্রিক গণনার, ইত্যাদি) মোড়কে সুপারিশ tf.function , এস হিসাবে এই নিশ্চিত TensorFlow ধারাবাহিকভাবে যাবে সাহায্য করে, এবং স্পষ্ট নিয়ন্ত্রণ নির্ভরতা প্রয়োজনীয়তার সরিয়ে ফেলা হয়।

ফেডারেটেড SGD-এর মতো মূল্যায়ন এবং অ্যালগরিদমের জন্য উপরেরটি যথেষ্ট। যাইহোক, ফেডারেটেড এভারেজিংয়ের জন্য, প্রতিটি ব্যাচে মডেলটিকে স্থানীয়ভাবে কীভাবে প্রশিক্ষণ দেওয়া উচিত তা আমাদের নির্দিষ্ট করতে হবে। ফেডারেটেড এভারেজিং অ্যালগরিদম তৈরি করার সময় আমরা একটি স্থানীয় অপ্টিমাইজার নির্দিষ্ট করব।

নতুন মডেলের সাথে ফেডারেটেড প্রশিক্ষণের অনুকরণ

উপরের সবগুলি জায়গায় রেখে, প্রক্রিয়াটির অবশিষ্টাংশ আমরা ইতিমধ্যে যা দেখেছি সেরকম দেখায় - শুধু আমাদের নতুন মডেল ক্লাসের কন্সট্রাক্টরের সাথে মডেল কনস্ট্রাক্টরকে প্রতিস্থাপন করুন, এবং আপনি চক্রের মাধ্যমে তৈরি করা পুনরাবৃত্তিমূলক প্রক্রিয়াতে দুটি ফেডারেটেড গণনা ব্যবহার করুন প্রশিক্ষণ রাউন্ড।

iterative_process = tff.learning.build_federated_averaging_process(
    MnistModel,
    client_optimizer_fn=lambda: tf.keras.optimizers.SGD(learning_rate=0.02))
state = iterative_process.initialize()
state, metrics = iterative_process.next(state, federated_train_data)
print('round  1, metrics={}'.format(metrics))
round  1, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 3.0708053), ('accuracy', 0.12777779)])), ('stat', OrderedDict([('num_examples', 4860)]))])
for round_num in range(2, 11):
  state, metrics = iterative_process.next(state, federated_train_data)
  print('round {:2d}, metrics={}'.format(round_num, metrics))
round  2, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 3.011699), ('accuracy', 0.13024691)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round  3, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.7408307), ('accuracy', 0.15576132)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round  4, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.6761012), ('accuracy', 0.17921811)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round  5, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.675567), ('accuracy', 0.1855967)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round  6, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.5664043), ('accuracy', 0.20329218)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round  7, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.4179392), ('accuracy', 0.24382716)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round  8, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.3237286), ('accuracy', 0.26687244)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round  9, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.1861682), ('accuracy', 0.28209877)])), ('stat', OrderedDict([('num_examples', 4860)]))])
round 10, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('mean_value', ()), ('mean_weight', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.046388), ('accuracy', 0.32037038)])), ('stat', OrderedDict([('num_examples', 4860)]))])

TensorBoard-এর মধ্যে এই মেট্রিকগুলি দেখতে, উপরে তালিকাভুক্ত ধাপগুলি "টেনসরবোর্ডে মডেল মেট্রিক্স প্রদর্শন করা" দেখুন৷

মূল্যায়ন

আমাদের সমস্ত পরীক্ষা-নিরীক্ষা এখন পর্যন্ত শুধুমাত্র ফেডারেটেড প্রশিক্ষণ মেট্রিক্স উপস্থাপন করেছে - রাউন্ডের সমস্ত ক্লায়েন্ট জুড়ে প্রশিক্ষিত ডেটার সমস্ত ব্যাচের গড় মেট্রিক্স। এটি ওভারফিটিং সম্পর্কে স্বাভাবিক উদ্বেগের পরিচয় দেয়, বিশেষ করে যেহেতু আমরা সরলতার জন্য প্রতিটি রাউন্ডে ক্লায়েন্টদের একই সেট ব্যবহার করেছি, তবে ফেডারেটেড এভারেজিং অ্যালগরিদমের জন্য নির্দিষ্ট প্রশিক্ষণ মেট্রিক্সে ওভারফিটিং এর একটি অতিরিক্ত ধারণা রয়েছে। এটি দেখা সবচেয়ে সহজ যে আমরা কল্পনা করি যে প্রতিটি ক্লায়েন্টের একটি একক ব্যাচ ডেটা রয়েছে এবং আমরা সেই ব্যাচে অনেক পুনরাবৃত্তির (যুগ) জন্য প্রশিক্ষণ দিই। এই ক্ষেত্রে, স্থানীয় মডেলটি সেই একটি ব্যাচের সাথে দ্রুত ফিট হয়ে যাবে, এবং তাই স্থানীয় নির্ভুলতা মেট্রিকটি আমরা গড় 1.0-এর কাছে পৌঁছাব। এইভাবে, এই প্রশিক্ষণের মেট্রিকগুলিকে একটি চিহ্ন হিসাবে নেওয়া যেতে পারে যে প্রশিক্ষণের অগ্রগতি হচ্ছে, তবে আরও বেশি কিছু নয়।

ফেডারেট ডেটার উপর মূল্যায়ন কর্ম সঞ্চালন করার জন্য, আপনি শুধু এই কাজের জন্য পরিকল্পিত অন্য ফেডারেট গণনার গঠন করা যেতে পারে ব্যবহার tff.learning.build_federated_evaluation ফাংশন, এবং একটি আর্গুমেন্ট হিসাবে আপনার মডেল কন্সট্রাকটর ক্ষণস্থায়ী। লক্ষ্য করুন ফেডারেটেড গড়, যেখানে আমরা ব্যবহার করেছি সঙ্গে অসদৃশ MnistTrainableModel , এটা পাস যথেষ্ট MnistModel । মূল্যায়ন গ্রেডিয়েন্ট ডিসেন্ট সঞ্চালন করে না, এবং অপ্টিমাইজার তৈরি করার কোন প্রয়োজন নেই।

পরীক্ষা ও গবেষণার জন্য, যখন একটি কেন্দ্রীভূত পরীক্ষা ডেটা সেটটি পাওয়া যায়, ফেডারেটেড শিক্ষণ টেক্সট জন্য জেনারেশন , সংযুক্ত শেখার থেকে প্রশিক্ষিত ওজন গ্রহণ তাদের একটি প্রমিত Keras মডেল আবেদন, এবং তারপর কেবল কলিং: অন্য মূল্যায়ন বিকল্প প্রমান tf.keras.models.Model.evaluate() একটি কেন্দ্রীভূত ডেটা সেটটি উপর।

evaluation = tff.learning.build_federated_evaluation(MnistModel)

আপনি নিম্নরূপ মূল্যায়ন ফাংশনের বিমূর্ত প্রকার স্বাক্ষর পরিদর্শন করতে পারেন।

str(evaluation.type_signature)
'(<server_model_weights=<trainable=<float32[784,10],float32[10]>,non_trainable=<>>@SERVER,federated_dataset={<x=float32[?,784],y=int32[?,1]>*}@CLIENTS> -> <eval=<num_examples=float32,loss=float32,accuracy=float32>,stat=<num_examples=int64>>@SERVER)'

কোন প্রয়োজন নেই এই সময়ে বিবরণ সম্পর্কে উদ্বিগ্ন করা, শুধু জেনে রাখুন যে নিম্নোক্ত সাধারণ ফর্ম, অনুরূপ লাগে হতে tff.templates.IterativeProcess.next কিন্তু দুই গুরুত্বপূর্ণ পার্থক্য রয়েছে। প্রথমত, আমরা সার্ভারের অবস্থা ফেরত দিচ্ছি না, যেহেতু মূল্যায়ন মডেল বা রাষ্ট্রের অন্য কোনো দিক পরিবর্তন করে না - আপনি এটিকে রাষ্ট্রহীন বলে মনে করতে পারেন। দ্বিতীয়ত, মূল্যায়নের জন্য শুধুমাত্র মডেলের প্রয়োজন হয় এবং সার্ভার স্টেটের অন্য কোনো অংশের প্রয়োজন হয় না যা প্রশিক্ষণের সাথে যুক্ত হতে পারে, যেমন অপ্টিমাইজার ভেরিয়েবল।

SERVER_MODEL, FEDERATED_DATA -> TRAINING_METRICS

প্রশিক্ষণের সময় আমরা যে সর্বশেষ অবস্থায় পৌঁছেছি তার মূল্যায়ন করা যাক। অর্ডার সার্ভার রাষ্ট্র থেকে সর্বশেষ প্রশিক্ষিত মডেল বের করে আনতে, আপনি কেবল অ্যাক্সেস .model সদস্য, যেমন অনুসরণ করে।

train_metrics = evaluation(state.model, federated_train_data)

এখানে আমরা কি পেতে. উপরের প্রশিক্ষণের শেষ রাউন্ডে যা রিপোর্ট করা হয়েছিল তার চেয়ে সংখ্যাগুলিকে কিছুটা ভালো মনে হচ্ছে। নিয়মানুযায়ী, পুনরাবৃত্তিমূলক প্রশিক্ষণ প্রক্রিয়া দ্বারা রিপোর্ট করা প্রশিক্ষণ মেট্রিক্স সাধারণত প্রশিক্ষণ রাউন্ডের শুরুতে মডেলের কর্মক্ষমতা প্রতিফলিত করে, তাই মূল্যায়ন মেট্রিক্স সবসময় এক ধাপ এগিয়ে থাকবে।

str(train_metrics)
"OrderedDict([('eval', OrderedDict([('num_examples', 4860.0), ('loss', 1.7510437), ('accuracy', 0.2788066)])), ('stat', OrderedDict([('num_examples', 4860)]))])"

এখন, ফেডারেটেড ডেটার একটি পরীক্ষার নমুনা সংকলন করা যাক এবং পরীক্ষার ডেটাতে পুনরায় মূল্যায়ন করা যাক। ডেটা আসল ব্যবহারকারীদের একই নমুনা থেকে আসবে, কিন্তু একটি স্বতন্ত্র রাখা-আউট ডেটা সেট থেকে।

federated_test_data = make_federated_data(emnist_test, sample_clients)

len(federated_test_data), federated_test_data[0]
(10,
 <DatasetV1Adapter shapes: OrderedDict([(x, (None, 784)), (y, (None, 1))]), types: OrderedDict([(x, tf.float32), (y, tf.int32)])>)
test_metrics = evaluation(state.model, federated_test_data)
str(test_metrics)
"OrderedDict([('eval', OrderedDict([('num_examples', 580.0), ('loss', 1.8361608), ('accuracy', 0.2413793)])), ('stat', OrderedDict([('num_examples', 580)]))])"

এই টিউটোরিয়াল সমাপ্তি. আমরা আপনাকে পরামিতিগুলির সাথে খেলতে উত্সাহিত করি (যেমন, ব্যাচের আকার, ব্যবহারকারীর সংখ্যা, যুগ, শেখার হার ইত্যাদি), প্রতিটি রাউন্ডে ব্যবহারকারীদের এলোমেলো নমুনার প্রশিক্ষণ অনুকরণ করতে এবং অন্যান্য টিউটোরিয়ালগুলি অন্বেষণ করতে উপরের কোডটি সংশোধন করতে। আমরা উন্নয়ন করেছি।