পুনঃব্যবহারযোগ্য সংরক্ষিত মডেল

ভূমিকা

TensorFlow Hub অন্যান্য অ্যাসেটের পাশাপাশি TensorFlow 2-এর জন্য SavedModel-গুলোও হোস্ট করে। obj = hub.load(url) [ আরও জানুন ] ব্যবহার করে এগুলোকে একটি পাইথন প্রোগ্রামে পুনরায় লোড করা যায়। ফেরত আসা obj হলো tf.saved_model.load() -এর ফলাফল (TensorFlow-এর SavedModel গাইড দেখুন)। এই অবজেক্টটিতে tf.functions, tf.Variables (তাদের প্রি-ট্রেইনড মান থেকে ইনিশিয়ালাইজ করা), অন্যান্য রিসোর্স এবং রিকার্সিভলি এই ধরনের আরও অবজেক্টের মতো যেকোনো অ্যাট্রিবিউট থাকতে পারে।

এই পৃষ্ঠাটি এমন একটি ইন্টারফেসের বর্ণনা দেয় যা লোড করা obj একটি TensorFlow পাইথন প্রোগ্রামে পুনঃব্যবহার করার জন্য ইমপ্লিমেন্ট করতে হয়। যে SavedModel-গুলো এই ইন্টারফেস মেনে চলে, সেগুলোকে Reusable SavedModel বলা হয়।

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

TensorFlow Hub টিম সেই সমস্ত SavedModel-এ Reusable SavedModel ইন্টারফেসটি প্রয়োগ করার পরামর্শ দেয়, যেগুলো উপরোক্ত অর্থে পুনঃব্যবহারের জন্য তৈরি। tensorflow_hub লাইব্রেরির অনেক ইউটিলিটি, বিশেষ করে hub.KerasLayer , ব্যবহারের জন্য SavedModel-গুলোতে এটি প্রয়োগ করা আবশ্যক।

SignatureDefs-এর সাথে সম্পর্ক

tf.functions এবং TF2-এর অন্যান্য ফিচারের ক্ষেত্রে এই ইন্টারফেসটি SavedModel-এর সিগনেচার থেকে আলাদা, যা TF1 থেকে উপলব্ধ এবং TF2-তে ইনফারেন্সের জন্য (যেমন TF Serving বা TF Lite-এ SavedModel ডেপ্লয় করার জন্য) এখনও ব্যবহৃত হয়। ইনফারেন্সের জন্য ব্যবহৃত সিগনেচারগুলো ফাইন-টিউনিং সমর্থন করার জন্য যথেষ্ট এক্সপ্রেসিভ নয়, এবং tf.function পুনঃব্যবহৃত মডেলের জন্য একটি আরও স্বাভাবিক ও এক্সপ্রেসিভ পাইথন এপিআই প্রদান করে।

মডেল-বিল্ডিং লাইব্রেরির সাথে সম্পর্ক

একটি পুনঃব্যবহারযোগ্য সংরক্ষিত মডেল (Reusable SavedModel) শুধুমাত্র TensorFlow 2-এর আদিম উপাদান (primitives) ব্যবহার করে, যা Keras বা Sonnet-এর মতো কোনো নির্দিষ্ট মডেল-বিল্ডিং লাইব্রেরির উপর নির্ভরশীল নয়। এটি মূল মডেল-বিল্ডিং কোডের উপর নির্ভরতা ছাড়াই বিভিন্ন মডেল-বিল্ডিং লাইব্রেরির মধ্যে পুনঃব্যবহারকে সহজতর করে।

যেকোনো মডেল-বিল্ডিং লাইব্রেরি থেকে পুনঃব্যবহারযোগ্য সেভডমডেল লোড করতে বা সেভ করতে কিছু অভিযোজনের প্রয়োজন হবে। কেরাসের জন্য, hub.KerasLayer লোড করার সুবিধা প্রদান করে, এবং কেরাসের বিল্ট-ইন সেভিং পদ্ধতি SavedModel ফরম্যাটে TF2-এর জন্য নতুন করে ডিজাইন করা হয়েছে, যার লক্ষ্য হলো এই ইন্টারফেসের একটি সুপারসেট প্রদান করা (মে ২০১৯-এর RFC দেখুন)।

টাস্ক-নির্দিষ্ট "সাধারণ সংরক্ষিত মডেল এপিআই"-এর সাথে সম্পর্ক

এই পৃষ্ঠার ইন্টারফেস সংজ্ঞাটি যেকোনো সংখ্যক ও ধরনের ইনপুট এবং আউটপুটের সুযোগ দেয়। TF Hub-এর জন্য Common SavedModel API-গুলো নির্দিষ্ট কাজের জন্য ব্যবহারের নিয়মাবলীর মাধ্যমে এই সাধারণ ইন্টারফেসটিকে পরিমার্জন করে, যাতে মডেলগুলো সহজে বিনিময়যোগ্য হয়।

