This page was translated by the Cloud Translation API.
Switch to English

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

টেনসরফ্লো.আর.জে দেখুন গুগল কোলাবে চালান গিটহাবের উত্স দেখুন

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

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

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

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

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

# 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 tb-nightly  # or tensorboard, but not both

import nest_asyncio
nest_asyncio.apply()
%load_ext tensorboard
Fetching TensorBoard MPM... done.

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

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

এর ডেটা দিয়ে শুরু করা যাক। ফেডারেট লার্নিংয়ের জন্য একটি ফেডারেশনযুক্ত ডেটা সেট, অর্থাত্ একাধিক ব্যবহারকারীর কাছ থেকে ডেটা সংগ্রহ করা দরকার। সংযুক্ত ডেটা সাধারণত নন- আইড হয় , যা চ্যালেঞ্জগুলির একটি অনন্য সেট।

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

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

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

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

len(emnist_train.client_ids)
3383
emnist_train.element_type_structure
OrderedDict([('pixels', TensorSpec(shape=(28, 28), dtype=tf.float32, name=None)), ('label', TensorSpec(shape=(), dtype=tf.int32, 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()

পিএনজি

সংঘবদ্ধ ডেটাগুলিতে ভিন্ন ভিন্নতা অন্বেষণ

ফেডারেশনযুক্ত ডেটা সাধারণত নন- আইড হয় , ব্যবহারকারীদের সাধারণত ব্যবহারের ধরণগুলির উপর নির্ভর করে ডেটার বিভিন্ন বিতরণ করে। কিছু ক্লায়েন্টের ডিভাইসে প্রশিক্ষণের উদাহরণ কম থাকতে পারে, স্থানীয়ভাবে ডেটা পলসিটি ভুগছে, আবার কিছু ক্লায়েন্টের কাছে পর্যাপ্ত প্রশিক্ষণের উদাহরণের চেয়ে আরও বেশি কিছু থাকতে পারে। আসুন আমরা উপলব্ধ 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

পিএনজি

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

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

পিএনজি

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

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

পিএনজি

পিএনজি

পিএনজি

পিএনজি

পিএনজি

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

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

যেহেতু ডেটা ইতিমধ্যে একটিtf.data.Dataset , ডেটাসেট রূপান্তর ব্যবহার করে প্রিপ্রসেসিং সম্পন্ন করা যায়। এখানে, আমরা 28x28 চিত্রগুলিকে 784 এলিমেন্ট অ্যারেগুলিতে সমতল করি, পৃথক উদাহরণগুলিকে বদলে ফেলি, তাদেরকে ব্যাচগুলিতে সংগঠিত করি এবং কেরাসের সাথে ব্যবহারের জন্য pixels এবং label থেকে x এবং y এর বৈশিষ্ট্যগুলির নাম পরিবর্তন করি। আমরা বিভিন্ন যুগের সময় চালানোর জন্য ডেটা সেটটির উপরেও 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).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([[0],
       [5],
       [0],
       [1],
       [3],
       [0],
       [5],
       [4],
       [1],
       [7],
       [0],
       [4],
       [0],
       [1],
       [7],
       [2],
       [2],
       [0],
       [7],
       [1]], dtype=int32))])

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

সিমুলেশনে টিএফএফকে সংযুক্ত তথ্য খাওয়ানোর একটি উপায় কেবল পাইথন তালিকা হিসাবে তালিকার প্রতিটি উপাদানকে পৃথক ব্যবহারকারীর ডেটা ধারণ করে, তালিকা হিসাবে বা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)])>

কেরাস দিয়ে একটি মডেল তৈরি করা হচ্ছে

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

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

টিএফএফের সাথে কোনও মডেল ব্যবহার করার জন্য, এটি টিএফএফেরনিং.মোডেল ইন্টারফেসের একটি উদাহরণে আবৃত করা দরকার যা মডেলটির ফরোয়ার্ড পাস, মেটাডাটা বৈশিষ্ট্য ইত্যাদির স্ট্যাম্পের পদ্ধতিগুলি tff.learning.Model প্রকাশ করে, তবে অতিরিক্তটিও প্রবর্তন করে উপাদানসমূহ, যেমন ফেডেরেটেড মেট্রিক্সের কম্পিউটিংয়ের প্রক্রিয়া নিয়ন্ত্রণের উপায়। আসুন আপাতত এই সম্পর্কে চিন্তা করবেন না; যদি আপনার উপরে কেবলমাত্র আমরা সংজ্ঞায়িত করেছি যেমন tff.learning.from_keras_model মডেল থাকে তবে নীচে দেখানো tff.learning.from_keras_model , 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.learning.build_federated_averaging_process নিম্নরূপে সাহায্যকারী ফাংশন tff.learning.build_federated_averaging_process করে একটি ফেডারেটেড এভারেজিং অ্যালগরিদম তৈরি করতে দিতে পারি।

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

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

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.templates.IterativeProcess একটি tff.templates.IterativeProcess প্যাকেজ করেছে যেখানে এই কম্পিউটিশনগুলির এক জোড়া সম্পত্তি হিসাবে initialize এবং next হিসাবে উপলব্ধ।

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

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

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

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 (এমএনআইএসটির প্রাথমিক মডেল প্যারামিটারগুলি যা সমস্ত ডিভাইসে বিতরণ করা হবে) এবং optimizer_state (সার্ভার দ্বারা রক্ষণাবেক্ষণ করা অতিরিক্ত তথ্য, যেমন হাইপারপ্যারামিটার শিডিয়ুলের জন্য ব্যবহারের জন্য রাউন্ডের সংখ্যা ইত্যাদি)।

