Filter by دسته‌ها
chatGTP
ابزارهای هوش مصنوعی
اخبار
گزارش
تیتر یک
چندرسانه ای
آموزش علوم داده
اینفوگرافیک
پادکست
ویدیو
دانش روز
آموزش‌های پایه‌ای هوش مصنوعی
اصول هوش مصنوعی
یادگیری بدون نظارت
یادگیری تقویتی
یادگیری عمیق
یادگیری نیمه نظارتی
آموزش‌های پیشرفته هوش مصنوعی
بینایی ماشین
پردازش زبان طبیعی
پردازش گفتار
چالش‌های عملیاتی
داده کاوی و بیگ دیتا
رایانش ابری و HPC
سیستم‌‌های امبدد
علوم شناختی
دیتاست
رویدادها
جیتکس
کاربردهای هوش مصنوعی
کتابخانه
اشخاص
شرکت‌های هوش مصنوعی
محصولات و مدل‌های هوش مصنوعی
مفاهیم
کسب‌و‌کار
تحلیل بازارهای هوش مصنوعی
کارآفرینی
هوش مصنوعی در ایران
هوش مصنوعی در جهان
مقاله
 آموزش پردازش زبان طبیعی با اکوسیستم هاگینگ فیس ؛ تنظیم دقیق مدل با Keras (فصل سوم؛قسمت دوم)

آموزش پردازش زبان طبیعی با اکوسیستم هاگینگ فیس ؛ تنظیم دقیق مدل با Keras (فصل سوم؛قسمت دوم)

زمان مطالعه: 5 دقیقه

این قسمت از دوره آموزش پردازش زبان طبیعی با اکوسیستم هاگینگ فیس به تنظیم دقیق مدل با Keras خواهد پرداخت. همچنین شما می‌توانید در انتهای مطلب به لینک سایر قسمت‌‎ها دسترسی داشته باشید.

به محض اِتمام کلیه‌ی کارهای پیش‌پردازش در بخش پیشین، فقط چند مرحله دیگر برای آموزش مدل در پیش دارید. اما توجه داشته باشید که دستور model.fit  عملکرد بسیار کُندی در CPU خواهد داشت. اگر سیستم‌تان را به GPU مناسب مجهز نکرده‌اید، می‌توانید به GPU یا TPU رایگان در Google Colab دسترسی داشته باشید. در کدهای زیر، فرض بر این است که نمونه‌ها را در بخش پیشین اجرا کرده‌اید. در بخش زیر، اقدامات مورد نیاز به طور خلاصه ذکر شده است:

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

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

def tokenize_dataset(dataset):
    encoded = tokenizer(
        dataset["sentence1"],
        dataset["sentence2"],
        padding=True,
        truncation=True,
        return_tensors='np',
    )
    return encoded.data

tokenized_datasets = {
    split: tokenize_dataset(raw_datasets[split]) for split in raw_datasets.keys()
}

آموزش

مدل‌های تنسورفلوی وارد شده از transformers  نوعی مدل Keras به حساب می‌آیند. در این بخش، مقدمه‌ی کوتاهی برای Keras تهیه کرده‌ایم.

پس از اینکه داده‌ها در دسترس قرار گرفت، کار اندکی برای آغاز فرایند آموزش بر روی آن نداریم. همان‌طور که در فصل قبل ملاحظه کردید، دسته‌ی TFAutoModelForSequenceClassification  با دو برچسب مورد استفاده قرار خواهد گرفت:

from transformers import TFAutoModelForSequenceClassification

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

برخلاف آنچه در فصل 2 ذکر شد، پس از راه‌اندازی این مدلِ از پیش آموزش‌دیده یک هشدار ارسال می‌شود زیرا برت با جفت جملات آموزش ندیده است. از این رو، هدِ مدل کنار گذاشته نشده و هد تازه‌ای به جای آن برای طبقه‌بندی توالی جایگذاری شده است. هشدارها نشان می‌دهند که بعضی از وزن‌ها استفاده نشده‌اند (وزن‌های مربوط به هد پیش‌آموزش) و بعضی نیز به طور تصادفی به کار برده شده‌اند (وزن‌های مربوط به هد جدید). کار با ترغیب شما برای آموزش مدل به پایان می‌رسد. اینک، دقیقاً قصد انجام همین کار را داریم.

