छवि वर्गीकरण के लिए फ़ेडरेटेड लर्निंग

TensorFlow.org पर देखें Google Colab में चलाएं GitHub पर स्रोत देखें नोटबुक डाउनलोड करें

इस ट्यूटोरियल में, हम TFF की फेडरेटेड लर्निंग (FL) API लेयर को पेश करने के लिए क्लासिक MNIST प्रशिक्षण उदाहरण का उपयोग करते हैं, tff.learning - उच्च-स्तरीय इंटरफेस का एक सेट जिसका उपयोग सामान्य प्रकार के फ़ेडरेटेड लर्निंग कार्यों को करने के लिए किया जा सकता है, जैसे कि TensorFlow में लागू उपयोगकर्ता द्वारा आपूर्ति किए गए मॉडल के विरुद्ध फ़ेडरेटेड प्रशिक्षण।

यह ट्यूटोरियल, और फ़ेडरेटेड लर्निंग एपीआई, मुख्य रूप से उन उपयोगकर्ताओं के लिए अभिप्रेत है जो अपने स्वयं के TensorFlow मॉडल को TFF में प्लग करना चाहते हैं, बाद वाले को ज्यादातर ब्लैक बॉक्स के रूप में मानते हैं। TFF की अधिक गहन समझ के लिए और अपने स्वयं के फ़ेडरेटेड लर्निंग एल्गोरिदम को कैसे कार्यान्वित करें, FC Core API - कस्टम फ़ेडरेटेड एल्गोरिथम भाग 1 और भाग 2 पर ट्यूटोरियल देखें।

tff.learning पर अधिक 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 --upgrade 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!'

इनपुट डेटा तैयार करना

आइए आंकड़ों से शुरू करते हैं। फ़ेडरेटेड लर्निंग के लिए फ़ेडरेटेड डेटा सेट की आवश्यकता होती है, यानी कई उपयोगकर्ताओं से डेटा का संग्रह। फ़ेडरेटेड डेटा आम तौर पर गैर- आईआईडी होता है , जो चुनौतियों का एक अनूठा सेट पेश करता है।

प्रयोग की सुविधा के लिए, हमने कुछ डेटासेट के साथ 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([('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

पीएनजी

आइए अब प्रत्येक 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])

पीएनजी

अब प्रत्येक 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')

पीएनजी

पीएनजी

पीएनजी

पीएनजी

पीएनजी

उपयोगकर्ता डेटा शोर और अविश्वसनीय रूप से लेबल किया जा सकता है। उदाहरण के लिए, ऊपर क्लाइंट #2 के डेटा को देखते हुए, हम देख सकते हैं कि लेबल 2 के लिए, यह संभव है कि कुछ गलत लेबल वाले उदाहरण हो सकते हैं जो एक नॉइज़ियर माध्य छवि बनाते हैं।

इनपुट डेटा को प्रीप्रोसेस करना

चूंकि डेटा पहले से ही एकtf.data.Dataset ,tf.data.Dataset डेटासेट ट्रांसफ़ॉर्मेशन का उपयोग करके प्रीप्रोसेसिंग को पूरा किया जा सकता है। यहां, हम 28x28 छवियों को 784 तत्व सरणियों में समतल करते हैं, अलग-अलग उदाहरणों को फेरबदल करते हैं, उन्हें बैचों में व्यवस्थित करते हैं, और 28x28 के उपयोग के लिए 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))])

फ़ेडरेटेड डेटा सेट बनाने के लिए हमारे पास लगभग सभी बिल्डिंग ब्लॉक्स हैं।

सिम्युलेशन में 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)])>

Keras के साथ एक मॉडल बनाना

यदि आप केरस का उपयोग कर रहे हैं, तो आपके पास पहले से ही कोड है जो केरस मॉडल बनाता है। यहां एक साधारण मॉडल का उदाहरण दिया गया है जो हमारी आवश्यकताओं के लिए पर्याप्त होगा।

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 इंटरफ़ेस के एक उदाहरण में tff.learning.Model की tff.learning.Model है, जो मॉडल के फ़ॉरवर्ड पास, मेटाडेटा गुणों आदि पर मुहर लगाने के तरीकों को उजागर करता है, इसी तरह केरस, लेकिन अतिरिक्त परिचय भी देता है तत्व, जैसे कि फ़ेडरेटेड मेट्रिक्स की गणना की प्रक्रिया को नियंत्रित करने के तरीके। आइए अभी इसके बारे में चिंता न करें; यदि आपके पास एक केरस मॉडल है जैसा कि हमने अभी ऊपर परिभाषित किया है, तो आप tff.learning.from_keras_model को लागू tff.learning.from_keras_model , मॉडल और नमूना डेटा बैच को तर्क के रूप में पास करके, जैसा कि नीचे दिखाया गया है, आप इसे अपने लिए TFF लपेट सकते हैं।

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 के साथ प्रयोग के लिए tff.learning.Model के रूप में लिपटा हुआ एक मॉडल है, हम TFF को हेल्पर फंक्शन tff.learning.build_federated_averaging_process को निम्नानुसार लागू करके एक फ़ेडरेटेड एवरेजिंग एल्गोरिथम का निर्माण करने दे सकते हैं।

