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

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

در این قسمت از دوره رایگان آموزش پردازش زبان طبیعی به مدیریت چندین توالی ورودی خواهیم پرداخت. ساده‌ترین موارد کاربرد (یعنی استنباط گیری از یک توالی با طول اندک) در بخش پیشین بررسی شد. با این حال، باید پاسخ مناسبی به پرسش‌های زیر داده شود:

  • مدیریت چندین توالی چگونه است؟
  • مدیریت چندین توالی با طول مختلف چگونه است؟
  • آیا شاخص‌های واژگانی تنها ورودی‌هایی هستند که زمینه را برای کارکرد خوبِ مدل فراهم می‌کنند؟
  • آیا امکان دارد یک توالی بیش از حد طولانی باشد؟

در بخش زیر خواهید دید که این قبیل از پرسش‌ها به چه مسائلی می‌انجامد. نحوه‌ی حل این مسائل با ترنسفورمر API نیز توضیح داده می‌شود. ابتدا ویدئو زیر را تماشا کنید:

ویدئو نحوه‌ی حل این مسائل با ترنسفورمر API

مدل‌ها به دسته‌ یا بچ از ورودی‌ها نیاز دارند

در تمرین پیشین، دیدید که توالی‌ها چگونه به لیستی از اعداد تبدیل می‌شوند. اینک، بیایید این لیست اعداد را به یک تنسور تبدیل و به مدل ارسال کنیم:

import tensorflow as tf
from transformers import AutoTokenizer, TFAutoModelForSequenceClassification

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint)

sequence = "I've been waiting for a HuggingFace course my whole life."

tokens = tokenizer.tokenize(sequence)
ids = tokenizer.convert_tokens_to_ids(tokens)
input_ids = tf.constant(ids)
# This line will fail.
model(input_ids)
.
InvalidArgumentError: Input to reshape is a tensor with 14 values, but the requested shape has 196 [Op:Reshape]

وای! چرا این کار با موفقیت به پایان نرسید؟  مراحل پایپ‌لاین در بخش ۲ پیاده‌سازی شدند. (در انتهای مطلب می‌توانید به دیگر قسمت‌های این دوره آموزش پردازش زبان طبیعی دسترسی داشته باشید).

مشکل اینجاست که یک توالی به مدل ارسال کردیم، اما مدل‌های ترنسفورمر به طور پیش‌فرض نیازمند چندین توالی هستند. در این بخش سعی کردیم تمام کارهای پشت صحنه توکن‌کننده را در صورت به‌کارگیری در توالی پوشش دهیم. اما اگر با دقت به این موضوع نگاه کنید، می‌بینید که توکن‌کننده صرفاً لیست شناسه‌های ورودی را به تنسور تبدیل نکرده است، بلکه شاهد اضافه شدن یک بُعد در بالای آن هستیم:

tokenized_inputs = tokenizer(sequence, return_tensors="tf")
print(tokenized_inputs["input_ids"])
.
<tf.Tensor: shape=(1, 16), dtype=int32, numpy=
array([[  101,  1045,  1005,  2310,  2042,  3403,  2005,  1037, 17662,
        ۱۲۱۷۲,  ۲۶۰۷,  ۲۰۲۶,  ۲۸۷۸,  ۲۱۶۶,  ۱۰۱۲,   ۱۰۲]], dtype=int32)>

اینک، بیایید دوباره امتحان کنیم و بُعد جدیدی بیفزاییم:

import tensorflow as tf
from transformers import AutoTokenizer, TFAutoModelForSequenceClassification

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint)

sequence = "I've been waiting for a HuggingFace course my whole life."

tokens = tokenizer.tokenize(sequence)
ids = tokenizer.convert_tokens_to_ids(tokens)

input_ids = tf.constant([ids])
print("Input IDs:", input_ids)

output = model(input_ids)
print("Logits:", output.logits)

باید شناسه‌های ورودی و توابع لوجیت را چاپ کرد. به خروجی کار توجه کنید:

Input IDs: tf.Tensor(
[[ ۱۰۴۵  ۱۰۰۵  ۲۳۱۰  ۲۰۴۲  ۳۴۰۳  ۲۰۰۵  ۱۰۳۷ ۱۷۶۶۲ ۱۲۱۷۲  ۲۶۰۷  ۲۰۲۶  ۲۸۷۸
   ۲۱۶۶  ۱۰۱۲]], shape=(1, 14), dtype=int32)