تنظیم دقیق مدل با توجه به دیتاست موجود مستلزم این است که مدل را کامپایل (compile()) کرده و سپس داده‌ها را در اختیار روش fit  قرار دهیم. به این ترتیب، فرایند تنظیم دقیق آغاز می‌شود (که معمولاً با GPU چند دقیقه به طول می‌انجامد). در وهله بعدی، لاس در زمان آموزش و لاس در زمان اعتبارسنجی در پایان هر دوره گزارش داده می‌شود.

تفسیر این کار آسانی نیست. چه اطلاعاتی درباره دقت حقیقیِ مدل در دسترس می‌باشد؟ افزودن متریک accuracy  الزامی است زیرا بینش‌مان را درباره عملکرد مدل ارتقاء می‌بخشد:

حال، ممکن است با یک مشکل روبرو شوید. فقط این امکان را دارید که نام تابع لاس را در قالب رشته‌ای به Keras منتقل کنید، اما Keras این پیش‌فرض را با خود دارد که از تابع سافت‌مکس در خروجی‌هایتان استفاده کرده‌اید. با این حال، بسیاری از مدل‌ها پیش از به‌کارگیری تابع سافت‌مکس از مقادیر خروجی می‌گیرند که با عنوان لاجیت نیز شناخته می‌شوند. باید این اطلاعات را در اختیار تابع loss قرار داد که مدل‌مان این کار را انجام می‌دهد و تنها راه برای انجامش این است که به طور مستقیم فراخوانی شود (نَه اینکه با یک رشته نام‌گذاری شود).

from tensorflow.keras.losses import SparseCategoricalCrossentropy

model.compile(
    optimizer='adam',
    loss=SparseCategoricalCrossentropy(from_logits=True),
    metrics=['accuracy'],
)
model.fit(
    tokenized_datasets['train'],
    np.array(raw_datasets['train']['label']), 
    validation_data=(
        tokenized_datasets['validation'],
        np.array(raw_datasets['validation']['label']),
    ),
    batch_size=8
)

ارتقای عملکرد آمورشی

اگر کد بالا را امتحان کنید، قطعاً اجرا می‌شود، اما خواهید دید که لاس به آهستگی یا به طور پراکنده کاهش می‌یابد. نرخ یادگیری، عامل اصلیِ این اتفاق است. همان‌طور که در لاس مشاهده کردید، اگر نام بهینه‌سازی را به عنوان یک رشته در اختیار Keras قرار دهید، آن بهینه‌ساز در همه پارامترها با مقادیر پیش‌فرض اجرا می‌شود (از جمله نرخ یادگیری). تجربه نشان می‌دهد که فایده‌ای که نرخ یادگیری پایین برای مدل‌های ترنسفورمر دارد، بیشتر از مقادیر پیش‌فرض Adam است (1e-3). این مقادیر به صورت  نیز نوشته می‌شوند. Adam ده برابر سرعت کمتری دارد، اما نقطه شروع بهتری محسوب می‌شود.

علاوه بر پایین آوردن نرخ یادگیری، باید ترفند دیگری را نیز به کار برد. این امکان وجود دارد که نرخ یادگیری را در طی فرایند آموزش کاهش دهید. در پژوهش‌های پیشین از این اقدام با عنوان تجزیه‌ی نرخ یادگیری نیز یاد می‌کنند. بهترین راه در Keras استفاده از ابزار زمان‌بندی نرخ یادگیری است. ما  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
num_train_steps = (len(tokenized_datasets['train']['input_ids']) // batch_size) * num_epochs
lr_scheduler = PolynomialDecay(
    initial_learning_rate=5e-5,
    end_learning_rate=0.,
    decay_steps=num_train_steps
    )
from tensorflow.keras.optimizers import Adam
opt = Adam(learning_rate=lr_scheduler)

اینک، یک بهینه‌ساز جدید در اختیار دارید که امکان آموزش را مهیا می‌سازد. در ابتدا، مدل را مجدداً بارگذاری کنید تا تغییرات اِعمال شده بر روی وزن‌ها در مرحله آموزش به حالت قبل بازگردد. سپس، مدل را با بهینه‌ساز جدید کامپایل نمائید.

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)