ध्यान रखें कि तर्क को एक कंस्ट्रक्टर (जैसे ऊपर model_fn ) होना चाहिए, न कि पहले से निर्मित इंस्टेंस, ताकि आपके मॉडल का निर्माण TFF द्वारा नियंत्रित संदर्भ में हो सके (यदि आप इसके कारणों के बारे में उत्सुक हैं) यह, हम आपको कस्टम एल्गोरिदम पर अनुवर्ती ट्यूटोरियल पढ़ने के लिए प्रोत्साहित करते हैं)।

नीचे दिए गए फ़ेडरेटेड एवरेजिंग एल्गोरिथम पर एक महत्वपूर्ण नोट, 2 ऑप्टिमाइज़र हैं: एक _क्लाइंट ऑप्टिमाइज़र और एक _सर्वर ऑप्टिमाइज़र । _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 में पैक किए गए फेडरेटेड एवरेजिंग को लागू करते हैं।

टीएफएफ का लक्ष्य गणनाओं को इस तरह परिभाषित करना है कि उन्हें वास्तविक फ़ेडरेटेड लर्निंग सेटिंग्स में निष्पादित किया जा सके, लेकिन वर्तमान में केवल स्थानीय निष्पादन सिमुलेशन रनटाइम लागू किया गया है। एक सिम्युलेटर में एक गणना को निष्पादित करने के लिए, आप बस इसे एक पायथन फ़ंक्शन की तरह लागू करते हैं। यह डिफ़ॉल्ट व्याख्या किया गया वातावरण उच्च प्रदर्शन के लिए डिज़ाइन नहीं किया गया है, लेकिन यह इस ट्यूटोरियल के लिए पर्याप्त होगा; हम भविष्य के रिलीज में बड़े पैमाने पर अनुसंधान की सुविधा के लिए उच्च-प्रदर्शन सिमुलेशन रनटाइम प्रदान करने की उम्मीद करते हैं।

