TensorFlow 2 में TF हब से SaveModels

TensorFlow 2 का SaveModel प्रारूप TensorFlow हब पर पूर्व-प्रशिक्षित मॉडल और मॉडल के टुकड़े साझा करने का अनुशंसित तरीका है। यह पुराने TF1 हब प्रारूप को प्रतिस्थापित करता है और एपीआई के एक नए सेट के साथ आता है।

यह पृष्ठ बताता है कि निम्न-स्तरीय hub.load() एपीआई और इसके hub.KerasLayer रैपर के साथ TensorFlow 2 प्रोग्राम में TF2 सेव्डमॉडल का पुन: उपयोग कैसे करें। (आमतौर पर, hub.KerasLayer अन्य tf.keras.layers के साथ मिलाकर एक Keras मॉडल या TF2 एस्टीमेटर का model_fn बनाया जाता है।) ये API सीमा के भीतर, TF1 हब प्रारूप में लीगेसी मॉडल को भी लोड कर सकते हैं, संगतता गाइड देखें।

TensorFlow 1 के उपयोगकर्ता TF 1.15 पर अपडेट कर सकते हैं और फिर उसी API का उपयोग कर सकते हैं। TF1 के पुराने संस्करण काम नहीं करते.

TF हब से SaveModels का उपयोग करना

केरस में सेव्डमॉडल का उपयोग करना

केरस, केरस लेयर ऑब्जेक्ट्स की रचना करके गहन शिक्षण मॉडल बनाने के लिए टेन्सरफ्लो का उच्च-स्तरीय एपीआई है। 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 में मॉडल का वजन डिफ़ॉल्ट रूप से गैर-प्रशिक्षित करने योग्य पर सेट होता है। इसे कैसे बदलें, इसके लिए नीचे फ़ाइन-ट्यूनिंग अनुभाग देखें। केरस में हमेशा की तरह, एक ही परत ऑब्जेक्ट के सभी अनुप्रयोगों के बीच वजन साझा किया जाता है।

एक अनुमानक में सेव्डमॉडल का उपयोग करना

वितरित प्रशिक्षण के लिए टेन्सरफ्लो के एस्टिमेटर एपीआई के उपयोगकर्ता अन्य tf.keras.layers के बीच hub.KerasLayer के संदर्भ में अपना model_fn लिखकर TF हब से SavedModels का उपयोग कर सकते हैं।

पर्दे के पीछे: सेव्डमॉडल डाउनलोडिंग और कैशिंग

TensorFlow हब (या अन्य HTTPS सर्वर जो इसके होस्टिंग प्रोटोकॉल को लागू करते हैं) से सेव्डमॉडल का उपयोग करके इसे डाउनलोड करता है और यदि पहले से मौजूद नहीं है तो इसे स्थानीय फाइल सिस्टम में डीकंप्रेस करता है। पर्यावरण चर TFHUB_CACHE_DIR डाउनलोड किए गए और असम्पीडित सेव्डमॉडल को कैशिंग के लिए डिफ़ॉल्ट अस्थायी स्थान को ओवरराइड करने के लिए सेट किया जा सकता है। विवरण के लिए, कैशिंग देखें।

निम्न-स्तरीय TensorFlow में SaveModel का उपयोग करना

मॉडल हैंडल

SaveModels को एक निर्दिष्ट handle से लोड किया जा सकता है, जहां handle एक फ़ाइल सिस्टम पथ है, वैध TFhub.dev मॉडल URL (उदाहरण के लिए "https://tfhub.dev/...")। कागल मॉडल यूआरएल हमारी शर्तों और मॉडल परिसंपत्तियों से जुड़े लाइसेंस के अनुसार TFhub.dev हैंडल को प्रतिबिंबित करते हैं, उदाहरण के लिए, "https://www.kaggle.com/..."। कागल मॉडल के हैंडल उनके संबंधित TFhub.dev हैंडल के बराबर हैं।

