TensorFlow 2-এ TF হাব থেকে সংরক্ষিত মডেলগুলি

TensorFlow 2-এর SavedModel ফরম্যাট হল TensorFlow Hub-এ প্রাক-প্রশিক্ষিত মডেল এবং মডেলের টুকরো শেয়ার করার প্রস্তাবিত উপায়। এটি পুরানো TF1 হাব ফর্ম্যাট প্রতিস্থাপন করে এবং একটি নতুন সেট API এর সাথে আসে।

নিম্ন-স্তরের hub.load() API এবং এর hub.KerasLayer র‍্যাপার সহ একটি TensorFlow 2 প্রোগ্রামে TF2 SavedModels কিভাবে পুনরায় ব্যবহার করা যায় এই পৃষ্ঠাটি ব্যাখ্যা করে। (সাধারণত, hub.KerasLayer অন্যান্য tf.keras.layers এর সাথে একত্রিত করে কেরাস মডেল বা একটি TF2 এস্টিমেটরের model_fn তৈরি করা হয়।) এই APIগুলি সীমার মধ্যে, লিগ্যাসি মডেলগুলিকে TF1 হাব ফর্ম্যাটেও লোড করতে পারে, সামঞ্জস্য নির্দেশিকা দেখুন।

TensorFlow 1 ব্যবহারকারীরা TF 1.15-এ আপডেট করতে পারে এবং তারপর একই API ব্যবহার করতে পারে। TF1 এর পুরানো সংস্করণগুলি কাজ করে না।

TF হাব থেকে সংরক্ষিত মডেল ব্যবহার করা

কেরাসে একটি সংরক্ষিত মডেল ব্যবহার করা

Keras কেরাস লেয়ার অবজেক্ট তৈরি করে গভীর শিক্ষার মডেল তৈরি করার জন্য TensorFlow-এর উচ্চ-স্তরের API। tensorflow_hub লাইব্রেরি ক্লাস hub.KerasLayer প্রদান করে যেটি একটি SavedModel-এর URL (বা ফাইল সিস্টেম পাথ) দিয়ে আরম্ভ করা হয় এবং তারপর SavedModel থেকে গণনা প্রদান করে, এর প্রাক-প্রশিক্ষিত ওজন সহ।

এখানে একটি প্রাক-প্রশিক্ষিত পাঠ্য এমবেডিং ব্যবহার করার একটি উদাহরণ রয়েছে:

import tensorflow as tf
import tensorflow_hub as hub

hub_url = "https://tfhub.dev/google/nnlm-en-dim128/2"
embed = hub.KerasLayer(hub_url)
embeddings = embed(["A long sentence.", "single-word", "http://example.com"])
print(embeddings.shape, embeddings.dtype)

এটি থেকে, একটি টেক্সট ক্লাসিফায়ার স্বাভাবিক কেরাস উপায়ে তৈরি করা যেতে পারে:

model = tf.keras.Sequential([
    embed,
    tf.keras.layers.Dense(16, activation="relu"),
    tf.keras.layers.Dense(1, activation="sigmoid"),
])

টেক্সট ক্লাসিফিকেশন কোল্যাব হল একটি সম্পূর্ণ উদাহরণ কিভাবে এই ধরনের ক্লাসিফায়ারের প্রশিক্ষণ এবং মূল্যায়ন করা যায়।

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

একটি এস্টিমেটরে একটি সংরক্ষিত মডেল ব্যবহার করা

বিতরণ করা প্রশিক্ষণের জন্য TensorFlow-এর অনুমানকারী API-এর ব্যবহারকারীরা TF Hub থেকে তাদের model_fn লিখে অন্যান্য tf.keras.layers এর মধ্যে hub.KerasLayer এর পরিপ্রেক্ষিতে SavedModels ব্যবহার করতে পারেন।

পর্দার পিছনে: SavedModel ডাউনলোড এবং ক্যাশিং

TensorFlow হাব (অথবা অন্যান্য HTTPS সার্ভার যা এর হোস্টিং প্রোটোকল প্রয়োগ করে) থেকে একটি SavedModel ব্যবহার করে ডাউনলোড হয় এবং ইতিমধ্যে উপস্থিত না থাকলে স্থানীয় ফাইল সিস্টেমে এটিকে ডিকম্প্রেস করে। এনভায়রনমেন্ট ভেরিয়েবল TFHUB_CACHE_DIR ডাউনলোড করা এবং আনকম্প্রেস করা সেভড মডেল ক্যাশ করার জন্য ডিফল্ট অস্থায়ী অবস্থান ওভাররাইড করতে সেট করা যেতে পারে। বিস্তারিত জানার জন্য, ক্যাশিং দেখুন।

নিম্ন-স্তরের টেনসরফ্লোতে একটি সংরক্ষিত মডেল ব্যবহার করা

মডেল হ্যান্ডলগুলি