ইন্টারফেস সংজ্ঞা

বৈশিষ্ট্য

একটি পুনঃব্যবহারযোগ্য সেভডমডেল হলো এমন একটি টেনসরফ্লো ২ সেভডমডেল, যার থেকে obj = tf.saved_model.load(...) কমান্ডটি এমন একটি অবজেক্ট রিটার্ন করে, যাতে নিম্নলিখিত অ্যাট্রিবিউটগুলো থাকে।

  • __call__ . আবশ্যক। একটি tf.function যা নিচের স্পেসিফিকেশন সাপেক্ষে মডেলের গণনা ("ফরোয়ার্ড পাস") বাস্তবায়ন করে।

  • variables : tf.Variable অবজেক্টের একটি তালিকা, যেখানে __call__ এর যেকোনো সম্ভাব্য আহ্বানে ব্যবহৃত সমস্ত ভেরিয়েবল তালিকাভুক্ত থাকে, যার মধ্যে প্রশিক্ষণযোগ্য এবং অপ্রশিক্ষণযোগ্য উভয় প্রকার ভেরিয়েবলই অন্তর্ভুক্ত।

    এই তালিকাটি খালি থাকলে বাদ দেওয়া যেতে পারে।

  • trainable_variables : tf.Variable অবজেক্টের একটি তালিকা, যেখানে প্রতিটি উপাদানের জন্য v.trainable সত্য। এই ভেরিয়েবলগুলো অবশ্যই variables এর একটি উপসেট হতে হবে। অবজেক্টটি ফাইন-টিউনিং করার সময় এই ভেরিয়েবলগুলোকেই প্রশিক্ষণ দেওয়া হবে। SavedModel-এর নির্মাতা এখানে কিছু ভেরিয়েবল বাদ দিতে পারেন যেগুলো মূলত প্রশিক্ষণযোগ্য ছিল, এটি বোঝানোর জন্য যে ফাইন-টিউনিং-এর সময় এগুলো পরিবর্তন করা উচিত নয়।

    এই তালিকাটি খালি থাকলে বাদ দেওয়া যেতে পারে, বিশেষ করে যদি SavedModel-টি ফাইন-টিউনিং সমর্থন না করে।

  • regularization_losses : tf.functions-এর একটি তালিকা, যার প্রতিটি শূন্য ইনপুট গ্রহণ করে এবং একটি একক স্কেলার ফ্লোট টেনসর রিটার্ন করে। ফাইন-টিউনিং-এর জন্য, SavedModel ব্যবহারকারীকে লস-এর মধ্যে অতিরিক্ত রেগুলাইজেশন টার্ম হিসেবে এগুলো অন্তর্ভুক্ত করার পরামর্শ দেওয়া হয় (সবচেয়ে সরল ক্ষেত্রে, কোনো অতিরিক্ত স্কেলিং ছাড়াই)। সাধারণত, এগুলো ওয়েট রেগুলাইজারকে উপস্থাপন করতে ব্যবহৃত হয়। (ইনপুটের অভাবে, এই tf.functions-গুলো অ্যাক্টিভিটি রেগুলাইজার প্রকাশ করতে পারে না।)

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

__call__ ফাংশন

একটি রিস্টোরড সেভডমডেল obj একটি obj.__call__ অ্যাট্রিবিউট থাকে, যা একটি রিস্টোরড tf.function এবং এর মাধ্যমে obj নিম্নোক্তভাবে কল করা যায়।

সারসংক্ষেপ (ছদ্ম-কোড):

outputs = obj(inputs, trainable=..., **kwargs)

যুক্তি

যুক্তিগুলো নিম্নরূপ।

  • SavedModel-এর ইনপুট অ্যাক্টিভেশনগুলোর একটি ব্যাচের সাথে একটি পজিশনাল, আবশ্যক আর্গুমেন্ট রয়েছে। এর টাইপ হলো নিম্নলিখিতগুলোর মধ্যে একটি।

    • একটি ইনপুটের জন্য একটি একক টেনসর,
    • নামবিহীন ইনপুটগুলির একটি ক্রমিক অনুক্রমের জন্য টেনসরগুলির একটি তালিকা,
    • নির্দিষ্ট কিছু ইনপুট নাম দ্বারা কী করা টেনসরগুলোর একটি ডিক্ট।

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

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

    __call__ ফাংশনের জন্য টেনসর-মানের training আর্গুমেন্ট গ্রহণ করা আবশ্যক নয়। প্রয়োজনে এদের মধ্যে আদান-প্রদানের জন্য tf.cond() ব্যবহার করার দায়িত্ব কলারের।

  • SavedModel-এর নির্মাতা নির্দিষ্ট নামের আরও ঐচ্ছিক kwargs গ্রহণ করার সিদ্ধান্ত নিতে পারেন।

    • Tensor-মানযুক্ত আর্গুমেন্টগুলির জন্য, SavedModel নির্মাতা তাদের অনুমোদিত dtypes এবং shapes নির্ধারণ করে দেন। tf.function এমন একটি আর্গুমেন্টে পাইথনের ডিফল্ট মান গ্রহণ করে, যা একটি tf.TensorSpec ইনপুট দিয়ে ট্রেস করা হয়। এই ধরনের আর্গুমেন্টগুলি __call__ এর সাথে জড়িত সাংখ্যিক হাইপারপ্যারামিটারগুলির (যেমন, ড্রপআউট রেট) কাস্টমাইজেশনের সুযোগ দিতে ব্যবহার করা যেতে পারে।

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

