آموزش پردازش زبان طبیعی با اکوسیستم هاگینگ فیس ؛ تنظیم دقیق مدل با Keras (فصل سوم؛قسمت دوم)
این قسمت از دوره آموزش پردازش زبان طبیعی با اکوسیستم هاگینگ فیس به تنظیم دقیق مدل با Keras خواهد پرداخت. همچنین شما میتوانید در انتهای مطلب به لینک سایر قسمتها دسترسی داشته باشید. به محض اِتمام کلیهی کارهای پیشپردازش در بخش پیشین، فقط چند مرحله دیگر برای…
خلاصه تحلیلی خبر
این قسمت از دوره آموزش پردازش زبان طبیعی با اکوسیستم هاگینگ فیس به تنظیم دقیق مدل با Keras خواهد پرداخت. همچنین شما میتوانید در انتهای مطلب به لینک سایر قسمتها دسترسی داشته باشید. به محض اِتمام کلیهی کارهای پیشپردازش در بخش پیشین، فقط چند مرحله دیگر برای…
موضوعات اصلی: پشتیبانی شبکه، مدل، Keras، آموزش، کنید، استفاده
این قسمت از دوره آموزش پردازش زبان طبیعی با اکوسیستم هاگینگ فیس به تنظیم دقیق مدل با 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://XNET.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]
برای ارزیابی پایداری، امنیت و نگهداری این زیرساخت، راهنمای پشتیبانی شبکه را نیز مطالعه کنید.