সংরক্ষিত মডেলগুলি একটি নির্দিষ্ট handle থেকে লোড করা যেতে পারে, যেখানে handle একটি ফাইল সিস্টেম পাথ, বৈধ TFhub.dev মডেল URL (যেমন "https://tfhub.dev/...")। Kaggle মডেলের URLs মিরর TFhub.dev আমাদের শর্তাবলী এবং মডেল সম্পদের সাথে যুক্ত লাইসেন্স অনুযায়ী পরিচালনা করে, যেমন, "https://www.kaggle.com/..."। Kaggle মডেলের হ্যান্ডেলগুলি তাদের সংশ্লিষ্ট TFhub.dev হ্যান্ডেলের সমতুল্য।

ফাংশন hub.load(handle) একটি SavedModel ডাউনলোড করে এবং ডিকম্প্রেস করে (যদি না handle ইতিমধ্যেই একটি ফাইল সিস্টেম পাথ হয়) এবং তারপর TensorFlow-এর অন্তর্নির্মিত ফাংশন tf.saved_model.load() দিয়ে লোড করার ফলাফল প্রদান করে। অতএব, hub.load() যেকোন বৈধ SavedModel (TF1 এর পূর্বসূরি hub.Module বিপরীতে) পরিচালনা করতে পারে।

উন্নত বিষয়: লোড করার পরে সংরক্ষিত মডেল থেকে কী আশা করা যায়