फ़ंक्शन hub.load(handle) एक SavedModel को डाउनलोड और डीकंप्रेस करता है (जब तक कि handle पहले से ही एक फ़ाइल सिस्टम पथ न हो) और फिर इसे TensorFlow के अंतर्निहित फ़ंक्शन tf.saved_model.load() के साथ लोड करने का परिणाम देता है। इसलिए, hub.load() किसी भी वैध SavedModel को संभाल सकता है (TF1 के लिए अपने पूर्ववर्ती hub.Module के विपरीत)।

उन्नत विषय: लोड करने के बाद सेव्डमॉडल से क्या अपेक्षा करें

सेव्डमॉडल की सामग्री के आधार पर, obj = hub.load(...) का परिणाम विभिन्न तरीकों से लागू किया जा सकता है (जैसा कि TensorFlow के सेव्डमॉडल गाइड में बहुत अधिक विस्तार से बताया गया है:

  • सेव्डमॉडल (यदि कोई हो) के सेवारत हस्ताक्षरों को ठोस कार्यों के शब्दकोश के रूप में दर्शाया जाता है और tensors_out = obj.signatures["serving_default"](**tensors_in) की तरह कहा जा सकता है, संबंधित इनपुट और आउटपुट द्वारा कुंजीबद्ध टेंसर के शब्दकोशों के साथ नाम और हस्ताक्षर के आकार और प्रकार की बाधाओं के अधीन।

  • सहेजे गए ऑब्जेक्ट (यदि कोई हो) के @tf.function -सजाए गए तरीकों को tf.function ऑब्जेक्ट के रूप में पुनर्स्थापित किया जाता है, जिन्हें Tensor और गैर-Tensor तर्कों के सभी संयोजनों द्वारा बुलाया जा सकता है, जिनके लिए tf.function को सहेजने से पहले पता लगाया गया था। विशेष रूप से, यदि उपयुक्त निशानों के साथ कोई obj.__call__ विधि है, obj स्वयं पायथन फ़ंक्शन की तरह कहा जा सकता है। एक साधारण उदाहरण output_tensor = obj(input_tensor, training=False) जैसा दिख सकता है।

यह उन इंटरफेस में भारी स्वतंत्रता छोड़ता है जिन्हें SavedModels लागू कर सकता है। obj के लिए पुन: प्रयोज्य सेव्डमॉडल इंटरफ़ेस ऐसे सम्मेलन स्थापित करता है कि क्लाइंट कोड, जिसमें hub.KerasLayer जैसे एडेप्टर शामिल हैं, जानते हैं कि सेव्डमॉडल का उपयोग कैसे करें।

कुछ सेव्डमॉडल उस सम्मेलन का पालन नहीं कर सकते हैं, विशेष रूप से पूरे मॉडल जो बड़े मॉडल में पुन: उपयोग के लिए नहीं हैं, और केवल सेवारत हस्ताक्षर प्रदान करते हैं।

सेव्डमॉडल में प्रशिक्षित करने योग्य चर को प्रशिक्षित करने योग्य के रूप में पुनः लोड किया जाता है, और tf.GradientTape उन्हें डिफ़ॉल्ट रूप से देखेगा। कुछ चेतावनियों के लिए नीचे फ़ाइन-ट्यूनिंग पर अनुभाग देखें, और शुरुआत करने वालों के लिए इससे बचने पर विचार करें। यहां तक ​​कि अगर आप फाइन-ट्यून करना चाहते हैं, तो आप यह देखना चाहेंगे कि क्या obj.trainable_variables मूल रूप से प्रशिक्षित चर के केवल एक उपसमूह को फिर से प्रशिक्षित करने की सलाह देता है।

टीएफ हब के लिए सेव्डमॉडल बनाना

सिंहावलोकन

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

केरस से बचाव

TensorFlow 2 से शुरू होकर, tf.keras.Model.save() और tf.keras.models.save_model() डिफ़ॉल्ट रूप से SavedModel प्रारूप में आते हैं (HDF5 नहीं)। परिणामी SavedModels का उपयोग 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 पर TensorFlow मॉडल BERT के लिए पूर्व दृष्टिकोण का उपयोग करता है ( nlp/tools/export_tfhub_lib.py देखें, निर्यात के लिए core_model और चेकपॉइंट को पुनर्स्थापित करने के लिए pretrainer बीच विभाजन पर ध्यान दें) और ResNet के लिए बाद वाला दृष्टिकोण ( Legacy/image_classification/tfhub_export.py देखें) ).