आइए 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 (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([('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)]))])

फ़ेडरेटेड प्रशिक्षण के प्रत्येक दौर के बाद प्रशिक्षण हानि कम हो रही है, यह दर्शाता है कि मॉडल अभिसरण कर रहा है। इन प्रशिक्षण मेट्रिक्स के साथ कुछ महत्वपूर्ण चेतावनी हैं, हालांकि, इस ट्यूटोरियल में बाद में मूल्यांकन पर अनुभाग देखें।

TensorBoard में मॉडल मेट्रिक्स प्रदर्शित करना

इसके बाद, आइए Tensorboard का उपयोग करके इन फ़ेडरेटेड कंप्यूटेशंस से मेट्रिक्स की कल्पना करें।

आइए मेट्रिक्स लिखने के लिए निर्देशिका और संबंधित सारांश लेखक बनाकर शुरू करें।

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

प्रासंगिक स्केलर मेट्रिक्स को समान सारांश लेखक के साथ प्लॉट करें।

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.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/*

मूल्यांकन मेट्रिक्स को उसी तरह देखने के लिए, आप TensorBoard को लिखने के लिए एक अलग eval फ़ोल्डर बना सकते हैं, जैसे "logs/scalars/eval"।

मॉडल कार्यान्वयन को अनुकूलित करना

केरस TensorFlow के लिए अनुशंसित उच्च-स्तरीय मॉडल API है , और जब भी संभव हो हम TFF में tff.learning.from_keras_model मॉडल ( tff.learning.from_keras_model माध्यम से) का उपयोग करने के लिए प्रोत्साहित करते हैं।

हालांकि, tff.learning एक कम स्तर के मॉडल इंटरफ़ेस, प्रदान करता है tff.learning.Model , कि कम से कम कार्यक्षमता फ़ेडरेटेड सीखने के लिए एक मॉडल का उपयोग करने के लिए आवश्यक उजागर करता है। इस इंटरफ़ेस को सीधे लागू करना (संभवतः अभी भीtf.keras.layers जैसे बिल्डिंग ब्लॉक्स का उपयोग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 रूप में tf.float32 , क्योंकि यह बाद के चरण में प्रकार के रूपांतरणों की आवश्यकता को समाप्त कर देगा। वेरिएबल इनिशियलाइज़र्स को लैम्ब्डा के रूप में लपेटना संसाधन वेरिएबल्स द्वारा लगाई गई आवश्यकता है।

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

अगला, हम एक फ़ंक्शन को परिभाषित करते हैं जो फिर से TensorFlow का उपयोग करके स्थानीय मीट्रिक का एक सेट लौटाता है। ये वे मान हैं (मॉडल अपडेट के अलावा, जो स्वचालित रूप से संभाले जाते हैं) जो कि फ़ेडरेटेड लर्निंग या मूल्यांकन प्रक्रिया में सर्वर पर एकत्रित होने के योग्य हैं।

यहां, हम केवल औसत loss और accuracy , साथ ही num_examples , जिसकी हमें फ़ेडरेटेड समुच्चय की गणना करते समय विभिन्न उपयोगकर्ताओं के योगदान को सही ढंग से 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 माध्यम से प्रत्येक डिवाइस द्वारा उत्सर्जित स्थानीय मेट्रिक्स को कैसे एकत्रित किया 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 - वे के रूप में "बॉक्सिंग" हैं tff.Value रों, यह आप नहीं रह गया है TensorFlow का उपयोग कर उन्हें हेरफेर कर सकते हैं स्पष्ट करने के लिए, लेकिन केवल TFF के फ़ेडरेटेड ऑपरेटरों जैसे tff.federated_mean और tff.federated_sum । वैश्विक समुच्चय का लौटाया हुआ शब्दकोश मेट्रिक्स के सेट को परिभाषित करता है जो सर्वर पर उपलब्ध होगा।

tff.learning.Model का एक उदाहरण tff.learning.Model

उपरोक्त सभी के साथ, हम TFF के साथ उपयोग के लिए एक मॉडल प्रतिनिधित्व का निर्माण करने के लिए तैयार हैं जो आपके लिए तब उत्पन्न होता है जब आप TFF को Keras मॉडल में प्रवेश करने देते हैं।

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
a

जैसा कि आप देख सकते हैं, tff.learning.Model द्वारा परिभाषित अमूर्त विधियाँ और गुण पिछले अनुभाग में कोड स्निपेट्स से मेल tff.learning.Model जो चरों को पेश करते हैं और हानि और आंकड़ों को परिभाषित करते हैं।

यहाँ कुछ बिंदु हाइलाइट करने लायक हैं:

  • आपके मॉडल द्वारा उपयोग किए जाने वाले सभी राज्यों को TensorFlow चर के रूप में कैप्चर किया जाना चाहिए, क्योंकि TFF रनटाइम पर पायथन का उपयोग नहीं करता है (याद रखें कि आपका कोड इस तरह लिखा जाना चाहिए कि इसे मोबाइल उपकरणों पर तैनात किया जा सके; अधिक गहराई के लिए कस्टम एल्गोरिदम ट्यूटोरियल देखें। कारणों पर टिप्पणी)।
  • आपके मॉडल को यह वर्णन करना चाहिए कि यह किस प्रकार के डेटा को स्वीकार करता है ( input_spec ), सामान्य रूप से, TFF एक दृढ़ता से टाइप किया गया वातावरण है और सभी घटकों के लिए प्रकार के हस्ताक्षर निर्धारित करना चाहता है। अपने मॉडल के इनपुट के प्रारूप की घोषणा करना इसका एक अनिवार्य हिस्सा है।
  • हालांकि तकनीकी रूप से इसकी आवश्यकता नहीं है, हम अनुशंसा करते हैं कि सभी TensorFlow तर्क (फॉरवर्ड पास, मीट्रिक गणना, आदि) को tf.function s के रूप में tf.function , क्योंकि इससे यह सुनिश्चित करने में मदद मिलती है कि TensorFlow को क्रमबद्ध किया जा सकता है, और स्पष्ट नियंत्रण निर्भरता की आवश्यकता को दूर करता है।

उपरोक्त संघीय एसजीडी जैसे मूल्यांकन और एल्गोरिदम के लिए पर्याप्त है। हालाँकि, फ़ेडरेटेड एवरेजिंग के लिए, हमें यह निर्दिष्ट करने की आवश्यकता है कि मॉडल को प्रत्येक बैच पर स्थानीय रूप से कैसे प्रशिक्षित किया जाना चाहिए। फ़ेडरेटेड एवरेजिंग एल्गोरिथम बनाते समय हम एक स्थानीय अनुकूलक निर्दिष्ट करेंगे।

नए मॉडल के साथ फ़ेडरेटेड प्रशिक्षण का अनुकरण

उपरोक्त सभी के साथ, शेष प्रक्रिया वैसी ही दिखती है जैसी हमने पहले ही देखी है - बस मॉडल कंस्ट्रक्टर को हमारे नए मॉडल वर्ग के कंस्ट्रक्टर के साथ बदलें, और दो फ़ेडरेटेड कंप्यूटेशंस का उपयोग पुनरावृत्ति प्रक्रिया में करें जिसे आपने चक्र के लिए बनाया है। प्रशिक्षण दौर।

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

TensorBoard के भीतर इन मीट्रिक्स को देखने के लिए, "TensorBoard में मॉडल मीट्रिक प्रदर्शित करना" में ऊपर सूचीबद्ध चरणों का संदर्भ लें।

मूल्यांकन

हमारे अब तक के सभी प्रयोगों ने केवल फ़ेडरेटेड ट्रेनिंग मेट्रिक्स प्रस्तुत किए - राउंड में सभी क्लाइंट्स में प्रशिक्षित डेटा के सभी बैचों पर औसत मेट्रिक्स। यह ओवरफिटिंग के बारे में सामान्य चिंताओं का परिचय देता है, खासकर जब से हमने सादगी के लिए प्रत्येक दौर में ग्राहकों के समान सेट का उपयोग किया है, लेकिन फेडरेटेड एवरेजिंग एल्गोरिदम के लिए विशिष्ट प्रशिक्षण मेट्रिक्स में ओवरफिटिंग की एक अतिरिक्त धारणा है। यह देखना सबसे आसान है कि क्या हम कल्पना करते हैं कि प्रत्येक ग्राहक के पास डेटा का एक बैच था, और हम उस बैच पर कई पुनरावृत्तियों (युगों) के लिए प्रशिक्षण देते हैं। इस मामले में, स्थानीय मॉडल जल्दी से उस एक बैच में बिल्कुल फिट हो जाएगा, और इसलिए स्थानीय सटीकता मीट्रिक हम औसत 1.0 तक पहुंच जाएंगे। इस प्रकार, इन प्रशिक्षण मेट्रिक्स को एक संकेत के रूप में लिया जा सकता है कि प्रशिक्षण प्रगति कर रहा है, लेकिन बहुत अधिक नहीं।

फ़ेडरेटेड डेटा पर मूल्यांकन करने के लिए, आप tff.learning.build_federated_evaluation फ़ंक्शन का उपयोग करके, और अपने मॉडल कंस्ट्रक्टर में तर्क के रूप में पास करते हुए, इस उद्देश्य के लिए डिज़ाइन की गई एक और फ़ेडरेटेड गणना का निर्माण कर सकते हैं। ध्यान दें कि फ़ेडरेटेड एवरेजिंग के विपरीत, जहाँ हमने MnistTrainableModel उपयोग किया है, यह MnistTrainableModel को पास करने के लिए MnistModel । मूल्यांकन ग्रेडिएंट डिसेंट नहीं करता है, और ऑप्टिमाइज़र बनाने की कोई आवश्यकता नहीं है।

प्रयोग और अनुसंधान के लिए, जब एक केंद्रीकृत परीक्षण डेटासेट उपलब्ध होता है, तो टेक्स्ट जनरेशन के लिए फ़ेडरेटेड लर्निंग एक और मूल्यांकन विकल्प प्रदर्शित करता है: फ़ेडरेटेड लर्निंग से प्रशिक्षित वज़न लेना, उन्हें एक मानक केरस मॉडल पर लागू करना, और फिर बस tf.keras.models.Model.evaluate() कॉल 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 कि यह 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>'

यह ट्यूटोरियल का समापन करता है। हम आपको प्रत्येक दौर में उपयोगकर्ताओं के यादृच्छिक नमूनों पर प्रशिक्षण का अनुकरण करने के लिए उपरोक्त कोड को संशोधित करने और अन्य ट्यूटोरियल का पता लगाने के लिए मापदंडों (जैसे, बैच आकार, उपयोगकर्ताओं की संख्या, युग, सीखने की दर, आदि) के साथ खेलने के लिए प्रोत्साहित करते हैं। हमने विकसित किया है।