আসুন সার্ভারের রাজ্যটি তৈরি করতে initialize গণনাটি 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([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.11502057), ('loss', 3.244929)]))])

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

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([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.14609054), ('loss', 2.9141645)]))])
round  3, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.15205762), ('loss', 2.9237952)]))])
round  4, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.18600823), ('loss', 2.7629454)]))])
round  5, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.20884773), ('loss', 2.622908)]))])
round  6, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.21872428), ('loss', 2.543587)]))])
round  7, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.2372428), ('loss', 2.4210362)]))])
round  8, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.28209877), ('loss', 2.2297976)]))])
round  9, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.2685185), ('loss', 2.195803)]))])
round 10, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('sparse_categorical_accuracy', 0.33868313), ('loss', 2.0523348)]))])

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

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

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

এর মেট্রিক লিখতে ডিরেক্টরি এবং সংশ্লিষ্ট সংক্ষিপ্ত লেখক তৈরি করে শুরু করি।

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)

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

!ls {logdir}
%tensorboard --logdir {logdir} --port=0
events.out.tfevents.1604020204.isim77-20020ad609500000b02900f40f27a5f6.prod.google.com.686098.10633.v2
events.out.tfevents.1604020602.isim77-20020ad609500000b02900f40f27a5f6.prod.google.com.794554.10607.v2

Launching TensorBoard...
<IPython.core.display.Javascript at 0x7fc5e8d3c128>
# 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/*

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

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

কেরাস হ'ল টেনসরফ্লো -র জন্য প্রস্তাবিত উচ্চ-স্তরের মডেল এপিআই এবং যখনই সম্ভব হবে আমরা টিএফএফ-এ কেরাস মডেলগুলি ( tff.learning.from_keras_model মাধ্যমে) ব্যবহার করতে উত্সাহিত করি।

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

সুতরাং আসুন এটি আবার শুরু থেকে শুরু করুন।

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

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

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

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

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 mnist_forward_pass(variables, batch):
  y = tf.nn.softmax(tf.matmul(batch['x'], variables.weights) + variables.bias)
  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

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

এখানে, আমরা কেবল গড় 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 দ্বারা প্রতিটি ডিভাইস দ্বারা নির্গত স্থানীয় মেট্রিকগুলি একত্রিত করতে হবে তা নির্ধারণ করতে হবে। এটি কোডের একমাত্র অংশ যা টেনসরফ্লোতে লেখা নেই - এটি টিএফএফ-তে প্রকাশিত একটি ফেডারেশনযুক্ত গণনা । আপনি যদি আরও গভীর খনন করতে চান তবে কাস্টম অ্যালগরিদম টিউটোরিয়ালটি দিয়ে স্কিম করুন তবে বেশিরভাগ অ্যাপ্লিকেশনগুলিতে আপনার সত্যিই প্রয়োজন হবে না; নীচে প্রদর্শিত প্যাটার্নের রূপগুলি যথেষ্ট হওয়া উচিত। দেখতে দেখতে এটি কী:

@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.federated_mean এবং tff.federated_sum । গ্লোবাল সমষ্টিগুলির প্রত্যাশিত অভিধানটি মেট্রিকের সেটটি সংজ্ঞায়িত করে যা সার্ভারে উপলব্ধ।

tff.learning.Model একটি উদাহরণ তৈরি করা

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

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

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

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

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

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

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

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

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([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 3.1527398), ('accuracy', 0.12469136)]))])

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([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.941014), ('accuracy', 0.14218107)]))])
round  3, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.9052832), ('accuracy', 0.14444445)]))])
round  4, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.7491086), ('accuracy', 0.17962962)]))])
round  5, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.5129666), ('accuracy', 0.19526748)]))])
round  6, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.4175923), ('accuracy', 0.23600823)]))])
round  7, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.4273515), ('accuracy', 0.24176955)]))])
round  8, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.2426176), ('accuracy', 0.2802469)]))])
round  9, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.1567981), ('accuracy', 0.295679)]))])
round 10, metrics=OrderedDict([('broadcast', ()), ('aggregation', OrderedDict([('value_sum_process', ()), ('weight_sum_process', ())])), ('train', OrderedDict([('num_examples', 4860.0), ('loss', 2.1092515), ('accuracy', 0.30843621)]))])

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

মূল্যায়ন

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

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

পরীক্ষা-নিরীক্ষার জন্য, যখন একটি কেন্দ্রীভূত পরীক্ষার ডেটাসেট পাওয়া যায় তখন ফেডারেট লার্নিং ফর টেক্সট জেনারেশন আরেকটি মূল্যায়ন বিকল্প প্রদর্শন করে: ফেডারেট লার্নিং থেকে প্রশিক্ষিত ওজন নেওয়া, তাদেরকে একটি আদর্শ কেরাস মডেলে প্রয়োগ করা এবং তারপরে কেবল tf.keras.models.Model.evaluate() কল করা সেন্ট্রালাইজড ডেটাসেটে 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> -> <num_examples=float32@SERVER,loss=float32@SERVER,accuracy=float32@SERVER>)'

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

SERVER_MODEL, FEDERATED_DATA -> TRAINING_METRICS

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

train_metrics = evaluation(state.model, federated_train_data)

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

str(train_metrics)
'<num_examples=4860.0,loss=1.7142657041549683,accuracy=0.38683128356933594>'

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

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)
'<num_examples=580.0,loss=1.861915111541748,accuracy=0.3362068831920624>'

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