SavedModel-এর বিষয়বস্তুর উপর নির্ভর করে, obj = hub.load(...) এর ফলাফল বিভিন্ন উপায়ে আহ্বান করা যেতে পারে (যেমন TensorFlow-এর SavedModel গাইডে আরও বিশদে ব্যাখ্যা করা হয়েছে:

  • সংরক্ষিত মডেলের সার্ভিং স্বাক্ষরগুলি (যদি থাকে) কংক্রিট ফাংশনগুলির অভিধান হিসাবে উপস্থাপিত হয় এবং একে বলা যেতে পারে tensors_out = obj.signatures["serving_default"](**tensors_in) , সংশ্লিষ্ট ইনপুট এবং আউটপুট দ্বারা কী করা টেনসরগুলির অভিধান সহ নাম এবং স্বাক্ষরের আকৃতি এবং dtype সীমাবদ্ধতার বিষয়।

  • সংরক্ষিত অবজেক্টের @tf.function -সজ্জিত পদ্ধতিগুলি (যদি থাকে) tf.function অবজেক্ট হিসাবে পুনরুদ্ধার করা হয় যেগুলিকে টেনসর এবং নন-টেনসর আর্গুমেন্টের সমস্ত সমন্বয় দ্বারা কল করা যেতে পারে যার জন্য tf.function সংরক্ষণ করার আগে ট্রেস করা হয়েছিল। বিশেষ করে, যদি উপযুক্ত ট্রেস সহ একটি obj.__call__ পদ্ধতি থাকে, তাহলে obj নিজেই একটি পাইথন ফাংশনের মতো বলা যেতে পারে। একটি সাধারণ উদাহরণ output_tensor = obj(input_tensor, training=False) এর মত দেখতে পারে।

এটি সংরক্ষিত মডেলগুলি প্রয়োগ করতে পারে এমন ইন্টারফেসে প্রচুর স্বাধীনতা দেয়। obj এর জন্য পুনঃব্যবহারযোগ্য SavedModels ইন্টারফেস এমন প্রথা স্থাপন করে যাতে hub.KerasLayer এর মত অ্যাডাপ্টার সহ ক্লায়েন্ট কোড, কিভাবে SavedModel ব্যবহার করতে হয় তা জানে।

কিছু সংরক্ষিত মডেল সেই নিয়ম অনুসরণ নাও করতে পারে, বিশেষ করে পুরো মডেলগুলি বড় মডেলগুলিতে পুনঃব্যবহারের জন্য নয়, এবং শুধুমাত্র পরিবেশন স্বাক্ষর প্রদান করে।

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

TF হাবের জন্য সংরক্ষিত মডেল তৈরি করা

ওভারভিউ

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

কেরাস থেকে সংরক্ষণ

TensorFlow 2 দিয়ে শুরু করে, tf.keras.Model.save() এবং tf.keras.models.save_model() SavedModel ফরম্যাটে ডিফল্ট (HDF5 নয়)। ফলস্বরূপ সংরক্ষিত মডেলগুলি যেগুলি উপলব্ধ হওয়ার সাথে সাথে hub.load() , hub.KerasLayer এবং অন্যান্য উচ্চ-স্তরের APIগুলির জন্য অনুরূপ অ্যাডাপ্টারগুলির সাথে ব্যবহার করা যেতে পারে৷

একটি সম্পূর্ণ কেরাস মডেল শেয়ার করতে, এটিকে শুধুমাত্র include_optimizer=False দিয়ে সংরক্ষণ করুন।

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

piece_to_share = tf.keras.Model(...)
full_model = tf.keras.Sequential([piece_to_share, ...])
full_model.fit(...)
piece_to_share.save(...)

...অথবা সত্যের পরে ভাগ করার জন্য অংশটি কেটে ফেলুন (যদি এটি আপনার সম্পূর্ণ মডেলের স্তরের সাথে সারিবদ্ধ হয়):

full_model = tf.keras.Model(...)
sharing_input = full_model.get_layer(...).get_output_at(0)
sharing_output = full_model.get_layer(...).get_output_at(0)
piece_to_share = tf.keras.Model(sharing_input, sharing_output)
piece_to_share.save(..., include_optimizer=False)

GitHub-এ টেনসরফ্লো মডেলগুলি BERT-এর জন্য পূর্বের পদ্ধতি ব্যবহার করে ( nlp/tools/export_tfhub_lib.py দেখুন, রপ্তানির জন্য core_model এবং চেকপয়েন্ট পুনরুদ্ধার করার জন্য pretrainer মধ্যে বিভক্তি লক্ষ্য করুন) এবং ResNet-এর জন্য পরবর্তী পদ্ধতি ( উত্তরাধিকার/image_classification/t. দেখুন। )

নিম্ন-স্তরের টেনসরফ্লো থেকে সংরক্ষণ করা হচ্ছে

এর জন্য TensorFlow এর SavedModel গাইডের সাথে ভালো পরিচিতি প্রয়োজন।

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

class MyMulModel(tf.train.Checkpoint):
  def __init__(self, v_init):
    super().__init__()
    self.v = tf.Variable(v_init)
    self.variables = [self.v]
    self.trainable_variables = [self.v]
    self.regularization_losses = [
        tf.function(input_signature=[])(lambda: 0.001 * self.v**2),
    ]

  @tf.function(input_signature=[tf.TensorSpec(shape=None, dtype=tf.float32)])
  def __call__(self, inputs):
    return tf.multiply(inputs, self.v)

tf.saved_model.save(MyMulModel(2.0), "/tmp/my_mul")

layer = hub.KerasLayer("/tmp/my_mul")
print(layer([10., 20.]))  # [20., 40.]
layer.trainable = True
print(layer.trainable_weights)  # [2.]
print(layer.losses)  # 0.004

ফাইন-টিউনিং

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

ফাইন-টিউনিং প্রশিক্ষিত "অবিরাম" মডেল প্যারামিটার পরিবর্তন করে। এটি হার্ড-কোডেড রূপান্তর পরিবর্তন করে না, যেমন টোকেনাইজিং টেক্সট ইনপুট এবং একটি এমবেডিং ম্যাট্রিক্সে তাদের সংশ্লিষ্ট এন্ট্রিতে টোকেন ম্যাপিং।

SavedModel গ্রাহকদের জন্য

একটি hub.KerasLayer তৈরি করা। কেরাস লেয়ারের মতো

layer = hub.KerasLayer(..., trainable=True)

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

ইমেজ ক্লাসিফিকেশন কোলাবে ঐচ্ছিক ফাইন-টিউনিং সহ একটি এন্ড-টু-এন্ড উদাহরণ রয়েছে।

ফাইন-টিউনিং ফলাফল পুনরায় রপ্তানি করা হচ্ছে

উন্নত ব্যবহারকারীরা সূক্ষ্ম-টিউনিংয়ের ফলাফলগুলিকে একটি SavedModel-এ সংরক্ষণ করতে চাইতে পারে যা মূলত লোড হওয়া পরিবর্তে ব্যবহার করা যেতে পারে। এই মত কোড দিয়ে করা যেতে পারে

loaded_obj = hub.load("https://tfhub.dev/...")
hub_layer = hub.KerasLayer(loaded_obj, trainable=True, ...)

model = keras.Sequential([..., hub_layer, ...])
model.compile(...)
model.fit(...)

export_module_dir = os.path.join(os.getcwd(), "finetuned_model_export")
tf.saved_model.save(loaded_obj, export_module_dir)

SavedModel নির্মাতাদের জন্য

TensorFlow Hub-এ শেয়ার করার জন্য একটি SavedModel তৈরি করার সময়, এর ভোক্তাদের এটিকে কীভাবে সূক্ষ্ম-টিউন করা উচিত এবং ডকুমেন্টেশনে নির্দেশিকা প্রদান করা উচিত কিনা তা ভেবে দেখুন।

একটি কেরাস মডেল থেকে সঞ্চয় করা উচিত সূক্ষ্ম-টিউনিং কাজের সমস্ত মেকানিক্স করা (ওজন নিয়মিতকরণের ক্ষতি সাশ্রয় করা, প্রশিক্ষণযোগ্য ভেরিয়েবল ঘোষণা করা, প্রশিক্ষণের জন্য __call__ ট্রেসিং training=True এবং training=False , ইত্যাদি)

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

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

পৃথক স্তরগুলিতে ওজন নিয়মিতকরণগুলি সংরক্ষণ করা হয় (তাদের নিয়মিতকরণ শক্তি সহগ সহ), তবে অপ্টিমাইজারের মধ্যে থেকে ওজন নিয়মিতকরণ (যেমন tf.keras.optimizers.Ftrl.l1_regularization_strength=...) ) হারিয়ে যায়। সেই অনুযায়ী আপনার সংরক্ষিত মডেলের ভোক্তাদের পরামর্শ দিন।