Logits: tf.Tensor([[-2.7276208  2.8789377]], shape=(1, 2), dtype=float32)

دسته‌بندی Batching به عمل ارسالِ همزمان چندین توالی به مدل اطلاق می‌شود. اگر فقط یک جمله داشته باشید، می‌توانید دسته‌ای با یک توالی ایجاد کنید:

batched_ids = [ids, ids]

این دسته دو توالی مشابه دارد.

خودتان امتحان کنید: لیست batched_ids را به تنسور کرده و به مدل انتقال دهید. به این موضوع توجه داشته باشید که باید توابع لوجیت یکسانی مثل قبل به دست بیاورید. عمل دسته‌بندی این امکان را در اختیار مدل قرار می‌دهد تا در صورت رویارویی با چندین توالی به فعالیت عادی خود ادامه دهد. استفاده از چندین توالی هم مثل ساختن دسته با یک توالی آسان است. البته مسئله دیگری هم وجود دارد. اگر می‌خواهید دو جمله را به صورت دسته‌ای کنار یکدیگر قرار دهید، ممکن است آن جملات طول متفاوتی داشته باشند. اگر پیشتر با تنسورها کار کرده باشید، احتمالاً می‌دانید که آنها باید شکل مستطیلی داشته باشند؛ بنابراین، قادر نخواهید بود این لیست شناسه‌های ورودی را به طور مستقیم به تنسور تبدیل کنید. شاید بهتر است از عمل پدینگ Padding استفاده کنید.

پدینگ کردن ورودی‌ها

امکان تبدیل لیست زیر به تنسور وجود ندارد:

batched_ids = [
  [۲۰۰, ۲۰۰, ۲۰۰],
  [۲۰۰, ۲۰۰]
]

برای اینکه در این بخش به اهداف مورد نظر دست یابیم، باید از عمل پدینگ برای اطمینان حاصل کردن از شکل مستطیلیِ تنسورها استفاده کنیم. پدینگ با افزودن واژه خاصی به نام padding token به جملات این اطمینان را می‌دهد که کلیه جملات طول یکسانی خواهند داشت. برای نمونه، اگر ۱۰ جمله با ۱۰ واژه و یک جمله با ۲۰ واژه داشته باشید، پدینگ به نحوی عمل خواهد کرد که کلیه جملات ۲۰ واژه داشته باشند. در مثال ما، تنسورِ بدست آمده به شکل زیر خواهد بود:

padding_id = 100

batched_ids = [
  [۲۰۰, ۲۰۰, ۲۰۰],
  [۲۰۰, ۲۰۰, padding_id]
]

شناسه‌ پدینگ توکن padding token ID در tokenizer.pad_token_id قابل دسترس است. بیایید از این ابزار استفاده کرده و دو جمله را به طور جداگانه در اختیار مدل قرار دهیم:

model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint)

sequence1_ids = [[200, 200, 200]]
sequence2_ids = [[200, 200]]
batched_ids = [
    [۲۰۰, ۲۰۰, ۲۰۰],
    [۲۰۰, ۲۰۰, tokenizer.pad_token_id]
]

print(model(tf.constant(sequence1_ids)).logits)
print(model(tf.constant(sequence2_ids)).logits)
print(model(tf.constant(batched_ids)).logits)

.

tf.Tensor([[ 1.5693678 -1.3894581]], shape=(1, 2), dtype=float32)
tf.Tensor([[ 0.5803005  -0.41252428]], shape=(1, 2), dtype=float32)
tf.Tensor(
[[ ۱.۵۶۹۳۶۸۱ -۱.۳۸۹۴۵۸۲]
 [ ۱.۳۳۷۳۴۸۶ -۱.۲۱۶۳۱۹۳]], shape=(2, 2), dtype=float32)