حال، شرایط مثل قبل شده است. اگر مدل کامپایل شود، کلیه تغییرات پیاده‌سازی می‌شوند. بنابراین، دستور fit  کارکرد یکسانی دارد.

پیش‌بینی مدل

آموزش و مشاهده‌ی روند کاهش زیان بسیار لذت‌بخش است، اما اگر می‌خواهید خروجی‌ها را از مدل آموزش دیده به دست آورید، محاسبه‌ی برخی متریک‌ها یا استفاده از مدل می‌تواند موثر باشد؟ برای انجام این کار، می‌توانید به استفاده از روش predict()  بسنده کنید. بنابراین، لاگیت‌ها از هد خروجی مدل به دست خواهند آمد (در ازای هر دسته).

preds = model.predict(tokenized_datasets['validation'])['logits']

می‌توانید این لاجیت‌ها را با استفاده از argmax  به پیش‌بینی دسته‌ی مدل تبدیل کنید تا بالاترین لاجیت به دست آید.

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

اکنون، باید از preds  برای محاسبه‌ی برخی متریک‌ها استفاده کنید. به همان شیوه‌ای که دیتاست را بارگذاری کردید، می‌توانید متریک‌های مرتبط با دیتاست MRPC را بارگذاری کنید، اما این بار با تابع load_metric . شیء خروجی شده یک روش compute  دارد که می‌تواند برای محاسبه متریک مورد استفاده قرار گیرد:

from datasets import load_metric

metric = load_metric("glue", "mrpc")
metric.compute(predictions=class_preds, references=raw_datasets['validation']['label'])
{'accuracy': 0.8578431372549019, 'f1': 0.8996539792387542}

نتایجی که به دست می‌آورید، می‌تواند متغیر باشد زیرا راه‌اندازیِ تصادفیِ هد مدل ممکن است متریک‌های به دست آمده را تغییر دهد. همان‌طور که می‌بینید، مدل در مجموعه اعتبارسنجی به دقت 0.8578 درصدی رسیده است و مقدار F1 آن برابر با 0.8997 می‌باشد. این دو متریک در ارزیابی نتایج دیتاست MRPC در بنچ‌مارک GLUE کاربرد دارند. جدول این مقاله‌ی برت، مقدار 0.889 را برای F1 گزارش کرده است. این مدل uncased  بود، اما در حال حاضر از مدل cased  استفاده می‌شود. اگر به صورت دستی این روش را فراخوانی کنید، شاید قدری اذیت شوید.

آیا این امکان وجود دارد که وظیفه‌ی محاسبات به عهده‌ی Keras سپرده شود؟ انجام این کار می‌تواند فرصتی برای رصدِ متریک‌ها در طی فرایند آموزش ارائه کند. Keras به طور پیش‌فرض از چند متریک پشتیبانی می‌کند و با نوشتن نام‌شان در یک رشته انتقال داده می‌شوند. عملکرد آن شبیه بهینه‌سازها و توابع زیان است. متاسفانه، مقدار F1 در این دسته جای نمی‌گیرد. اگر تعریف مقدار F1 را جستجو کنید، می‌بینید که صرفاً میانگین هامونیکِ دقت و فراخوانی است؛ متریک Keras از هر دوی آنها پشتیبانی می‌کند. آیا می‌توان از آن برای نوشتن یک متریک F1 ساده استفاده کرد؟

