TensorFlow.org এ দেখুন | Google Colab-এ চালান | GitHub-এ উৎস দেখুন | নোটবুক ডাউনলোড করুন |
আমরা শুরু করার আগে
আমরা শুরু করার আগে, আপনার পরিবেশ সঠিকভাবে সেটআপ করা হয়েছে তা নিশ্চিত করতে অনুগ্রহ করে নিম্নলিখিতটি চালান। আপনি যদি একটি অভিবাদন দেখতে না পান তাহলে, পড়ুন দয়া ইনস্টলেশন নির্দেশাবলীর জন্য গাইড।
!pip install --quiet --upgrade tensorflow-federated-nightly
!pip install --quiet --upgrade nest-asyncio
import nest_asyncio
nest_asyncio.apply()
import tensorflow as tf
import tensorflow_federated as tff
ইন ইমেজ শ্রেণীবিন্যাস এবং টেক্সট প্রজন্ম টিউটোরিয়াল, আমরা কিভাবে ফেডারেটেড শিক্ষণ (এফএল) জন্য মডেল এবং ডেটা পাইপলাইনগুলি সেট আপ করার শিখেছি, এবং মাধ্যমে ফেডারেট প্রশিক্ষণ সঞ্চালিত tff.learning
TFF এর এপিআই স্তর।
FL গবেষণার ক্ষেত্রে এটি শুধুমাত্র আইসবার্গের টিপ। এই টিউটোরিয়ালে আমরা কিভাবে পিছিয়ে ছাড়া ফেডারেট লার্নিং আলগোরিদিম বাস্তবায়ন নিয়ে আলোচনা tff.learning
API- টি। আমরা নিম্নলিখিতগুলি সম্পন্ন করার লক্ষ্য রাখি:
লক্ষ্য:
- ফেডারেটেড লার্নিং অ্যালগরিদমের সাধারণ কাঠামো বুঝুন।
- TFF এর ফেডারেটেড কোর এক্সপ্লোর করুন।
- ফেডারেটেড এভারেজিং সরাসরি বাস্তবায়ন করতে ফেডারেটেড কোর ব্যবহার করুন।
যদিও এই টিউটোরিয়াল স্বয়ংসম্পূর্ণ হয়, আমরা প্রথম পড়া সুপারিশ ইমেজ শ্রেণীবিন্যাস এবং টেক্সট প্রজন্ম টিউটোরিয়াল।
ইনপুট ডেটা প্রস্তুত করা হচ্ছে
আমরা প্রথমে TFF-এ অন্তর্ভুক্ত EMNIST ডেটাসেট লোড এবং প্রিপ্রসেস করি। অধিক বিবরণের জন্য, দেখুন ইমেজ শ্রেণীবিন্যাস টিউটোরিয়াল।
emnist_train, emnist_test = tff.simulation.datasets.emnist.load_data()
যাতে আমাদের মডেল মধ্যে ডেটা সেটটি ভোজন করার জন্য, আমরা তথ্য চেপ্টা, এবং ফর্ম একটি tuple প্রতিটি উদাহরণ রূপান্তর (flattened_image_vector, label)
।
NUM_CLIENTS = 10
BATCH_SIZE = 20
def preprocess(dataset):
def batch_format_fn(element):
"""Flatten a batch of EMNIST data and return a (features, label) tuple."""
return (tf.reshape(element['pixels'], [-1, 784]),
tf.reshape(element['label'], [-1, 1]))
return dataset.batch(BATCH_SIZE).map(batch_format_fn)
আমরা এখন অল্প সংখ্যক ক্লায়েন্ট নির্বাচন করি এবং তাদের ডেটাসেটে উপরের প্রিপ্রসেসিং প্রয়োগ করি।
client_ids = sorted(emnist_train.client_ids)[:NUM_CLIENTS]
federated_train_data = [preprocess(emnist_train.create_tf_dataset_for_client(x))
for x in client_ids
]
মডেল প্রস্তুত করা হচ্ছে
আমরা হিসাবে একই মডেল ব্যবহার ইমেজ শ্রেণীবিন্যাস টিউটোরিয়াল। এই মডেল (মাধ্যমে বাস্তবায়িত tf.keras
) একটা একক লুকানো স্তর, একটি softmax স্তর দ্বারা অনুসরণ হয়েছে।
def create_keras_model():
initializer = tf.keras.initializers.GlorotNormal(seed=0)
return tf.keras.models.Sequential([
tf.keras.layers.Input(shape=(784,)),
tf.keras.layers.Dense(10, kernel_initializer=initializer),
tf.keras.layers.Softmax(),
])
অর্ডার TFF মধ্যে এই মডেল ব্যবহার করার জন্য, আমরা একটি হিসাবে Keras মডেল মোড়ানো tff.learning.Model
। এটা আমাদের মডেলের করতে সক্ষম হবেন ফরওয়ার্ড পাস TFF মধ্যে, এবং নির্যাস মডেল আউটপুট । অধিক বিবরণের জন্য, তাও দেখতে ইমেজ শ্রেণীবিন্যাস টিউটোরিয়াল।
def model_fn():
keras_model = create_keras_model()
return tff.learning.from_keras_model(
keras_model,
input_spec=federated_train_data[0].element_spec,
loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=[tf.keras.metrics.SparseCategoricalAccuracy()])
আমরা ব্যবহৃত যদিও tf.keras
একটি তৈরি করতে tff.learning.Model
, TFF আরো অনেক কিছু সাধারণ মডেলের সমর্থন করে। এই মডেলগুলির মডেলের ওজন ক্যাপচার করার জন্য নিম্নলিখিত প্রাসঙ্গিক বৈশিষ্ট্য রয়েছে:
-
trainable_variables
: tensors trainable স্তর সংশ্লিষ্ট একটি iterable। -
non_trainable_variables
: tensors অ trainable স্তর সংশ্লিষ্ট একটি iterable।
আমাদের উদ্দেশ্যে, আমরা কেবল ব্যবহার করবে trainable_variables
। (যেমন আমাদের মডেলে শুধুমাত্র সেগুলি আছে!)
আপনার নিজস্ব ফেডারেটেড লার্নিং অ্যালগরিদম তৈরি করা
যদিও tff.learning
এপিআই এক ফেডারেটেড গড় বিভিন্ন রুপ তৈরি করতে অনুমতি দেয়, অন্যান্য ফেডারেট আলগোরিদিম যা এই কাঠামোর মধ্যে সুন্দরভাবে ফিট না। উদাহরণস্বরূপ, যদি আপনি যেমন নিয়মিতকরণ, ক্লিপিং, বা আরো জটিল আলগোরিদিম যোগ করতে পারেন ফেডারেট GAN প্রশিক্ষণ । এছাড়াও আপনি পরিবর্তে আগ্রহী হতে হতে পারে ফেডারেট বিশ্লেষণ ।
এই আরও উন্নত অ্যালগরিদমগুলির জন্য, আমাদের TFF ব্যবহার করে আমাদের নিজস্ব কাস্টম অ্যালগরিদম লিখতে হবে। অনেক ক্ষেত্রে, ফেডারেটেড অ্যালগরিদমের 4টি প্রধান উপাদান থাকে:
- একটি সার্ভার থেকে ক্লায়েন্ট সম্প্রচার পদক্ষেপ.
- একটি স্থানীয় ক্লায়েন্ট আপডেট পদক্ষেপ।
- একটি ক্লায়েন্ট থেকে সার্ভার আপলোড ধাপ।
- একটি সার্ভার আপডেট পদক্ষেপ.
TFF, আমরা সাধারণত একটি হিসাবে ফেডারেট আলগোরিদিম প্রতিনিধিত্ব tff.templates.IterativeProcess
(যা আমরা শুধু একটি হিসেবে উল্লেখ IterativeProcess
সর্বত্র)। এই শ্রেণী যে রয়েছে initialize
এবং next
ফাংশন। এখানে, initialize
সার্ভার আরম্ভ করতে ব্যবহৃত হয়, এবং next
ফেডারেট অ্যালগরিদম এক যোগাযোগ বৃত্তাকার পারফর্ম করবেন। FedAvg এর জন্য আমাদের পুনরাবৃত্তিমূলক প্রক্রিয়া কেমন হওয়া উচিত তার একটি কঙ্কাল লিখি।
প্রথমত, আমরা একটি আরম্ভ ফাংশন যা কেবল একটি সৃষ্টি আছে tff.learning.Model
, এবং তার trainable ওজন ফেরৎ।
def initialize_fn():
model = model_fn()
return model.trainable_variables
এই ফাংশনটি ভাল দেখাচ্ছে, কিন্তু আমরা পরে দেখব, এটিকে একটি "TFF গণনা" করার জন্য আমাদের একটি ছোট পরিবর্তন করতে হবে।
আমরা স্কেচ করতে চান next_fn
।
def next_fn(server_weights, federated_dataset):
# Broadcast the server weights to the clients.
server_weights_at_client = broadcast(server_weights)
# Each client computes their updated weights.
client_weights = client_update(federated_dataset, server_weights_at_client)
# The server averages these updates.
mean_client_weights = mean(client_weights)
# The server updates its model.
server_weights = server_update(mean_client_weights)
return server_weights
আমরা আলাদাভাবে এই চারটি উপাদান বাস্তবায়নে ফোকাস করব। আমরা প্রথমে সেই অংশগুলিতে ফোকাস করি যা খাঁটি টেনসরফ্লোতে প্রয়োগ করা যেতে পারে, যেমন ক্লায়েন্ট এবং সার্ভার আপডেট পদক্ষেপ।
টেনসরফ্লো ব্লক
ক্লায়েন্ট আপডেট
আমরা আমাদের ব্যবহার করবে tff.learning.Model
মূলত একই ভাবে আপনি একটি TensorFlow মডেল প্রশিক্ষণ করবে ক্লায়েন্ট প্রশিক্ষণ না। বিশেষ করে, আমরা ব্যবহার করবে tf.GradientTape
ডেটার ব্যাচ উপর গ্রেডিয়েন্ট গনা, তারপর ব্যবহার করে এই গ্রেডিয়েন্ট প্রয়োগ client_optimizer
। আমরা শুধুমাত্র প্রশিক্ষণযোগ্য ওজনের উপর ফোকাস করি।
@tf.function
def client_update(model, dataset, server_weights, client_optimizer):
"""Performs training (using the server model weights) on the client's dataset."""
# Initialize the client model with the current server weights.
client_weights = model.trainable_variables
# Assign the server weights to the client model.
tf.nest.map_structure(lambda x, y: x.assign(y),
client_weights, server_weights)
# Use the client_optimizer to update the local model.
for batch in dataset:
with tf.GradientTape() as tape:
# Compute a forward pass on the batch of data
outputs = model.forward_pass(batch)
# Compute the corresponding gradient
grads = tape.gradient(outputs.loss, client_weights)
grads_and_vars = zip(grads, client_weights)
# Apply the gradient using a client optimizer.
client_optimizer.apply_gradients(grads_and_vars)
return client_weights
সার্ভার আপডেট
FedAvg-এর সার্ভার আপডেট ক্লায়েন্ট আপডেটের চেয়ে সহজ। আমরা "ভ্যানিলা" ফেডারেটেড গড় বাস্তবায়ন করব, যেখানে আমরা কেবল ক্লায়েন্ট মডেল ওজনের গড় দ্বারা সার্ভার মডেল ওজন প্রতিস্থাপন করব। আবার, আমরা শুধুমাত্র প্রশিক্ষণযোগ্য ওজনের উপর ফোকাস করি।
@tf.function
def server_update(model, mean_client_weights):
"""Updates the server model weights as the average of the client model weights."""
model_weights = model.trainable_variables
# Assign the mean client weights to the server model.
tf.nest.map_structure(lambda x, y: x.assign(y),
model_weights, mean_client_weights)
return model_weights
স্নিপেট কেবল ফিরে সরলীকৃত যেতে পারে mean_client_weights
। যাইহোক, ফেডারেটেড গড় ব্যবহারের আরো উন্নত বাস্তবায়নের mean_client_weights
যেমন ভরবেগ বা adaptivity যেমন আরো পরিশীলিত কৌশল, সঙ্গে।
চ্যালেঞ্জ: একটি সংস্করণ বাস্তবায়ন server_update
যে সার্ভার ওজন আপডেট model_weights এবং mean_client_weights মিডপয়েন্ট যাবে। (দ্রষ্টব্য: "মিডপয়েন্ট" পদ্ধতির এই ধরনের সাম্প্রতিক কাজ অনুরূপ Lookahead অপটিমাইজার !)।
এখন পর্যন্ত, আমরা শুধুমাত্র বিশুদ্ধ TensorFlow কোড লিখেছি। এটি ডিজাইন অনুসারে, কারণ TFF আপনাকে টেনসরফ্লো কোডের অনেকটাই ব্যবহার করতে দেয় যার সাথে আপনি ইতিমধ্যে পরিচিত৷ যাইহোক, এখন আমরা অর্কেস্ট্রারচনা যুক্তি, যে যুক্তি যে নির্দেশনা ক্লায়েন্ট কি সার্ভার সম্প্রচার, এবং কি ক্লায়েন্ট আপলোড সার্ভারে নির্দিষ্ট করতে হবে।
এই TFF এর ফেডারেটেড কোর প্রয়োজন হবে।
ফেডারেটেড কোরের পরিচিতি
ফেডারেটেড কোর (এফসি) নিম্ন স্তরের ইন্টারফেস যে জন্য ভিত্তি হিসেবে কাজ একটি সেট tff.learning
API- টি। যাইহোক, এই ইন্টারফেসগুলি শেখার মধ্যে সীমাবদ্ধ নয়। প্রকৃতপক্ষে, এগুলি বিতরণ করা ডেটার উপর বিশ্লেষণ এবং অন্যান্য অনেক গণনার জন্য ব্যবহার করা যেতে পারে।
একটি উচ্চ-স্তরে, ফেডারেটেড কোর হল একটি উন্নয়ন পরিবেশ যা টেনসরফ্লো কোডকে বিতরণকৃত যোগাযোগ অপারেটরগুলির সাথে (যেমন বিতরণকৃত যোগফল এবং সম্প্রচার) একত্রিত করতে কম্প্যাক্টলিভাবে প্রকাশ করা প্রোগ্রাম লজিককে সক্ষম করে। লক্ষ্য হল গবেষক এবং অনুশীলনকারীদের তাদের সিস্টেমে বিতরণ করা যোগাযোগের উপর সুস্পষ্ট নিয়ন্ত্রণ দেওয়া, সিস্টেম বাস্তবায়নের বিশদ প্রয়োজন ছাড়াই (যেমন পয়েন্ট-টু-পয়েন্ট নেটওয়ার্ক বার্তা বিনিময় নির্দিষ্ট করা)।
একটি মূল বিষয় হল যে TFF গোপনীয়তা-সংরক্ষণের জন্য ডিজাইন করা হয়েছে। অতএব, কেন্দ্রীভূত সার্ভার অবস্থানে ডেটার অবাঞ্ছিত জমা হওয়া রোধ করতে, এটি ডেটা কোথায় থাকে তার উপর সুস্পষ্ট নিয়ন্ত্রণের অনুমতি দেয়।
ফেডারেটেড ডেটা
টিএফএফ-এর একটি মূল ধারণা হল "ফেডারেটেড ডেটা", যা একটি বিতরণ করা সিস্টেমে (যেমন ক্লায়েন্ট ডেটাসেট, বা সার্ভার মডেল ওজন) ডিভাইসগুলির একটি গ্রুপ জুড়ে হোস্ট করা ডেটা আইটেমগুলির একটি সংগ্রহকে বোঝায়। আমরা একটি একক ফেডারেট মান হিসাবে সমস্ত ডিভাইস জুড়ে তথ্য আইটেম সম্পূর্ণ সংগ্রহ মডেল।
উদাহরণস্বরূপ, ধরুন আমাদের কাছে ক্লায়েন্ট ডিভাইস রয়েছে যেগুলির প্রতিটিতে একটি ফ্লোট রয়েছে যা একটি সেন্সরের তাপমাত্রা উপস্থাপন করে। আমরা একটি ফেডারেট ভাসা যেমন প্রতিনিধিত্ব করতে পারে
federated_float_on_clients = tff.FederatedType(tf.float32, tff.CLIENTS)
ফেডারেটেড ধরনের একটি টাইপ দ্বারা নির্দিষ্ট T
সদস্য উপাদানসমূহের (যেমন। tf.float32
) এবং একটি গ্রুপ G
ডিভাইস। আমরা ক্ষেত্রে যেখানে উপর ফোকাস করা G
পারেন হয় tff.CLIENTS
বা tff.SERVER
। যেমন একটি ফেডারেট টাইপ হিসাবে প্রতিনিধিত্ব করা হয় {T}@G
নিচের চিত্রের।
str(federated_float_on_clients)
'{float32}@CLIENTS'
কেন আমরা প্লেসমেন্ট সম্পর্কে এত যত্ন? TFF-এর একটি মূল লক্ষ্য হল লেখার কোড সক্ষম করা যা একটি বাস্তব বিতরণ করা সিস্টেমে স্থাপন করা যেতে পারে। এর মানে হল যে ডিভাইসগুলির কোন উপসেটগুলি কোন কোডটি কার্যকর করে এবং কোথায় ডেটার বিভিন্ন অংশ থাকে সে সম্পর্কে যুক্তি দেওয়া অত্যাবশ্যক৷
TFF তিনটি জিনিস উপর দৃষ্টি নিবদ্ধ করে: ডেটা, যেখানে তথ্য স্থাপন করা হয়, এবং তথ্য কিভাবে রুপান্তরিত করা হচ্ছে। প্রথম দুই, সংযুক্ত ধরনের encapsulated হয় যখন গত ফেডারেট কম্পিউটেশন মধ্যে encapsulated করা হয়।
ফেডারেটেড গণনা
TFF একটি জোরালোভাবে টাইপ কার্মিক প্রোগ্রামিং এনভায়রনমেন্ট যার মৌলিক ইউনিট ফেডারেট কম্পিউটেশন হয়। এগুলি যুক্তির অংশ যা ইনপুট হিসাবে ফেডারেটেড মান গ্রহণ করে এবং আউটপুট হিসাবে ফেডারেটেড মান ফিরিয়ে দেয়।
উদাহরণস্বরূপ, ধরুন আমরা আমাদের ক্লায়েন্ট সেন্সরগুলিতে তাপমাত্রা গড় করতে চেয়েছিলাম। আমরা নিম্নলিখিত সংজ্ঞায়িত করতে পারি (আমাদের ফেডারেটেড ফ্লোট ব্যবহার করে):
@tff.federated_computation(tff.FederatedType(tf.float32, tff.CLIENTS))
def get_average_temperature(client_temperatures):
return tff.federated_mean(client_temperatures)
আপনি চাইতে পারি, কিভাবে এই ভিন্ন tf.function
TensorFlow মধ্যে প্রসাধক? কী উত্তর যে দ্বারা উত্পন্ন কোড tff.federated_computation
তন্ন তন্ন TensorFlow কিংবা পাইথন কোড; এটি একটি অভ্যন্তরীণ প্ল্যাটফর্ম-স্বাধীন আঠালো ভাষায় বিতরণ ব্যবস্থার একটি স্পেসিফিকেশন হয়।
যদিও এটি জটিল মনে হতে পারে, আপনি TFF গণনাগুলিকে ভাল-সংজ্ঞায়িত টাইপ স্বাক্ষর সহ ফাংশন হিসাবে ভাবতে পারেন। এই ধরনের স্বাক্ষর সরাসরি জিজ্ঞাসা করা যেতে পারে.
str(get_average_temperature.type_signature)
'({float32}@CLIENTS -> float32@SERVER)'
এই tff.federated_computation
ফেডারেট টাইপ অফ আর্গুমেন্ট গ্রহণ {float32}@CLIENTS
এবং ফেডারেট ধরনের আয় মান {float32}@SERVER
। ফেডারেটেড গণনা সার্ভার থেকে ক্লায়েন্ট, ক্লায়েন্ট থেকে ক্লায়েন্ট, বা সার্ভার থেকে সার্ভারে যেতে পারে। ফেডারেটেড কম্পিউটেশনগুলিও স্বাভাবিক ফাংশনের মতোই রচিত হতে পারে, যতক্ষণ না তাদের টাইপের স্বাক্ষর মেলে।
উন্নয়ন সমর্থন করতে, TFF আপনি একটি ডাকা করতে পারবেন tff.federated_computation
একটি পাইথন ফাংশন হিসাবে। উদাহরণস্বরূপ, আমরা কল করতে পারি
get_average_temperature([68.5, 70.3, 69.8])
69.53334
অ-আগ্রহী গণনা এবং টেনসরফ্লো
সচেতন হতে দুটি মূল সীমাবদ্ধতা আছে. প্রথমত, যখন পাইথন ইন্টারপ্রেটার একটি encounters tff.federated_computation
প্রসাধক, ফাংশন একবার আঁকা এবং ভবিষ্যতে ব্যবহারের জন্য ধারাবাহিকভাবে হয়। ফেডারেটেড লার্নিং-এর বিকেন্দ্রীভূত প্রকৃতির কারণে, এই ভবিষ্যৎ ব্যবহার অন্যত্র ঘটতে পারে, যেমন দূরবর্তী কার্যকরী পরিবেশ। অতএব, TFF কম্পিউটেশন মৌলিকভাবে অ আগ্রহী। এই আচরণ কিছুটা যে অনুরূপ tf.function
TensorFlow মধ্যে প্রসাধক।
দ্বিতীয়ত, একটি ফেডারেট গণনার শুধুমাত্র (যেমন ফেডারেট অপারেটরদের গঠিত হতে পারে tff.federated_mean
), তারা TensorFlow অপারেশন থাকতে পারে না। TensorFlow কোড দিয়ে সাজানো ব্লক সীমাবদ্ধ করা আবশ্যক tff.tf_computation
। সর্বাধিক সাধারণ TensorFlow কোড সরাসরি যেমন নিম্নলিখিত ফাংশন যা একটি সংখ্যা নেয় এবং যোগ হিসাবে, সজ্জিত করা যায় 0.5
এটি।
@tff.tf_computation(tf.float32)
def add_half(x):
return tf.add(x, 0.5)
এগুলোও টাইপ স্বাক্ষর আছে, কিন্তু এদেশের ছাড়া। উদাহরণস্বরূপ, আমরা কল করতে পারি
str(add_half.type_signature)
'(float32 -> float32)'
এখানে আমরা মধ্যে একটি গুরুত্বপূর্ণ পার্থক্য দেখতে tff.federated_computation
এবং tff.tf_computation
। আগেরটির সুস্পষ্ট প্লেসমেন্ট আছে, যখন পরেরটির নেই৷
আমরা ব্যবহার করতে পারি tff.tf_computation
এদেশের নির্দিষ্ট করে ফেডারেট কম্পিউটেশন ব্লক। এর একটি ফাংশন তৈরি করা যাক যা অর্ধেক যোগ করে, কিন্তু শুধুমাত্র ক্লায়েন্টদের ফেডারেটেড ফ্লোটগুলিতে। আমরা ব্যবহার করে এটা করতে পারেন tff.federated_map
, একজন প্রদত্ত প্রযোজ্য যা tff.tf_computation
, যখন বসানো সংরক্ষণের।
@tff.federated_computation(tff.FederatedType(tf.float32, tff.CLIENTS))
def add_half_on_clients(x):
return tff.federated_map(add_half, x)
এই ফাংশনটি প্রায় অভিন্ন add_half
ছাড়া এটি শুধুমাত্র এ বসানো সঙ্গে মান গ্রহণ করে tff.CLIENTS
একই বসানো সঙ্গে আয় মান, এবং। আমরা এটির টাইপ স্বাক্ষরে এটি দেখতে পারি:
str(add_half_on_clients.type_signature)
'({float32}@CLIENTS -> {float32}@CLIENTS)'
সংক্ষেপে:
- TFF ফেডারেটেড মানগুলির উপর কাজ করে।
- প্রতিটি ফেডারেট মান একটি টাইপ (যেমন। সঙ্গে একটি ফেডারেট টাইপ হয়েছে
tf.float32
) এবং একটি বসানো (যেমন।tff.CLIENTS
)। - ফেডারেটেড মান ফেডারেট কম্পিউটেশন, যা দিয়ে সাজানো করা আবশ্যক ব্যবহার রুপান্তরিত করা যায়
tff.federated_computation
এবং একটি ফেডারেট টাইপ স্বাক্ষর। - TensorFlow কোড সহ ব্লক অন্তর্ভুক্ত করা আবশ্যক
tff.tf_computation
টেকনিক। - এই ব্লকগুলিকে তখন ফেডারেটেড কম্পিউটেশনে অন্তর্ভুক্ত করা যেতে পারে।
আপনার নিজস্ব ফেডারেটেড লার্নিং অ্যালগরিদম তৈরি করা, পুনর্বিবেচনা করা হয়েছে
এখন যেহেতু আমরা ফেডারেটেড কোরের একটি আভাস পেয়েছি, আমরা আমাদের নিজস্ব ফেডারেটেড লার্নিং অ্যালগরিদম তৈরি করতে পারি। মনে রাখবেন যে উপরে, আমরা একটি সংজ্ঞায়িত initialize_fn
এবং next_fn
আমাদের এলগরিদম জন্য। next_fn
ব্যবহার করতে হবে client_update
এবং server_update
আমরা বিশুদ্ধ TensorFlow কোড ব্যবহার সংজ্ঞায়িত।
যাইহোক, অর্ডার আমাদের এলগরিদম একটি ফেডারেট গণনার করতে, আমরা উভয় প্রয়োজন হবে next_fn
এবং initialize_fn
প্রতিটি একটি হতে tff.federated_computation
।
টেনসরফ্লো ফেডারেটেড ব্লক
প্রারম্ভিক গণনা তৈরি করা হচ্ছে
আরম্ভ ফাংশন বেশ সহজ হবে: আমরা একটি মডেল ব্যবহার করে তৈরি করবে model_fn
। যাইহোক, মনে রাখবেন যে আমরা ব্যবহার আমাদের TensorFlow কোড আলাদা নয় tff.tf_computation
।
@tff.tf_computation
def server_init():
model = model_fn()
return model.trainable_variables
আমরা তখন ব্যবহার করে একটি ফেডারেট গণনার মধ্যে সরাসরি এই পাস করতে পারেন tff.federated_value
।
@tff.federated_computation
def initialize_fn():
return tff.federated_value(server_init(), tff.SERVER)
তৈরি করা হচ্ছে next_fn
আমরা এখন প্রকৃত অ্যালগরিদম লিখতে আমাদের ক্লায়েন্ট এবং সার্ভার আপডেট কোড ব্যবহার করি। আমরা প্রথম আমাদের চালু হবে client_update
একটি মধ্যে tff.tf_computation
যে একটি ক্লায়েন্ট ডেটাসেট এবং সার্ভার ওজন গ্রহণ করে, এবং একটি আপডেট ক্লায়েন্ট ওজন টেন্সর আউটপুট।
আমাদের ফাংশনটি সঠিকভাবে সাজানোর জন্য আমাদের সংশ্লিষ্ট প্রকারের প্রয়োজন হবে। ভাগ্যক্রমে, সার্ভারের ওজনের ধরন সরাসরি আমাদের মডেল থেকে বের করা যেতে পারে।
whimsy_model = model_fn()
tf_dataset_type = tff.SequenceType(whimsy_model.input_spec)
আসুন ডেটাসেট টাইপ স্বাক্ষর দেখি। মনে রাখবেন যে আমরা 28 বাই 28 ছবি (পূর্ণসংখ্যা লেবেল সহ) নিয়েছি এবং সেগুলিকে সমতল করেছি।
str(tf_dataset_type)
'<float32[?,784],int32[?,1]>*'
আমরা আমাদের ব্যবহার করে মডেল ওজন টাইপ নিষ্কাশন করতে পারেন server_init
উপরে ফাংশন।
model_weights_type = server_init.type_signature.result
টাইপ স্বাক্ষর পরীক্ষা করে, আমরা আমাদের মডেলের আর্কিটেকচার দেখতে সক্ষম হব!
str(model_weights_type)
'<float32[784,10],float32[10]>'
এখন আমরা আমাদের তৈরি করতে পারেন tff.tf_computation
ক্লায়েন্ট আপডেটের জন্য।
@tff.tf_computation(tf_dataset_type, model_weights_type)
def client_update_fn(tf_dataset, server_weights):
model = model_fn()
client_optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
return client_update(model, tf_dataset, server_weights, client_optimizer)
tff.tf_computation
সার্ভার আপডেট সংস্করণ একই ভাবে সংজ্ঞায়িত করা যায়, ধরন ইতিমধ্যে আমরা নিষ্কাশিত তা ব্যবহার করে।
@tff.tf_computation(model_weights_type)
def server_update_fn(mean_client_weights):
model = model_fn()
return server_update(model, mean_client_weights)
সর্বশেষ, কিন্তু না অন্তত, আমরা তৈরি করতে হবে tff.federated_computation
যে এই সব একসাথে নিয়ে আসে। এই ফাংশনটি দুই ফেডারেট মূল্যবোধ, এক সার্ভার ওজন সংশ্লিষ্ট (বসানো সঙ্গে গ্রহণ করবে tff.SERVER
), এবং অন্যান্য ক্লায়েন্ট ডেটাসেট সংশ্লিষ্ট (বসানো সঙ্গে tff.CLIENTS
)।
উল্লেখ্য যে এই উভয় ধরনের উপরে সংজ্ঞায়িত করা হয়েছে! আমরা কেবল তাদের সঠিক বসানো ব্যবহার দিতে হবে tff.FederatedType
।
federated_server_type = tff.FederatedType(model_weights_type, tff.SERVER)
federated_dataset_type = tff.FederatedType(tf_dataset_type, tff.CLIENTS)
একটি FL অ্যালগরিদমের 4 টি উপাদান মনে রাখবেন?
- একটি সার্ভার থেকে ক্লায়েন্ট সম্প্রচার পদক্ষেপ.
- একটি স্থানীয় ক্লায়েন্ট আপডেট পদক্ষেপ।
- একটি ক্লায়েন্ট থেকে সার্ভার আপলোড ধাপ।
- একটি সার্ভার আপডেট পদক্ষেপ.
এখন যেহেতু আমরা উপরেরটি তৈরি করেছি, প্রতিটি অংশ টিএফএফ কোডের একক লাইন হিসাবে কম্প্যাক্টভাবে উপস্থাপন করা যেতে পারে। এই সরলতার কারণেই আমাদেরকে ফেডারেটেড টাইপের মতো জিনিসগুলি নির্দিষ্ট করতে অতিরিক্ত যত্ন নিতে হয়েছিল!
@tff.federated_computation(federated_server_type, federated_dataset_type)
def next_fn(server_weights, federated_dataset):
# Broadcast the server weights to the clients.
server_weights_at_client = tff.federated_broadcast(server_weights)
# Each client computes their updated weights.
client_weights = tff.federated_map(
client_update_fn, (federated_dataset, server_weights_at_client))
# The server averages these updates.
mean_client_weights = tff.federated_mean(client_weights)
# The server updates its model.
server_weights = tff.federated_map(server_update_fn, mean_client_weights)
return server_weights
আমরা এখন একটি আছে tff.federated_computation
উভয় অ্যালগরিদম আরম্ভের, এবং আলগোরিদিম এক ধাপ চালানোর জন্য জন্য। আমাদের এলগরিদম শেষ করার জন্য, আমরা মধ্যে এই পাস tff.templates.IterativeProcess
।
federated_algorithm = tff.templates.IterativeProcess(
initialize_fn=initialize_fn,
next_fn=next_fn
)
ধরণ স্বাক্ষর যাক চেহারা initialize
এবং next
আমাদের পুনরাবৃত্ত প্রক্রিয়ার ফাংশন।
str(federated_algorithm.initialize.type_signature)
'( -> <float32[784,10],float32[10]>@SERVER)'
বাস্তবে দেখা যায় যে প্রতিফলিত federated_algorithm.initialize
একটি নো ARG ফাংশন যে আয় একটি একক লেয়ার মডেল (ক 784 বাই-10 ওজন ম্যাট্রিক্স সঙ্গে, এবং 10 পক্ষপাত একক)।
str(federated_algorithm.next.type_signature)
'(<server_weights=<float32[784,10],float32[10]>@SERVER,federated_dataset={<float32[?,784],int32[?,1]>*}@CLIENTS> -> <float32[784,10],float32[10]>@SERVER)'
এখানে আমরা দেখতে পাই যে federated_algorithm.next
একটি সার্ভার মডেল এবং ক্লায়েন্ট ডেটা, এবং আয় একটি আপডেট সার্ভার মডেল গ্রহণ করে।
অ্যালগরিদম মূল্যায়ন
এর কয়েক রাউন্ড চালানো যাক, এবং ক্ষতি পরিবর্তিত কিভাবে দেখুন. প্রথমত, আমরা মূল্যায়ন ফাংশন কেন্দ্রীভূত পদ্ধতির দ্বিতীয় টিউটোরিয়ালে আলোচনা ব্যবহার সংজ্ঞায়িত হবে।
আমরা প্রথমে একটি কেন্দ্রীভূত মূল্যায়ন ডেটাসেট তৈরি করি, এবং তারপর প্রশিক্ষণের ডেটার জন্য আমরা যে প্রিপ্রসেসিং ব্যবহার করি তা প্রয়োগ করি।
central_emnist_test = emnist_test.create_tf_dataset_from_all_clients()
central_emnist_test = preprocess(central_emnist_test)
এর পরে, আমরা একটি ফাংশন লিখি যা একটি সার্ভারের অবস্থা গ্রহণ করে এবং পরীক্ষার ডেটাসেটে মূল্যায়ন করতে কেরাস ব্যবহার করে। আপনার সাথে পরিচিত হন, তাহলে tf.Keras
, এই হবে সব বর্ণন পরিচিত, যদিও নোট ব্যবহার set_weights
!
def evaluate(server_state):
keras_model = create_keras_model()
keras_model.compile(
loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=[tf.keras.metrics.SparseCategoricalAccuracy()]
)
keras_model.set_weights(server_state)
keras_model.evaluate(central_emnist_test)
এখন, আসুন আমাদের অ্যালগরিদম শুরু করি এবং পরীক্ষা সেটে মূল্যায়ন করি।
server_state = federated_algorithm.initialize()
evaluate(server_state)
2042/2042 [==============================] - 2s 767us/step - loss: 2.8479 - sparse_categorical_accuracy: 0.1027
চলুন কয়েক রাউন্ডের জন্য ট্রেনিং করি এবং দেখি কিছু পরিবর্তন হয় কিনা।
for round in range(15):
server_state = federated_algorithm.next(server_state, federated_train_data)
evaluate(server_state)
2042/2042 [==============================] - 2s 738us/step - loss: 2.5867 - sparse_categorical_accuracy: 0.0980
আমরা ক্ষতি ফাংশন একটি সামান্য হ্রাস দেখতে. যদিও লাফটি ছোট, আমরা শুধুমাত্র 15টি প্রশিক্ষণ রাউন্ড এবং ক্লায়েন্টদের একটি ছোট উপসেটে পারফর্ম করেছি। আরও ভাল ফলাফল দেখতে, আমাদের হাজার হাজার রাউন্ড না হলেও শত শত করতে হতে পারে।
আমাদের অ্যালগরিদম পরিবর্তন
এই মুহুর্তে, আসুন থামুন এবং আমরা কী অর্জন করেছি সে সম্পর্কে চিন্তা করি। TFF এর ফেডারেটেড কোর থেকে ফেডারেটেড কম্পিউটেশনের সাথে বিশুদ্ধ TensorFlow কোড (ক্লায়েন্ট এবং সার্ভার আপডেটের জন্য) একত্রিত করে আমরা সরাসরি ফেডারেটেড এভারেজিং প্রয়োগ করেছি।
আরও পরিশীলিত শেখার জন্য, আমরা উপরে যা আছে তা পরিবর্তন করতে পারি। বিশেষ করে, উপরের বিশুদ্ধ TF কোডটি সম্পাদনা করে, আমরা ক্লায়েন্ট কীভাবে প্রশিক্ষণ সম্পাদন করে বা সার্ভার কীভাবে তার মডেল আপডেট করে তা পরিবর্তন করতে পারি।
চ্যালেঞ্জ: যোগ গ্রেডিয়েন্ট ক্লিপিং করার client_update
ফাংশন।
আমরা যদি আরও বড় পরিবর্তন করতে চাই, তাহলে আমরা সার্ভার স্টোরও রাখতে পারতাম এবং আরও ডেটা সম্প্রচার করতে পারতাম। উদাহরণস্বরূপ, সার্ভারটি ক্লায়েন্ট শেখার হারও সংরক্ষণ করতে পারে এবং সময়ের সাথে সাথে এটি ক্ষয় করতে পারে! নোট যে এই ব্যবহৃত টাইপ স্বাক্ষর পরিবর্তন প্রয়োজন হবে tff.tf_computation
উপরে কল।
কঠিন চ্যালেঞ্জ: ক্লায়েন্ট হার ক্ষয় শেখার বাস্তবায়ন ফেডারেটেড গড়।
এই মুহুর্তে, আপনি বুঝতে শুরু করতে পারেন যে আপনি এই কাঠামোতে যা বাস্তবায়ন করতে পারেন তাতে কতটা নমনীয়তা রয়েছে। ধারনা (উপরে কঠিন প্রতিদ্বন্দ্বিতার উত্তরে সহ) আপনার জন্য উৎস-কোড দেখতে পারেন tff.learning.build_federated_averaging_process
, অথবা বিভিন্ন খুঁজে বার করো গবেষণা প্রকল্প TFF ব্যবহার করে।