Pytorch
TensorFlow

#
मॉडल कि फाइन-ट्यूनिंग Keras के साथ

एक बार जब आप अंतिम खंड में सभी डेटा पूर्व प्रसंस्करण कार्य कर लेते हैं, तो आपके पास मॉडल को प्रशिक्षित करने के लिए बस कुछ ही चरण शेष हैं। हालाँकि, ध्यान दें कि `model.fit()` कमांड CPU पर बहुत धीमी गति से चलेगा। यदि आपके पास GPU सेट अप नहीं है, तो आप Google Colab पर निःशुल्क GPU या TPU का एक्सेस प्राप्त कर सकते हैं।

नीचे दिए गए कोड उदाहरण मानते हैं कि आपने पिछले खंड में उदाहरणों को पहले ही निष्पादित कर दिया है। यहां एक संक्षिप्त सारांश दिया गया है जिसकी आपको आवश्यकता है:

    from datasets import load_dataset
    from transformers import AutoTokenizer, DataCollatorWithPadding
    import numpy as np

    raw_datasets = load_dataset("glue", "mrpc")
    checkpoint = "bert-base-uncased"
    tokenizer = AutoTokenizer.from_pretrained(checkpoint)

    def tokenize_function(example):
        return tokenizer(example["sentence1"], example["sentence2"], truncation=True)

    tokenized_datasets = raw_datasets.map(tokenize_function, batched=True)

    data_collator = DataCollatorWithPadding(tokenizer=tokenizer, return_tensors="tf")

    tf_train_dataset = tokenized_datasets["train"].to_tf_dataset(
        columns=["attention_mask", "input_ids", "token_type_ids"],
        label_cols=["labels"],
        shuffle=True,
        collate_fn=data_collator,
        batch_size=8,
    )

    tf_validation_dataset = tokenized_datasets["validation"].to_tf_dataset(
        columns=["attention_mask", "input_ids", "token_type_ids"],
        label_cols=["labels"],
        shuffle=False,
        collate_fn=data_collator,
        batch_size=8,
    )

### प्रशिक्षण

🤗 ट्रांसफॉर्मर से आयात किए गए TensorFlow मॉडल पहले से ही Keras मॉडल हैं। यहाँ Keras का संक्षिप्त परिचय दिया गया है।

इसका मतलब है कि एक बार जब हमारे पास हमारा डेटा होता है, तो उस पर प्रशिक्षण शुरू करने के लिए बहुत कम काम करने की आवश्यकता होती है।

पिछले अध्याय की तरह, हम `TFAutoModelForSequenceClassification` क्लास का उपयोग दो लेबल के साथ करेंगे:

    from transformers import TFAutoModelForSequenceClassification

    model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)

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

अपने डेटासेट पर मॉडल को फाइन-ट्यून करने के लिए, हमें बस अपने मॉडल को `compile()` करना होगा और फिर अपने डेटा को `fit()` विधि में पास करना होगा। यह फ़ाइन-ट्यूनिंग प्रक्रिया को शुरू करेगा (जो GPU पर कुछ मिनट लेगा) और आगे जा कर यह हर युग यानि एपॉच के अंत में प्रशिक्षण हानि यानि लॉस साथ ही सत्यापन हानि की रिपोर्ट करेगा।

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

    from tensorflow.keras.losses import SparseCategoricalCrossentropy

    model.compile(
        optimizer="adam",
        loss=SparseCategoricalCrossentropy(from_logits=True),
        metrics=["accuracy"],
    )
    model.fit(
        tf_train_dataset,
        validation_data=tf_validation_dataset,
    )

यहां एक बहुत ही सामान्य नुकसान पर ध्यान दें - आप केवल लॉस का नाम स्ट्रिंग के रूप मे Keras को पास कर सकते है, लेकिन डिफ़ॉल्ट रूप से Keras यह मानेगा कि आपने पहले ही अपने आउटपुट में सॉफ्टमैक्स लागू कर दिया है। हालाँकि, कई मॉडल सॉफ्टमैक्स लागू होने से ठीक पहले मानों यानि वैल्यूज़ को आउटपुट करते हैं, जिन्हें logits के रूप में भी जाना जाता है। हमें लॉस फ़ंक्शन को यह बताने की आवश्यकता है कि हमारा मॉडल क्या करता है, और ऐसा करने का एकमात्र तरीका है कि इसे सीधे कॉल करना, बजाय एक स्ट्रिंग के नाम से।

### प्रशिक्षण प्रदर्शन में सुधार करना

