Google I/O एक लपेट है! TensorFlow सत्रों पर पकड़ बनाएं सत्र देखें

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

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

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

यह ट्यूटोरियल, और फ़ेडरेटेड लर्निंग एपीआई, मुख्य रूप से उन उपयोगकर्ताओं के लिए अभिप्रेत है जो अपने स्वयं के TensorFlow मॉडल को TFF में प्लग करना चाहते हैं, बाद वाले को ज्यादातर ब्लैक बॉक्स के रूप में मानते हैं। - TFF का एक और अधिक में गहराई से समझ और कैसे अपनी खुद की फ़ेडरेटेड सीखने वाले एल्गोरिदम लागू करने के लिए के लिए, एफसी कोर एपीआई पर ट्यूटोरियल देखने के कस्टम संघीय एल्गोरिदम भाग 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!'

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

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

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

यहां बताया गया है कि हम इसे कैसे लोड कर सकते हैं।

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

पीएनजी

फ़ेडरेटेड डेटा में विविधता की खोज

संघीय डेटा आम तौर पर गैर है आईआईडी , उपयोगकर्ताओं को आम तौर पर उपयोग पैटर्न के आधार पर डेटा के विभिन्न वितरण की है। कुछ क्लाइंट के पास डिवाइस पर कम प्रशिक्षण उदाहरण हो सकते हैं, जो स्थानीय रूप से डेटा की कमी से पीड़ित हैं, जबकि कुछ क्लाइंट के पास पर्याप्त से अधिक प्रशिक्षण उदाहरण होंगे। आइए हमारे पास उपलब्ध 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 , preprocessing डेटासेट परिवर्तनों का उपयोग कर पूरा किया जा सकता। यहाँ, हम समतल 28x28 में छवियों को 784 तत्व सरणियों, व्यक्तिगत उदाहरण शफ़ल, उन्हें बैच में व्यवस्थित, और से सुविधाओं का नाम बदलने 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)])>

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 इंटरफ़ेस है, जो तरीकों को उजागर करता है 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 सहायक समारोह लागू करके एक संघीय औसत का कलन विधि का निर्माण कर सकते हैं 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 लागू संघीय औसत का

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

के साथ शुरू करते हैं 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([('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)]))])

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

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

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

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

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

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

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

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

का एक उदाहरण का निर्माण tff.learning.Model

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

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 श्रृंखलाबद्ध किया जा सकता है में मदद करता है, और स्पष्ट नियंत्रण निर्भरता के लिए की जरूरत को हटा।

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

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

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

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 के भीतर इन मीट्रिक्स को देखने के लिए, "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)]))])"

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