توابع لوجیت در پیش‌بینی‌های ما ایراد دارند؛ سطر دوم باید مثل لوجیت‌های جمله‌ی دوم باشد، اما مقادیر کاملاً متفاوتی به دست آمده است. دلیل مشکل فوق این است که لایه‌های توجه به عنوان ویژگی کلیدیِ مدل‌های ترنسفورمر به شمار می‌روند. این لایه‌ها نقش موثری در مفهوم‌سازی زمینه‌ای Contextualize هر یک از توکن‌ها دارند. در این فرایند، توکن‌های پدینگ حتماً مد نظر قرار خواهند گرفت زیرا به همه توکن‌های توالی Sequence می‌پردازند. برای اینکه هنگام انتقال تک‌تک جملات به مدل که طول مختلفی دارند، نتیجه یکسانی بگیرید، باید به کلیه‌ لایه‌های توجه دستور دهید تا از توکن‌های پدینگ چشم‌پوشی کنند. این کار با استفاده از ماسک توجه Attention mask صورت می‌پذیرد.

ماسک‌های توجه

ماسک‌های توجه به تنسورهایی گفته می‌شود که شکل‌شان دقیقاً مثل تنسور شناسه‌های ورودی است و با صفر و یک پر شده‌اند. اعداد ۱ نشان‌دهنده‌ی توکن‌هایی هستند که نیاز به بررسی دارند و اعداد صفر به توکن‌هایی اشاره دارد که نیازمند بررسی نیستند. حال بیایید نمونه پیشین را با یک ماسک توجه تکمیل کنیم:

batched_ids = [
    [۲۰۰, ۲۰۰, ۲۰۰],
    [۲۰۰, ۲۰۰, tokenizer.pad_token_id]
]

attention_mask = [
  [۱, ۱, ۱],
  [۱, ۱, ۰]
]

outputs = model(tf.constant(batched_ids), attention_mask=tf.constant(attention_mask))
print(outputs.logits)

.

tf.Tensor(
[[ ۱.۵۶۹۳۶۸۱  -۱.۳۸۹۴۵۸۲ ]
 [ ۰.۵۸۰۳۰۲۱  -۰.۴۱۲۵۲۵۸۶]], shape=(2, 2), dtype=float32)

اینک، لوجیت‌های یکسانی برای جمله دوم در دسته به دست می‌آید. توجه داشته باشید که رقم آخرِ توالی دوم یک شناسه پدینگ به حساب می‌آید و در ماسک توجه از مقدار صفر برخوردار است.

خودتان امتحان کنید: عمل توکن‌سازی را به صورت جداگانه در دو جمله‌ی مورد استفاده در بخش ۲ انجام دهید. آنها را به مدل انتقال دهید و مطمئن شوید که لوجیت‌های یکسانی در بخش ۲ به دست می‌آیند. اکنون، آنها را با استفاده از padding token کنار یکدیگر قرار دهید؛ سپس، ماسک توجه مناسبی ایجاد کنید. مطمئن شوید که با به‌کارگیری مدل به نتایج یکسانی می‌رسید.

توالی‌های طولانی‌تر

یکی از ویژگی‌های مدل‌های ترنسفورمر این است که طول جملاتی که در اختیار مدل قرار می‌گیرد، باید محدود باشد. اکثر مدل‌ها می‌توانند توالی‌هایی با ۵۱۲ یا ۱۰۲۴ توکن را به خوبی مدیریت کنند. اما اگر توالی‌های طولانی‌تری برای پردازش در اختیارشان قرار داده شود، کارایی لازم را نخواهند داشت. دو راهکار برای این مسئله پیشنهاد شده است:

  • استفاده از مدلی با طول توالی بیشتر
  • کاهش طول توالی‌ها

مدل‌ها طول توالی متفاوتی دارند و برخی از آنها توالی‌های بسیار طویل را به خوبی مدیریت می‌کنند. Longformer  و LED نمونه بارزی از این مدل‌ها برشمرده می‌شوند. اگر بر روی پروژه‌ای کار می‌کنید که به توالی‌های بسیار بلندی نیاز دارد، پیشنهاد می‌کنیم به این مدل‌ها نگاه کنید. در غیر این صورت، توصیه‌مان این است که توالی‌هایتان را با تصریح پارامتر max_sequence_length   کوتاه‌تر کنید:

sequence = sequence[:max_sequence_length]

برای مشاهده باقی قسمت‌های این دوره وارد لینک زیر شوید:

[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]

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

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

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