class F1_metric(tf.keras.metrics.Metric):
    def __init__(self, name='f1_score', **kwargs):
        super().__init__(name=name, **kwargs)
        # Initialize our metric by initializing the two metrics it's based on:
        # Precision and Recall
        self.precision = tf.keras.metrics.Precision()
        self.recall = tf.keras.metrics.Recall()

    def update_state(self, y_true, y_pred, sample_weight=None):
        # Update our metric by updating the two metrics it's based on
        self.precision.update_state(y_true, y_pred, sample_weight)
        self.recall.update_state(y_true, y_pred, sample_weight)

    def reset_state(self):
        self.precision.reset_state()
        self.recall.reset_state()

    def result(self):
        # To get the F1 result, we compute the harmonic mean of the current
        # precision and recall
        return 2 / ((1 / self.precision.result()) + (1 / self.recall.result())) 

شاید کدهای بالا موجب ترس و اضطراب‌تان می‌شود، اما نگران نباشید. ساخت دسته با عملِ subclassing  در این کدها توضیح داده شده است. این روش قدرتمند در کدهای بسیار پیشرفته‌ی پایتون کاربرد دارد. اکنون لازم نیست همه جزئیات این کدها را درک کنید. ما سعی کردیم متریک Metric  جدیدی با استفاده از دسته‌ی tf.keras.metrics.Metric  بسازیم. به تعبیری، فقط باید به تصریح مواردی پرداخت که Metric  به صورت منحصربفرد انجام می‌دهد. دسته‌ی base (پایه) می‌تواند سایر کدهای بویلرپلیتِ دسته‌های Metric  را مدیریت کند. دوباره تکرار می‌کنیم که اجازه ندهید این فرایند موجب ترس و اضطراب‌تان شود. اکنون نوبت به بارگذاری و آموزش مجدد مدل رسیده است. توجه داشته باشید که متریک‌‌ها می‌توانند با هم ترکیب شوند.

model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)
lr_scheduler = PolynomialDecay(
    initial_learning_rate=5e-5,
    end_learning_rate=0.,
    decay_steps=num_train_steps
    )
opt = Adam(learning_rate=lr_scheduler)
model.compile(optimizer=opt, loss=loss, metrics=['accuracy', F1_metric()])
model.fit(
    tokenized_datasets['train'],
    np.array(raw_datasets['train']['label']),
    validation_data=(tokenized_datasets['validation'], np.array(raw_datasets['validation']['label'])),
    batch_size=8,
    epochs=3
)

این بار، تابع زیان و متریک‌های موجود در بالای زیان آموزش گزارش می‌شوند. دوباره، مقدار دقیق F1 ممکن است قدری با محاسبات ما فرق داشته باشد و دلیل آن را می‌توان به راه‌اندازی هد تصادفیِ مدل نسبت داد. بنابراین، مقدمه‌ی تنظیم دقیق با استفاده از Keras API به پایان می‌رسد. در فصل 7، نمونه‌ای از آن برای متداول‌ترین کارهای NLP ارائه خواهد شد. اگر قصد دارید مهارت‌هایتان را در Keras API تقویت کنید، مد را با دیتاست GLUE SST-2 تنظیم کنید. می‌توانید از فرایند پردازش داده در بخش 2 استفاده کنید.

از طریق لینک زیر می‌توانید به سایر فصل‌ها و قسمت‌های دوره آموزش پردازش زبان طبیعی دسترسی داشته باشید:

[button href=”https://hooshio.com/%D8%B1%D8%B3%D8%A7%D9%86%D9%87-%D9%87%D8%A7/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D9%BE%D8%B1%D8%AF%D8%A7%D8%B2%D8%B4-%D8%B2%D8%A8%D8%A7%D9%86-%D8%B7%D8%A8%DB%8C%D8%B9%DB%8C/” type=”btn-default” size=”btn-lg”]آموزش پردازش زبان طبیعی[/button]

میانگین امتیاز / 5. تعداد ارا :

مطالب پیشنهادی مرتبط

اشتراک در
اطلاع از
0 نظرات
بازخورد (Feedback) های اینلاین
مشاهده همه دیدگاه ها
[wpforms id="48325"]