পুনরুদ্ধার করা __call__ ফাংশনটিকে অবশ্যই আর্গুমেন্টের সমস্ত অনুমোদিত সংমিশ্রণের জন্য ট্রেস প্রদান করতে হবে। True এবং False এর মধ্যে training পরিবর্তন করলে আর্গুমেন্টের অনুমোদনযোগ্যতা বদলাবে না।

ফলাফল

obj কল করার ফলে outputs হতে পারে

  • একটি আউটপুটের জন্য একটি একক টেনসর,
  • নামবিহীন আউটপুটগুলির একটি ক্রমিক অনুক্রমের জন্য টেনসরগুলির একটি তালিকা,
  • নির্দিষ্ট কিছু আউটপুট নাম দ্বারা কী করা টেনসরগুলোর একটি ডিক্ট।

(এই ইন্টারফেসের ভবিষ্যৎ সংস্করণগুলিতে আরও সাধারণ নেস্টের অনুমতি দেওয়া হতে পারে।) পাইথন-ভিত্তিক kwargs-এর উপর নির্ভর করে রিটার্ন টাইপ ভিন্ন হতে পারে। এটি ফ্ল্যাগ ব্যবহার করে অতিরিক্ত আউটপুট তৈরির সুযোগ দেয়। SavedModel ক্রিয়েটর আউটপুটের dtypes ও shapes এবং ইনপুটের উপর তাদের নির্ভরতা নির্ধারণ করে।

নামযুক্ত আহ্বানযোগ্য

একটি পুনঃব্যবহারযোগ্য সংরক্ষিত মডেল (Reusable SavedModel) উপরে বর্ণিত পদ্ধতিতে একাধিক মডেলের অংশ সরবরাহ করতে পারে, সেগুলোকে নামযুক্ত সাবঅবজেক্টে রেখে, যেমন, obj.foo , obj.bar ইত্যাদি। প্রতিটি সাবঅবজেক্ট একটি __call__ মেথড এবং সেই নির্দিষ্ট মডেলের অংশের জন্য প্রয়োজনীয় ভেরিয়েবল ইত্যাদি সম্পর্কিত সহায়ক অ্যাট্রিবিউট সরবরাহ করে। উপরের উদাহরণটির জন্য, obj.foo.__call__ , obj.foo.variables ইত্যাদি থাকবে।

উল্লেখ্য যে, এই ইন্টারফেসটি সরাসরি tf.foo হিসেবে একটি খালি tf.function যোগ করার পদ্ধতি সমর্থন করে না ।

পুনঃব্যবহারযোগ্য সংরক্ষিত মডেলের (Reusable SavedModels) ব্যবহারকারীদের কেবল এক স্তরের নেস্টিং ( obj.bar , কিন্তু obj.bar.baz নয়) পরিচালনা করতে হবে। (এই ইন্টারফেসের ভবিষ্যৎ সংস্করণগুলোতে আরও গভীর নেস্টিংয়ের অনুমতি দেওয়া হতে পারে এবং শীর্ষ-স্তরের অবজেক্টটিকে নিজে কলযোগ্য হওয়ার আবশ্যকতাটি শিথিল করা হতে পারে।)

সমাপনী বক্তব্য

প্রক্রিয়াধীন এপিআইগুলির সাথে সম্পর্ক

এই ডকুমেন্টটি একটি পাইথন ক্লাসের ইন্টারফেস বর্ণনা করে, যা tf.function এবং tf.Variable-এর মতো প্রিমিটিভ নিয়ে গঠিত এবং যা tf.saved_model.save() ও tf.saved_model.load() এর মাধ্যমে সিরিয়ালাইজেশনের রাউন্ড-ট্রিপ সম্পন্ন করে। তবে, tf.saved_model.save() এ পাস করা মূল অবজেক্টটিতে ইন্টারফেসটি আগে থেকেই উপস্থিত ছিল। সেই ইন্টারফেসটির সাথে অভিযোজন একটিমাত্র TensorFlow প্রোগ্রামের মধ্যে মডেল-বিল্ডিং API-গুলোর মধ্যে মডেলের অংশবিশেষ বিনিময় সম্ভব করে তোলে।