यदि आप उपर दिए गए कोड का प्रयास करते हैं, तो यह निश्चित रूप से चलता है, लेकिन आप पाएंगे कि लॉस केवल धीरे-धीरे या छिटपुट रूप से घटता है। इसका मुख्य कारण है सीखने की दर यानि लर्निंग रेट। लॉस के साथ, जब हम Keras को ऑप्टिमाइज़र का नाम स्ट्रिंग के रूप में पास करते है, तो Keras उस ऑप्टिमाइज़र को लर्निंग रेट सहित सभी मापदंडों के लिए डिफ़ॉल्ट वैल्यूज़ के साथ आरंभ यानि इनिशलाइज़ करता है। लंबे अनुभव से, हालांकि, हम जानते हैं कि ट्रांसफॉर्मर मॉडल डिफ़ॉल्ट एडम की तुलना में बहुत कम लर्निंग रेट से लाभ होता हैं, जो कि 1e-3 है, जिसे 10 की पॉवर -3 या 0.001 के रूप में भी लिखा जाता है। 5e-5 (0.00005), जो कुछ बीस गुना कम है, एक बेहतर प्रारंभिक बिंदु है।

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

    from tensorflow.keras.optimizers.schedules import PolynomialDecay

    batch_size = 8
    num_epochs = 3
    # The number of training steps is the number of samples in the dataset, divided by the batch size then multiplied
    # by the total number of epochs. Note that the tf_train_dataset here is a batched tf.data.Dataset,
    # not the original Hugging Face Dataset, so its len() is already num_samples // batch_size.
    num_train_steps = len(tf_train_dataset) * num_epochs
    lr_scheduler = PolynomialDecay(
        initial_learning_rate=5e-5, end_learning_rate=0.0, decay_steps=num_train_steps
    )
    from tensorflow.keras.optimizers import Adam

    opt = Adam(learning_rate=lr_scheduler)

🤗 ट्रांसफॉर्मर्स लाइब्रेरी में एक `create_optimizer()` फ़ंक्शन भी है जो लर्निंग रेट क्षय के साथ एक `AdamW` ऑप्टिमाइज़र बनाएगा। यह एक सुविधाजनक शॉर्टकट है जिसे आप पाठ्यक्रम के भविष्य के अनुभागों में विस्तार से देखेंगे।

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

    import tensorflow as tf

    model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)
    loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
    model.compile(optimizer=opt, loss=loss, metrics=["accuracy"])

अब, हम फिर से फिट करेगे:

    model.fit(tf_train_dataset, validation_data=tf_validation_dataset, epochs=3)

💡 यदि आप प्रशिक्षण के दौरान अपने मॉडल को हब पर स्वचालित रूप से अपलोड करना चाहते हैं, तो आप `model.fit()` विधि में `PushToHubCallback` के साथ पास कर सकते हैं। हम इसके बारे में अध्याय 4 में और जानेंगे

### मॉडल के पूर्वानुमान

प्रशिक्षण और लॉस को कम होते देखना बहुत अच्छा है, लेकिन क्या होगा अगर हम वास्तव में प्रशिक्षित मॉडल से आउटपुट प्राप्त करना चाहते हैं, या तो कुछ मेट्रिक्स की गणना करने के लिए, या उत्पादन में मॉडल का उपयोग करने के लिए? ऐसा करने के लिए, हम केवल `predict()` विधि का उपयोग कर सकते हैं। यह एक प्रति क्लास, मॉडल के आउटपुट हेड से logits लौटाएगा।

    preds = model.predict(tf_validation_dataset)["logits"]

हम उच्चतम लॉगिट् को खोजने के लिए `argmax` का उपयोग करके इन लॉगिट्स को मॉडल के क्लास पूर्वानुमान में बदल सकते हैं, जो सबसे संभावित क्लास से मेल खाता है:

    class_preds = np.argmax(preds, axis=1)
    print(preds.shape, class_preds.shape)

    (408, 2) (408,)

अब, कुछ मेट्रिक्स की गणना करने के लिए उन `preds` का उपयोग करते हैं! हम MRPC डेटासेट से जुड़े मेट्रिक्स को उतनी ही आसानी से लोड कर सकते हैं, जितनी आसानी से हमने डेटासेट लोड किया, इस बार `evaluate.load()` फ़ंक्शन के साथ। इसने एक वस्तु लौटाया जिसमे एक `compute()` विधि है जिसका उपयोग हम मीट्रिक गणना करने के लिए कर सकते हैं:

    import evaluate

    metric = evaluate.load("glue", "mrpc")
    metric.compute(predictions=class_preds, references=raw_datasets["validation"]["label"])

    {'accuracy': 0.8578431372549019, 'f1': 0.8996539792387542}

आपको मिलने वाले सटीक परिणाम अलग-अलग हो सकते हैं, क्योंकि मॉडल हेड के क्रमरहित इनिशियलाइज़ेशन से प्राप्त मेट्रिक्स में बदलाव हो सकता है। यहां, हम देख सकते हैं कि हमारे मॉडल का सत्यापन सेट पर 85.78% की सटीकता है और 89.97 का F1 स्कोर है। वे दो मेट्रिक्स हैं जिनका उपयोग GLUE बेंचमार्क के लिए MRPC डेटासेट पर परिणामों का मूल्यांकन करने के लिए किया जाता है। BERT पेपर में टेबल ने बेस मॉडल के लिए F1 स्कोर 88.9 बताया। वह एक `uncased` मॉडल था जबकि हम वर्तमान में `cased` मॉडल का उपयोग कर रहे हैं, जो बेहतर परिणाम की व्याख्या करता है।

यह Keras API का उपयोग करके फाइन-ट्यूनिंग के परिचय को समाप्त करता है। अधिकांश सामान्य NLP कार्यों के लिए ऐसा करने का एक उदाहरण अध्याय 7 में दिया जाएगा। यदि आप Keras API पर अपने कौशल को सुधारना चाहते हैं, तो GLUE SST-2 डेटासेट पर एक मॉडल को फाइन-ट्यून करने का प्रयास करें, डेटा प्रसंस्करण यानि डेटा प्रोसेसिंग का उपयोग करके जिसे आपने सेक्शन 2 में किया था