निम्न-स्तरीय TensorFlow से बचत

इसके लिए 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

फ़ाइन ट्यूनिंग

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

फ़ाइन-ट्यूनिंग प्रशिक्षित किए गए "निरंतर" मॉडल मापदंडों को बदल देती है। यह हार्ड-कोडित परिवर्तनों को नहीं बदलता है, जैसे टेक्स्ट इनपुट को टोकनाइज़ करना और एम्बेडिंग मैट्रिक्स में उनकी संबंधित प्रविष्टियों में टोकन मैप करना।

सेव्डमॉडल उपभोक्ताओं के लिए

एक hub.KerasLayer बनाना.KerasLayer जैसा

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

परत द्वारा लोड किए गए SaveModel को ठीक से ट्यून करने में सक्षम बनाता है। यह सेव्डमॉडल में घोषित प्रशिक्षण योग्य वजन और वजन नियमितीकरण को केरस मॉडल में जोड़ता है, और सेव्डमॉडल की गणना को प्रशिक्षण मोड (ड्रॉपआउट आदि के बारे में सोचें) में चलाता है।

छवि वर्गीकरण कोलाब में वैकल्पिक फाइन-ट्यूनिंग के साथ एक एंड-टू-एंड उदाहरण शामिल है।

फाइन-ट्यूनिंग परिणाम को पुनः निर्यात करना

उन्नत उपयोगकर्ता फाइन-ट्यूनिंग के परिणामों को वापस सेव्डमॉडल में सहेजना चाह सकते हैं जिसका उपयोग मूल रूप से लोड किए गए मॉडल के बजाय किया जा सकता है। जैसे कोड के साथ ऐसा किया जा सकता है

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)

सेव्डमॉडल रचनाकारों के लिए

TensorFlow हब पर साझा करने के लिए एक SavedModel बनाते समय, पहले से सोचें कि क्या और कैसे इसके उपभोक्ताओं को इसे ठीक करना चाहिए, और दस्तावेज़ीकरण में मार्गदर्शन प्रदान करना चाहिए।

केरस मॉडल से बचत करने से फाइन-ट्यूनिंग कार्य के सभी तंत्र तैयार होने चाहिए (वजन नियमितीकरण के नुकसान को बचाना, प्रशिक्षण योग्य चर घोषित करना, training=True और training=False दोनों के लिए __call__ का पता लगाना, आदि)

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

यदि मॉडल ड्रॉपआउट, बैच सामान्यीकरण, या इसी तरह की प्रशिक्षण तकनीकों का उपयोग करता है जिसमें हाइपरपैरामीटर शामिल हैं, तो उन्हें उन मानों पर सेट करें जो कई अपेक्षित लक्ष्य समस्याओं और बैच आकारों में समझ में आते हैं। (इस लेखन के समय, केरास से बचत करने से उपभोक्ताओं को उन्हें समायोजित करने में आसानी नहीं होती है।)

अलग-अलग परतों पर वजन नियमित करने वालों को बचाया जाता है (उनके नियमितीकरण शक्ति गुणांक के साथ), लेकिन ऑप्टिमाइज़र के भीतर से वजन नियमितीकरण (जैसे tf.keras.optimizers.Ftrl.l1_regularization_strength=...) ) खो जाता है। अपने सेव्डमॉडल के उपभोक्ताओं को तदनुसार सलाह दें।